ActivityManagerService.java revision 6fdb5e6df178b3b1062ac67b505b288aa609a66b
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;
27import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
28
29import android.app.AppOpsManager;
30import android.app.IActivityContainer;
31import android.app.IActivityContainerCallback;
32import android.appwidget.AppWidgetManager;
33import android.graphics.Rect;
34import android.util.ArrayMap;
35
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.os.Zygote;
46import com.android.internal.util.FastPrintWriter;
47import com.android.internal.util.FastXmlSerializer;
48import com.android.internal.util.MemInfoReader;
49import com.android.internal.util.Preconditions;
50import com.android.server.AppOpsService;
51import com.android.server.AttributeCache;
52import com.android.server.IntentResolver;
53import com.android.server.LocalServices;
54import com.android.server.ServiceThread;
55import com.android.server.SystemService;
56import com.android.server.Watchdog;
57import com.android.server.am.ActivityStack.ActivityState;
58import com.android.server.firewall.IntentFirewall;
59import com.android.server.pm.UserManagerService;
60import com.android.server.wm.AppTransition;
61import com.android.server.wm.WindowManagerService;
62import com.google.android.collect.Lists;
63import com.google.android.collect.Maps;
64
65import libcore.io.IoUtils;
66
67import org.xmlpull.v1.XmlPullParser;
68import org.xmlpull.v1.XmlPullParserException;
69import org.xmlpull.v1.XmlSerializer;
70
71import android.app.Activity;
72import android.app.ActivityManager;
73import android.app.ActivityManager.RunningTaskInfo;
74import android.app.ActivityManager.StackInfo;
75import android.app.ActivityManagerInternal;
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    ComponentName mTopComponent;
803    String mTopAction = Intent.ACTION_MAIN;
804    String mTopData;
805    boolean mProcessesReady = false;
806    boolean mSystemReady = false;
807    boolean mBooting = false;
808    boolean mWaitingUpdate = false;
809    boolean mDidUpdate = false;
810    boolean mOnBattery = false;
811    boolean mLaunchWarningShown = false;
812
813    Context mContext;
814
815    int mFactoryTest;
816
817    boolean mCheckedForSetup;
818
819    /**
820     * The time at which we will allow normal application switches again,
821     * after a call to {@link #stopAppSwitches()}.
822     */
823    long mAppSwitchesAllowedTime;
824
825    /**
826     * This is set to true after the first switch after mAppSwitchesAllowedTime
827     * is set; any switches after that will clear the time.
828     */
829    boolean mDidAppSwitch;
830
831    /**
832     * Last time (in realtime) at which we checked for power usage.
833     */
834    long mLastPowerCheckRealtime;
835
836    /**
837     * Last time (in uptime) at which we checked for power usage.
838     */
839    long mLastPowerCheckUptime;
840
841    /**
842     * Set while we are wanting to sleep, to prevent any
843     * activities from being started/resumed.
844     */
845    boolean mSleeping = false;
846
847    /**
848     * State of external calls telling us if the device is asleep.
849     */
850    boolean mWentToSleep = false;
851
852    /**
853     * State of external call telling us if the lock screen is shown.
854     */
855    boolean mLockScreenShown = false;
856
857    /**
858     * Set if we are shutting down the system, similar to sleeping.
859     */
860    boolean mShuttingDown = false;
861
862    /**
863     * Current sequence id for oom_adj computation traversal.
864     */
865    int mAdjSeq = 0;
866
867    /**
868     * Current sequence id for process LRU updating.
869     */
870    int mLruSeq = 0;
871
872    /**
873     * Keep track of the non-cached/empty process we last found, to help
874     * determine how to distribute cached/empty processes next time.
875     */
876    int mNumNonCachedProcs = 0;
877
878    /**
879     * Keep track of the number of cached hidden procs, to balance oom adj
880     * distribution between those and empty procs.
881     */
882    int mNumCachedHiddenProcs = 0;
883
884    /**
885     * Keep track of the number of service processes we last found, to
886     * determine on the next iteration which should be B services.
887     */
888    int mNumServiceProcs = 0;
889    int mNewNumAServiceProcs = 0;
890    int mNewNumServiceProcs = 0;
891
892    /**
893     * Allow the current computed overall memory level of the system to go down?
894     * This is set to false when we are killing processes for reasons other than
895     * memory management, so that the now smaller process list will not be taken as
896     * an indication that memory is tighter.
897     */
898    boolean mAllowLowerMemLevel = false;
899
900    /**
901     * The last computed memory level, for holding when we are in a state that
902     * processes are going away for other reasons.
903     */
904    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
905
906    /**
907     * The last total number of process we have, to determine if changes actually look
908     * like a shrinking number of process due to lower RAM.
909     */
910    int mLastNumProcesses;
911
912    /**
913     * The uptime of the last time we performed idle maintenance.
914     */
915    long mLastIdleTime = SystemClock.uptimeMillis();
916
917    /**
918     * Total time spent with RAM that has been added in the past since the last idle time.
919     */
920    long mLowRamTimeSinceLastIdle = 0;
921
922    /**
923     * If RAM is currently low, when that horrible situatin started.
924     */
925    long mLowRamStartTime = 0;
926
927    /**
928     * This is set if we had to do a delayed dexopt of an app before launching
929     * it, to increasing the ANR timeouts in that case.
930     */
931    boolean mDidDexOpt;
932
933    /**
934     * Set if the systemServer made a call to enterSafeMode.
935     */
936    boolean mSafeMode;
937
938    String mDebugApp = null;
939    boolean mWaitForDebugger = false;
940    boolean mDebugTransient = false;
941    String mOrigDebugApp = null;
942    boolean mOrigWaitForDebugger = false;
943    boolean mAlwaysFinishActivities = false;
944    IActivityController mController = null;
945    String mProfileApp = null;
946    ProcessRecord mProfileProc = null;
947    String mProfileFile;
948    ParcelFileDescriptor mProfileFd;
949    int mProfileType = 0;
950    boolean mAutoStopProfiler = false;
951    String mOpenGlTraceApp = null;
952
953    static class ProcessChangeItem {
954        static final int CHANGE_ACTIVITIES = 1<<0;
955        static final int CHANGE_IMPORTANCE= 1<<1;
956        int changes;
957        int uid;
958        int pid;
959        int importance;
960        boolean foregroundActivities;
961    }
962
963    final RemoteCallbackList<IProcessObserver> mProcessObservers
964            = new RemoteCallbackList<IProcessObserver>();
965    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
966
967    final ArrayList<ProcessChangeItem> mPendingProcessChanges
968            = new ArrayList<ProcessChangeItem>();
969    final ArrayList<ProcessChangeItem> mAvailProcessChanges
970            = new ArrayList<ProcessChangeItem>();
971
972    /**
973     * Runtime CPU use collection thread.  This object's lock is used to
974     * protect all related state.
975     */
976    final Thread mProcessCpuThread;
977
978    /**
979     * Used to collect process stats when showing not responding dialog.
980     * Protected by mProcessCpuThread.
981     */
982    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
983            MONITOR_THREAD_CPU_USAGE);
984    final AtomicLong mLastCpuTime = new AtomicLong(0);
985    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
986
987    long mLastWriteTime = 0;
988
989    /**
990     * Used to retain an update lock when the foreground activity is in
991     * immersive mode.
992     */
993    final UpdateLock mUpdateLock = new UpdateLock("immersive");
994
995    /**
996     * Set to true after the system has finished booting.
997     */
998    boolean mBooted = false;
999
1000    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1001    int mProcessLimitOverride = -1;
1002
1003    WindowManagerService mWindowManager;
1004
1005    final ActivityThread mSystemThread;
1006
1007    int mCurrentUserId = 0;
1008    private UserManagerService mUserManager;
1009
1010    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1011        final ProcessRecord mApp;
1012        final int mPid;
1013        final IApplicationThread mAppThread;
1014
1015        AppDeathRecipient(ProcessRecord app, int pid,
1016                IApplicationThread thread) {
1017            if (localLOGV) Slog.v(
1018                TAG, "New death recipient " + this
1019                + " for thread " + thread.asBinder());
1020            mApp = app;
1021            mPid = pid;
1022            mAppThread = thread;
1023        }
1024
1025        @Override
1026        public void binderDied() {
1027            if (localLOGV) Slog.v(
1028                TAG, "Death received in " + this
1029                + " for thread " + mAppThread.asBinder());
1030            synchronized(ActivityManagerService.this) {
1031                appDiedLocked(mApp, mPid, mAppThread);
1032            }
1033        }
1034    }
1035
1036    static final int SHOW_ERROR_MSG = 1;
1037    static final int SHOW_NOT_RESPONDING_MSG = 2;
1038    static final int SHOW_FACTORY_ERROR_MSG = 3;
1039    static final int UPDATE_CONFIGURATION_MSG = 4;
1040    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1041    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1042    static final int SERVICE_TIMEOUT_MSG = 12;
1043    static final int UPDATE_TIME_ZONE = 13;
1044    static final int SHOW_UID_ERROR_MSG = 14;
1045    static final int IM_FEELING_LUCKY_MSG = 15;
1046    static final int PROC_START_TIMEOUT_MSG = 20;
1047    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1048    static final int KILL_APPLICATION_MSG = 22;
1049    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1050    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1051    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1052    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1053    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1054    static final int CLEAR_DNS_CACHE_MSG = 28;
1055    static final int UPDATE_HTTP_PROXY_MSG = 29;
1056    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1057    static final int DISPATCH_PROCESSES_CHANGED = 31;
1058    static final int DISPATCH_PROCESS_DIED = 32;
1059    static final int REPORT_MEM_USAGE_MSG = 33;
1060    static final int REPORT_USER_SWITCH_MSG = 34;
1061    static final int CONTINUE_USER_SWITCH_MSG = 35;
1062    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1063    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1064    static final int PERSIST_URI_GRANTS_MSG = 38;
1065    static final int REQUEST_ALL_PSS_MSG = 39;
1066    static final int UPDATE_TIME = 40;
1067
1068    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1069    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1070    static final int FIRST_COMPAT_MODE_MSG = 300;
1071    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1072
1073    AlertDialog mUidAlert;
1074    CompatModeDialog mCompatModeDialog;
1075    long mLastMemUsageReportTime = 0;
1076
1077    /**
1078     * Flag whether the current user is a "monkey", i.e. whether
1079     * the UI is driven by a UI automation tool.
1080     */
1081    private boolean mUserIsMonkey;
1082
1083    final ServiceThread mHandlerThread;
1084    final MainHandler mHandler;
1085
1086    final class MainHandler extends Handler {
1087        public MainHandler(Looper looper) {
1088            super(looper, null, true);
1089        }
1090
1091        @Override
1092        public void handleMessage(Message msg) {
1093            switch (msg.what) {
1094            case SHOW_ERROR_MSG: {
1095                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1096                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1097                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1098                synchronized (ActivityManagerService.this) {
1099                    ProcessRecord proc = (ProcessRecord)data.get("app");
1100                    AppErrorResult res = (AppErrorResult) data.get("result");
1101                    if (proc != null && proc.crashDialog != null) {
1102                        Slog.e(TAG, "App already has crash dialog: " + proc);
1103                        if (res != null) {
1104                            res.set(0);
1105                        }
1106                        return;
1107                    }
1108                    if (!showBackground && UserHandle.getAppId(proc.uid)
1109                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1110                            && proc.pid != MY_PID) {
1111                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1112                        if (res != null) {
1113                            res.set(0);
1114                        }
1115                        return;
1116                    }
1117                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1118                        Dialog d = new AppErrorDialog(mContext,
1119                                ActivityManagerService.this, res, proc);
1120                        d.show();
1121                        proc.crashDialog = d;
1122                    } else {
1123                        // The device is asleep, so just pretend that the user
1124                        // saw a crash dialog and hit "force quit".
1125                        if (res != null) {
1126                            res.set(0);
1127                        }
1128                    }
1129                }
1130
1131                ensureBootCompleted();
1132            } break;
1133            case SHOW_NOT_RESPONDING_MSG: {
1134                synchronized (ActivityManagerService.this) {
1135                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1136                    ProcessRecord proc = (ProcessRecord)data.get("app");
1137                    if (proc != null && proc.anrDialog != null) {
1138                        Slog.e(TAG, "App already has anr dialog: " + proc);
1139                        return;
1140                    }
1141
1142                    Intent intent = new Intent("android.intent.action.ANR");
1143                    if (!mProcessesReady) {
1144                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1145                                | Intent.FLAG_RECEIVER_FOREGROUND);
1146                    }
1147                    broadcastIntentLocked(null, null, intent,
1148                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1149                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1150
1151                    if (mShowDialogs) {
1152                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1153                                mContext, proc, (ActivityRecord)data.get("activity"),
1154                                msg.arg1 != 0);
1155                        d.show();
1156                        proc.anrDialog = d;
1157                    } else {
1158                        // Just kill the app if there is no dialog to be shown.
1159                        killAppAtUsersRequest(proc, null);
1160                    }
1161                }
1162
1163                ensureBootCompleted();
1164            } break;
1165            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1166                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1167                synchronized (ActivityManagerService.this) {
1168                    ProcessRecord proc = (ProcessRecord) data.get("app");
1169                    if (proc == null) {
1170                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1171                        break;
1172                    }
1173                    if (proc.crashDialog != null) {
1174                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1175                        return;
1176                    }
1177                    AppErrorResult res = (AppErrorResult) data.get("result");
1178                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1179                        Dialog d = new StrictModeViolationDialog(mContext,
1180                                ActivityManagerService.this, res, proc);
1181                        d.show();
1182                        proc.crashDialog = d;
1183                    } else {
1184                        // The device is asleep, so just pretend that the user
1185                        // saw a crash dialog and hit "force quit".
1186                        res.set(0);
1187                    }
1188                }
1189                ensureBootCompleted();
1190            } break;
1191            case SHOW_FACTORY_ERROR_MSG: {
1192                Dialog d = new FactoryErrorDialog(
1193                    mContext, msg.getData().getCharSequence("msg"));
1194                d.show();
1195                ensureBootCompleted();
1196            } break;
1197            case UPDATE_CONFIGURATION_MSG: {
1198                final ContentResolver resolver = mContext.getContentResolver();
1199                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1200            } break;
1201            case GC_BACKGROUND_PROCESSES_MSG: {
1202                synchronized (ActivityManagerService.this) {
1203                    performAppGcsIfAppropriateLocked();
1204                }
1205            } break;
1206            case WAIT_FOR_DEBUGGER_MSG: {
1207                synchronized (ActivityManagerService.this) {
1208                    ProcessRecord app = (ProcessRecord)msg.obj;
1209                    if (msg.arg1 != 0) {
1210                        if (!app.waitedForDebugger) {
1211                            Dialog d = new AppWaitingForDebuggerDialog(
1212                                    ActivityManagerService.this,
1213                                    mContext, app);
1214                            app.waitDialog = d;
1215                            app.waitedForDebugger = true;
1216                            d.show();
1217                        }
1218                    } else {
1219                        if (app.waitDialog != null) {
1220                            app.waitDialog.dismiss();
1221                            app.waitDialog = null;
1222                        }
1223                    }
1224                }
1225            } break;
1226            case SERVICE_TIMEOUT_MSG: {
1227                if (mDidDexOpt) {
1228                    mDidDexOpt = false;
1229                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1230                    nmsg.obj = msg.obj;
1231                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1232                    return;
1233                }
1234                mServices.serviceTimeout((ProcessRecord)msg.obj);
1235            } break;
1236            case UPDATE_TIME_ZONE: {
1237                synchronized (ActivityManagerService.this) {
1238                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1239                        ProcessRecord r = mLruProcesses.get(i);
1240                        if (r.thread != null) {
1241                            try {
1242                                r.thread.updateTimeZone();
1243                            } catch (RemoteException ex) {
1244                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1245                            }
1246                        }
1247                    }
1248                }
1249            } break;
1250            case CLEAR_DNS_CACHE_MSG: {
1251                synchronized (ActivityManagerService.this) {
1252                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1253                        ProcessRecord r = mLruProcesses.get(i);
1254                        if (r.thread != null) {
1255                            try {
1256                                r.thread.clearDnsCache();
1257                            } catch (RemoteException ex) {
1258                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1259                            }
1260                        }
1261                    }
1262                }
1263            } break;
1264            case UPDATE_HTTP_PROXY_MSG: {
1265                ProxyProperties proxy = (ProxyProperties)msg.obj;
1266                String host = "";
1267                String port = "";
1268                String exclList = "";
1269                String pacFileUrl = null;
1270                if (proxy != null) {
1271                    host = proxy.getHost();
1272                    port = Integer.toString(proxy.getPort());
1273                    exclList = proxy.getExclusionList();
1274                    pacFileUrl = proxy.getPacFileUrl();
1275                }
1276                synchronized (ActivityManagerService.this) {
1277                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1278                        ProcessRecord r = mLruProcesses.get(i);
1279                        if (r.thread != null) {
1280                            try {
1281                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1282                            } catch (RemoteException ex) {
1283                                Slog.w(TAG, "Failed to update http proxy for: " +
1284                                        r.info.processName);
1285                            }
1286                        }
1287                    }
1288                }
1289            } break;
1290            case SHOW_UID_ERROR_MSG: {
1291                String title = "System UIDs Inconsistent";
1292                String text = "UIDs on the system are inconsistent, you need to wipe your"
1293                        + " data partition or your device will be unstable.";
1294                Log.e(TAG, title + ": " + text);
1295                if (mShowDialogs) {
1296                    // XXX This is a temporary dialog, no need to localize.
1297                    AlertDialog d = new BaseErrorDialog(mContext);
1298                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1299                    d.setCancelable(false);
1300                    d.setTitle(title);
1301                    d.setMessage(text);
1302                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1303                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1304                    mUidAlert = d;
1305                    d.show();
1306                }
1307            } break;
1308            case IM_FEELING_LUCKY_MSG: {
1309                if (mUidAlert != null) {
1310                    mUidAlert.dismiss();
1311                    mUidAlert = null;
1312                }
1313            } break;
1314            case PROC_START_TIMEOUT_MSG: {
1315                if (mDidDexOpt) {
1316                    mDidDexOpt = false;
1317                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1318                    nmsg.obj = msg.obj;
1319                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1320                    return;
1321                }
1322                ProcessRecord app = (ProcessRecord)msg.obj;
1323                synchronized (ActivityManagerService.this) {
1324                    processStartTimedOutLocked(app);
1325                }
1326            } break;
1327            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1328                synchronized (ActivityManagerService.this) {
1329                    doPendingActivityLaunchesLocked(true);
1330                }
1331            } break;
1332            case KILL_APPLICATION_MSG: {
1333                synchronized (ActivityManagerService.this) {
1334                    int appid = msg.arg1;
1335                    boolean restart = (msg.arg2 == 1);
1336                    Bundle bundle = (Bundle)msg.obj;
1337                    String pkg = bundle.getString("pkg");
1338                    String reason = bundle.getString("reason");
1339                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1340                            UserHandle.USER_ALL, reason);
1341                }
1342            } break;
1343            case FINALIZE_PENDING_INTENT_MSG: {
1344                ((PendingIntentRecord)msg.obj).completeFinalize();
1345            } break;
1346            case POST_HEAVY_NOTIFICATION_MSG: {
1347                INotificationManager inm = NotificationManager.getService();
1348                if (inm == null) {
1349                    return;
1350                }
1351
1352                ActivityRecord root = (ActivityRecord)msg.obj;
1353                ProcessRecord process = root.app;
1354                if (process == null) {
1355                    return;
1356                }
1357
1358                try {
1359                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1360                    String text = mContext.getString(R.string.heavy_weight_notification,
1361                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1362                    Notification notification = new Notification();
1363                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1364                    notification.when = 0;
1365                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1366                    notification.tickerText = text;
1367                    notification.defaults = 0; // please be quiet
1368                    notification.sound = null;
1369                    notification.vibrate = null;
1370                    notification.setLatestEventInfo(context, text,
1371                            mContext.getText(R.string.heavy_weight_notification_detail),
1372                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1373                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1374                                    new UserHandle(root.userId)));
1375
1376                    try {
1377                        int[] outId = new int[1];
1378                        inm.enqueueNotificationWithTag("android", "android", null,
1379                                R.string.heavy_weight_notification,
1380                                notification, outId, root.userId);
1381                    } catch (RuntimeException e) {
1382                        Slog.w(ActivityManagerService.TAG,
1383                                "Error showing notification for heavy-weight app", e);
1384                    } catch (RemoteException e) {
1385                    }
1386                } catch (NameNotFoundException e) {
1387                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1388                }
1389            } break;
1390            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1391                INotificationManager inm = NotificationManager.getService();
1392                if (inm == null) {
1393                    return;
1394                }
1395                try {
1396                    inm.cancelNotificationWithTag("android", null,
1397                            R.string.heavy_weight_notification,  msg.arg1);
1398                } catch (RuntimeException e) {
1399                    Slog.w(ActivityManagerService.TAG,
1400                            "Error canceling notification for service", e);
1401                } catch (RemoteException e) {
1402                }
1403            } break;
1404            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1405                synchronized (ActivityManagerService.this) {
1406                    checkExcessivePowerUsageLocked(true);
1407                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1408                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1409                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1410                }
1411            } break;
1412            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1413                synchronized (ActivityManagerService.this) {
1414                    ActivityRecord ar = (ActivityRecord)msg.obj;
1415                    if (mCompatModeDialog != null) {
1416                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1417                                ar.info.applicationInfo.packageName)) {
1418                            return;
1419                        }
1420                        mCompatModeDialog.dismiss();
1421                        mCompatModeDialog = null;
1422                    }
1423                    if (ar != null && false) {
1424                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1425                                ar.packageName)) {
1426                            int mode = mCompatModePackages.computeCompatModeLocked(
1427                                    ar.info.applicationInfo);
1428                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1429                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1430                                mCompatModeDialog = new CompatModeDialog(
1431                                        ActivityManagerService.this, mContext,
1432                                        ar.info.applicationInfo);
1433                                mCompatModeDialog.show();
1434                            }
1435                        }
1436                    }
1437                }
1438                break;
1439            }
1440            case DISPATCH_PROCESSES_CHANGED: {
1441                dispatchProcessesChanged();
1442                break;
1443            }
1444            case DISPATCH_PROCESS_DIED: {
1445                final int pid = msg.arg1;
1446                final int uid = msg.arg2;
1447                dispatchProcessDied(pid, uid);
1448                break;
1449            }
1450            case REPORT_MEM_USAGE_MSG: {
1451                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1452                Thread thread = new Thread() {
1453                    @Override public void run() {
1454                        final SparseArray<ProcessMemInfo> infoMap
1455                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1456                        for (int i=0, N=memInfos.size(); i<N; i++) {
1457                            ProcessMemInfo mi = memInfos.get(i);
1458                            infoMap.put(mi.pid, mi);
1459                        }
1460                        updateCpuStatsNow();
1461                        synchronized (mProcessCpuThread) {
1462                            final int N = mProcessCpuTracker.countStats();
1463                            for (int i=0; i<N; i++) {
1464                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1465                                if (st.vsize > 0) {
1466                                    long pss = Debug.getPss(st.pid, null);
1467                                    if (pss > 0) {
1468                                        if (infoMap.indexOfKey(st.pid) < 0) {
1469                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1470                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1471                                            mi.pss = pss;
1472                                            memInfos.add(mi);
1473                                        }
1474                                    }
1475                                }
1476                            }
1477                        }
1478
1479                        long totalPss = 0;
1480                        for (int i=0, N=memInfos.size(); i<N; i++) {
1481                            ProcessMemInfo mi = memInfos.get(i);
1482                            if (mi.pss == 0) {
1483                                mi.pss = Debug.getPss(mi.pid, null);
1484                            }
1485                            totalPss += mi.pss;
1486                        }
1487                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1488                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1489                                if (lhs.oomAdj != rhs.oomAdj) {
1490                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1491                                }
1492                                if (lhs.pss != rhs.pss) {
1493                                    return lhs.pss < rhs.pss ? 1 : -1;
1494                                }
1495                                return 0;
1496                            }
1497                        });
1498
1499                        StringBuilder tag = new StringBuilder(128);
1500                        StringBuilder stack = new StringBuilder(128);
1501                        tag.append("Low on memory -- ");
1502                        appendMemBucket(tag, totalPss, "total", false);
1503                        appendMemBucket(stack, totalPss, "total", true);
1504
1505                        StringBuilder logBuilder = new StringBuilder(1024);
1506                        logBuilder.append("Low on memory:\n");
1507
1508                        boolean firstLine = true;
1509                        int lastOomAdj = Integer.MIN_VALUE;
1510                        for (int i=0, N=memInfos.size(); i<N; i++) {
1511                            ProcessMemInfo mi = memInfos.get(i);
1512
1513                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1514                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1515                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1516                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1517                                if (lastOomAdj != mi.oomAdj) {
1518                                    lastOomAdj = mi.oomAdj;
1519                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1520                                        tag.append(" / ");
1521                                    }
1522                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1523                                        if (firstLine) {
1524                                            stack.append(":");
1525                                            firstLine = false;
1526                                        }
1527                                        stack.append("\n\t at ");
1528                                    } else {
1529                                        stack.append("$");
1530                                    }
1531                                } else {
1532                                    tag.append(" ");
1533                                    stack.append("$");
1534                                }
1535                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1536                                    appendMemBucket(tag, mi.pss, mi.name, false);
1537                                }
1538                                appendMemBucket(stack, mi.pss, mi.name, true);
1539                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1540                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1541                                    stack.append("(");
1542                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1543                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1544                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1545                                            stack.append(":");
1546                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1547                                        }
1548                                    }
1549                                    stack.append(")");
1550                                }
1551                            }
1552
1553                            logBuilder.append("  ");
1554                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1555                            logBuilder.append(' ');
1556                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1557                            logBuilder.append(' ');
1558                            ProcessList.appendRamKb(logBuilder, mi.pss);
1559                            logBuilder.append(" kB: ");
1560                            logBuilder.append(mi.name);
1561                            logBuilder.append(" (");
1562                            logBuilder.append(mi.pid);
1563                            logBuilder.append(") ");
1564                            logBuilder.append(mi.adjType);
1565                            logBuilder.append('\n');
1566                            if (mi.adjReason != null) {
1567                                logBuilder.append("                      ");
1568                                logBuilder.append(mi.adjReason);
1569                                logBuilder.append('\n');
1570                            }
1571                        }
1572
1573                        logBuilder.append("           ");
1574                        ProcessList.appendRamKb(logBuilder, totalPss);
1575                        logBuilder.append(" kB: TOTAL\n");
1576
1577                        long[] infos = new long[Debug.MEMINFO_COUNT];
1578                        Debug.getMemInfo(infos);
1579                        logBuilder.append("  MemInfo: ");
1580                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1581                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1582                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1583                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1584                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1585                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1586                            logBuilder.append("  ZRAM: ");
1587                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1588                            logBuilder.append(" kB RAM, ");
1589                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1590                            logBuilder.append(" kB swap total, ");
1591                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1592                            logBuilder.append(" kB swap free\n");
1593                        }
1594                        Slog.i(TAG, logBuilder.toString());
1595
1596                        StringBuilder dropBuilder = new StringBuilder(1024);
1597                        /*
1598                        StringWriter oomSw = new StringWriter();
1599                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1600                        StringWriter catSw = new StringWriter();
1601                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1602                        String[] emptyArgs = new String[] { };
1603                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1604                        oomPw.flush();
1605                        String oomString = oomSw.toString();
1606                        */
1607                        dropBuilder.append(stack);
1608                        dropBuilder.append('\n');
1609                        dropBuilder.append('\n');
1610                        dropBuilder.append(logBuilder);
1611                        dropBuilder.append('\n');
1612                        /*
1613                        dropBuilder.append(oomString);
1614                        dropBuilder.append('\n');
1615                        */
1616                        StringWriter catSw = new StringWriter();
1617                        synchronized (ActivityManagerService.this) {
1618                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1619                            String[] emptyArgs = new String[] { };
1620                            catPw.println();
1621                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1622                            catPw.println();
1623                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1624                                    false, false, null);
1625                            catPw.println();
1626                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1627                            catPw.flush();
1628                        }
1629                        dropBuilder.append(catSw.toString());
1630                        addErrorToDropBox("lowmem", null, "system_server", null,
1631                                null, tag.toString(), dropBuilder.toString(), null, null);
1632                        //Slog.i(TAG, "Sent to dropbox:");
1633                        //Slog.i(TAG, dropBuilder.toString());
1634                        synchronized (ActivityManagerService.this) {
1635                            long now = SystemClock.uptimeMillis();
1636                            if (mLastMemUsageReportTime < now) {
1637                                mLastMemUsageReportTime = now;
1638                            }
1639                        }
1640                    }
1641                };
1642                thread.start();
1643                break;
1644            }
1645            case REPORT_USER_SWITCH_MSG: {
1646                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1647                break;
1648            }
1649            case CONTINUE_USER_SWITCH_MSG: {
1650                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1651                break;
1652            }
1653            case USER_SWITCH_TIMEOUT_MSG: {
1654                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1655                break;
1656            }
1657            case IMMERSIVE_MODE_LOCK_MSG: {
1658                final boolean nextState = (msg.arg1 != 0);
1659                if (mUpdateLock.isHeld() != nextState) {
1660                    if (DEBUG_IMMERSIVE) {
1661                        final ActivityRecord r = (ActivityRecord) msg.obj;
1662                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1663                    }
1664                    if (nextState) {
1665                        mUpdateLock.acquire();
1666                    } else {
1667                        mUpdateLock.release();
1668                    }
1669                }
1670                break;
1671            }
1672            case PERSIST_URI_GRANTS_MSG: {
1673                writeGrantedUriPermissions();
1674                break;
1675            }
1676            case REQUEST_ALL_PSS_MSG: {
1677                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1678                break;
1679            }
1680            case UPDATE_TIME: {
1681                synchronized (ActivityManagerService.this) {
1682                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1683                        ProcessRecord r = mLruProcesses.get(i);
1684                        if (r.thread != null) {
1685                            try {
1686                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1687                            } catch (RemoteException ex) {
1688                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1689                            }
1690                        }
1691                    }
1692                }
1693
1694                break;
1695            }
1696            }
1697        }
1698    };
1699
1700    static final int COLLECT_PSS_BG_MSG = 1;
1701
1702    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1703        @Override
1704        public void handleMessage(Message msg) {
1705            switch (msg.what) {
1706            case COLLECT_PSS_BG_MSG: {
1707                int i=0, num=0;
1708                long start = SystemClock.uptimeMillis();
1709                long[] tmp = new long[1];
1710                do {
1711                    ProcessRecord proc;
1712                    int procState;
1713                    int pid;
1714                    synchronized (ActivityManagerService.this) {
1715                        if (i >= mPendingPssProcesses.size()) {
1716                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1717                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1718                            mPendingPssProcesses.clear();
1719                            return;
1720                        }
1721                        proc = mPendingPssProcesses.get(i);
1722                        procState = proc.pssProcState;
1723                        if (proc.thread != null && procState == proc.setProcState) {
1724                            pid = proc.pid;
1725                        } else {
1726                            proc = null;
1727                            pid = 0;
1728                        }
1729                        i++;
1730                    }
1731                    if (proc != null) {
1732                        long pss = Debug.getPss(pid, tmp);
1733                        synchronized (ActivityManagerService.this) {
1734                            if (proc.thread != null && proc.setProcState == procState
1735                                    && proc.pid == pid) {
1736                                num++;
1737                                proc.lastPssTime = SystemClock.uptimeMillis();
1738                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1739                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1740                                        + ": " + pss + " lastPss=" + proc.lastPss
1741                                        + " state=" + ProcessList.makeProcStateString(procState));
1742                                if (proc.initialIdlePss == 0) {
1743                                    proc.initialIdlePss = pss;
1744                                }
1745                                proc.lastPss = pss;
1746                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1747                                    proc.lastCachedPss = pss;
1748                                }
1749                            }
1750                        }
1751                    }
1752                } while (true);
1753            }
1754            }
1755        }
1756    };
1757
1758    public void setSystemProcess() {
1759        try {
1760            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1761            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1762            ServiceManager.addService("meminfo", new MemBinder(this));
1763            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1764            ServiceManager.addService("dbinfo", new DbBinder(this));
1765            if (MONITOR_CPU_USAGE) {
1766                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1767            }
1768            ServiceManager.addService("permission", new PermissionController(this));
1769
1770            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1771                    "android", STOCK_PM_FLAGS);
1772            mSystemThread.installSystemApplicationInfo(info);
1773
1774            synchronized (this) {
1775                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1776                app.persistent = true;
1777                app.pid = MY_PID;
1778                app.maxAdj = ProcessList.SYSTEM_ADJ;
1779                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1780                mProcessNames.put(app.processName, app.uid, app);
1781                synchronized (mPidsSelfLocked) {
1782                    mPidsSelfLocked.put(app.pid, app);
1783                }
1784                updateLruProcessLocked(app, false, null);
1785                updateOomAdjLocked();
1786            }
1787        } catch (PackageManager.NameNotFoundException e) {
1788            throw new RuntimeException(
1789                    "Unable to find android system package", e);
1790        }
1791    }
1792
1793    public void setWindowManager(WindowManagerService wm) {
1794        mWindowManager = wm;
1795        mStackSupervisor.setWindowManager(wm);
1796    }
1797
1798    public void startObservingNativeCrashes() {
1799        final NativeCrashListener ncl = new NativeCrashListener(this);
1800        ncl.start();
1801    }
1802
1803    public IAppOpsService getAppOpsService() {
1804        return mAppOpsService;
1805    }
1806
1807    static class MemBinder extends Binder {
1808        ActivityManagerService mActivityManagerService;
1809        MemBinder(ActivityManagerService activityManagerService) {
1810            mActivityManagerService = activityManagerService;
1811        }
1812
1813        @Override
1814        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1815            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1816                    != PackageManager.PERMISSION_GRANTED) {
1817                pw.println("Permission Denial: can't dump meminfo from from pid="
1818                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1819                        + " without permission " + android.Manifest.permission.DUMP);
1820                return;
1821            }
1822
1823            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1824        }
1825    }
1826
1827    static class GraphicsBinder extends Binder {
1828        ActivityManagerService mActivityManagerService;
1829        GraphicsBinder(ActivityManagerService activityManagerService) {
1830            mActivityManagerService = activityManagerService;
1831        }
1832
1833        @Override
1834        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1835            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1836                    != PackageManager.PERMISSION_GRANTED) {
1837                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1838                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1839                        + " without permission " + android.Manifest.permission.DUMP);
1840                return;
1841            }
1842
1843            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1844        }
1845    }
1846
1847    static class DbBinder extends Binder {
1848        ActivityManagerService mActivityManagerService;
1849        DbBinder(ActivityManagerService activityManagerService) {
1850            mActivityManagerService = activityManagerService;
1851        }
1852
1853        @Override
1854        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1855            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1856                    != PackageManager.PERMISSION_GRANTED) {
1857                pw.println("Permission Denial: can't dump dbinfo from from pid="
1858                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1859                        + " without permission " + android.Manifest.permission.DUMP);
1860                return;
1861            }
1862
1863            mActivityManagerService.dumpDbInfo(fd, pw, args);
1864        }
1865    }
1866
1867    static class CpuBinder extends Binder {
1868        ActivityManagerService mActivityManagerService;
1869        CpuBinder(ActivityManagerService activityManagerService) {
1870            mActivityManagerService = activityManagerService;
1871        }
1872
1873        @Override
1874        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1875            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1876                    != PackageManager.PERMISSION_GRANTED) {
1877                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1878                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1879                        + " without permission " + android.Manifest.permission.DUMP);
1880                return;
1881            }
1882
1883            synchronized (mActivityManagerService.mProcessCpuThread) {
1884                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1885                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1886                        SystemClock.uptimeMillis()));
1887            }
1888        }
1889    }
1890
1891    public static final class Lifecycle extends SystemService {
1892        private final ActivityManagerService mService;
1893
1894        public Lifecycle(Context context) {
1895            super(context);
1896            mService = new ActivityManagerService(context);
1897        }
1898
1899        @Override
1900        public void onStart() {
1901            mService.start();
1902        }
1903
1904        public ActivityManagerService getService() {
1905            return mService;
1906        }
1907    }
1908
1909    // Note: This method is invoked on the main thread but may need to attach various
1910    // handlers to other threads.  So take care to be explicit about the looper.
1911    public ActivityManagerService(Context systemContext) {
1912        mContext = systemContext;
1913        mFactoryTest = FactoryTest.getMode();
1914        mSystemThread = ActivityThread.currentActivityThread();
1915
1916        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1917
1918        mHandlerThread = new ServiceThread(TAG,
1919                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1920        mHandlerThread.start();
1921        mHandler = new MainHandler(mHandlerThread.getLooper());
1922
1923        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1924                "foreground", BROADCAST_FG_TIMEOUT, false);
1925        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1926                "background", BROADCAST_BG_TIMEOUT, true);
1927        mBroadcastQueues[0] = mFgBroadcastQueue;
1928        mBroadcastQueues[1] = mBgBroadcastQueue;
1929
1930        mServices = new ActiveServices(this);
1931        mProviderMap = new ProviderMap(this);
1932
1933        // TODO: Move creation of battery stats service outside of activity manager service.
1934        File dataDir = Environment.getDataDirectory();
1935        File systemDir = new File(dataDir, "system");
1936        systemDir.mkdirs();
1937        mBatteryStatsService = new BatteryStatsService(new File(
1938                systemDir, "batterystats.bin").toString(), mHandler);
1939        mBatteryStatsService.getActiveStatistics().readLocked();
1940        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1941        mOnBattery = DEBUG_POWER ? true
1942                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1943        mBatteryStatsService.getActiveStatistics().setCallback(this);
1944
1945        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1946
1947        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1948        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1949
1950        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1951
1952        // User 0 is the first and only user that runs at boot.
1953        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1954        mUserLru.add(Integer.valueOf(0));
1955        updateStartedUserArrayLocked();
1956
1957        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1958            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1959
1960        mConfiguration.setToDefaults();
1961        mConfiguration.setLocale(Locale.getDefault());
1962
1963        mConfigurationSeq = mConfiguration.seq = 1;
1964        mProcessCpuTracker.init();
1965
1966        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1967        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1968        mStackSupervisor = new ActivityStackSupervisor(this);
1969
1970        mProcessCpuThread = new Thread("CpuTracker") {
1971            @Override
1972            public void run() {
1973                while (true) {
1974                    try {
1975                        try {
1976                            synchronized(this) {
1977                                final long now = SystemClock.uptimeMillis();
1978                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1979                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1980                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1981                                //        + ", write delay=" + nextWriteDelay);
1982                                if (nextWriteDelay < nextCpuDelay) {
1983                                    nextCpuDelay = nextWriteDelay;
1984                                }
1985                                if (nextCpuDelay > 0) {
1986                                    mProcessCpuMutexFree.set(true);
1987                                    this.wait(nextCpuDelay);
1988                                }
1989                            }
1990                        } catch (InterruptedException e) {
1991                        }
1992                        updateCpuStatsNow();
1993                    } catch (Exception e) {
1994                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1995                    }
1996                }
1997            }
1998        };
1999
2000        Watchdog.getInstance().addMonitor(this);
2001        Watchdog.getInstance().addThread(mHandler);
2002    }
2003
2004    private void start() {
2005        mProcessCpuThread.start();
2006
2007        mBatteryStatsService.publish(mContext);
2008        mUsageStatsService.publish(mContext);
2009        mAppOpsService.publish(mContext);
2010
2011        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2012    }
2013
2014    @Override
2015    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2016            throws RemoteException {
2017        if (code == SYSPROPS_TRANSACTION) {
2018            // We need to tell all apps about the system property change.
2019            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2020            synchronized(this) {
2021                final int NP = mProcessNames.getMap().size();
2022                for (int ip=0; ip<NP; ip++) {
2023                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2024                    final int NA = apps.size();
2025                    for (int ia=0; ia<NA; ia++) {
2026                        ProcessRecord app = apps.valueAt(ia);
2027                        if (app.thread != null) {
2028                            procs.add(app.thread.asBinder());
2029                        }
2030                    }
2031                }
2032            }
2033
2034            int N = procs.size();
2035            for (int i=0; i<N; i++) {
2036                Parcel data2 = Parcel.obtain();
2037                try {
2038                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2039                } catch (RemoteException e) {
2040                }
2041                data2.recycle();
2042            }
2043        }
2044        try {
2045            return super.onTransact(code, data, reply, flags);
2046        } catch (RuntimeException e) {
2047            // The activity manager only throws security exceptions, so let's
2048            // log all others.
2049            if (!(e instanceof SecurityException)) {
2050                Slog.wtf(TAG, "Activity Manager Crash", e);
2051            }
2052            throw e;
2053        }
2054    }
2055
2056    void updateCpuStats() {
2057        final long now = SystemClock.uptimeMillis();
2058        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2059            return;
2060        }
2061        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2062            synchronized (mProcessCpuThread) {
2063                mProcessCpuThread.notify();
2064            }
2065        }
2066    }
2067
2068    void updateCpuStatsNow() {
2069        synchronized (mProcessCpuThread) {
2070            mProcessCpuMutexFree.set(false);
2071            final long now = SystemClock.uptimeMillis();
2072            boolean haveNewCpuStats = false;
2073
2074            if (MONITOR_CPU_USAGE &&
2075                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2076                mLastCpuTime.set(now);
2077                haveNewCpuStats = true;
2078                mProcessCpuTracker.update();
2079                //Slog.i(TAG, mProcessCpu.printCurrentState());
2080                //Slog.i(TAG, "Total CPU usage: "
2081                //        + mProcessCpu.getTotalCpuPercent() + "%");
2082
2083                // Slog the cpu usage if the property is set.
2084                if ("true".equals(SystemProperties.get("events.cpu"))) {
2085                    int user = mProcessCpuTracker.getLastUserTime();
2086                    int system = mProcessCpuTracker.getLastSystemTime();
2087                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2088                    int irq = mProcessCpuTracker.getLastIrqTime();
2089                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2090                    int idle = mProcessCpuTracker.getLastIdleTime();
2091
2092                    int total = user + system + iowait + irq + softIrq + idle;
2093                    if (total == 0) total = 1;
2094
2095                    EventLog.writeEvent(EventLogTags.CPU,
2096                            ((user+system+iowait+irq+softIrq) * 100) / total,
2097                            (user * 100) / total,
2098                            (system * 100) / total,
2099                            (iowait * 100) / total,
2100                            (irq * 100) / total,
2101                            (softIrq * 100) / total);
2102                }
2103            }
2104
2105            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2106            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2107            synchronized(bstats) {
2108                synchronized(mPidsSelfLocked) {
2109                    if (haveNewCpuStats) {
2110                        if (mOnBattery) {
2111                            int perc = bstats.startAddingCpuLocked();
2112                            int totalUTime = 0;
2113                            int totalSTime = 0;
2114                            final int N = mProcessCpuTracker.countStats();
2115                            for (int i=0; i<N; i++) {
2116                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2117                                if (!st.working) {
2118                                    continue;
2119                                }
2120                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2121                                int otherUTime = (st.rel_utime*perc)/100;
2122                                int otherSTime = (st.rel_stime*perc)/100;
2123                                totalUTime += otherUTime;
2124                                totalSTime += otherSTime;
2125                                if (pr != null) {
2126                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
2127                                            st.name, st.pid);
2128                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2129                                            st.rel_stime-otherSTime);
2130                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2131                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2132                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
2133                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2134                                    if (ps == null) {
2135                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
2136                                                "(Unknown)");
2137                                    }
2138                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2139                                            st.rel_stime-otherSTime);
2140                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2141                                } else {
2142                                    BatteryStatsImpl.Uid.Proc ps =
2143                                            bstats.getProcessStatsLocked(st.name, st.pid);
2144                                    if (ps != null) {
2145                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2146                                                st.rel_stime-otherSTime);
2147                                        ps.addSpeedStepTimes(cpuSpeedTimes);
2148                                    }
2149                                }
2150                            }
2151                            bstats.finishAddingCpuLocked(perc, totalUTime,
2152                                    totalSTime, cpuSpeedTimes);
2153                        }
2154                    }
2155                }
2156
2157                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2158                    mLastWriteTime = now;
2159                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2160                }
2161            }
2162        }
2163    }
2164
2165    @Override
2166    public void batteryNeedsCpuUpdate() {
2167        updateCpuStatsNow();
2168    }
2169
2170    @Override
2171    public void batteryPowerChanged(boolean onBattery) {
2172        // When plugging in, update the CPU stats first before changing
2173        // the plug state.
2174        updateCpuStatsNow();
2175        synchronized (this) {
2176            synchronized(mPidsSelfLocked) {
2177                mOnBattery = DEBUG_POWER ? true : onBattery;
2178            }
2179        }
2180    }
2181
2182    /**
2183     * Initialize the application bind args. These are passed to each
2184     * process when the bindApplication() IPC is sent to the process. They're
2185     * lazily setup to make sure the services are running when they're asked for.
2186     */
2187    private HashMap<String, IBinder> getCommonServicesLocked() {
2188        if (mAppBindArgs == null) {
2189            mAppBindArgs = new HashMap<String, IBinder>();
2190
2191            // Setup the application init args
2192            mAppBindArgs.put("package", ServiceManager.getService("package"));
2193            mAppBindArgs.put("window", ServiceManager.getService("window"));
2194            mAppBindArgs.put(Context.ALARM_SERVICE,
2195                    ServiceManager.getService(Context.ALARM_SERVICE));
2196        }
2197        return mAppBindArgs;
2198    }
2199
2200    final void setFocusedActivityLocked(ActivityRecord r) {
2201        if (mFocusedActivity != r) {
2202            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2203            mFocusedActivity = r;
2204            mStackSupervisor.setFocusedStack(r);
2205            if (r != null) {
2206                mWindowManager.setFocusedApp(r.appToken, true);
2207            }
2208            applyUpdateLockStateLocked(r);
2209        }
2210    }
2211
2212    @Override
2213    public void setFocusedStack(int stackId) {
2214        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2215        synchronized (ActivityManagerService.this) {
2216            ActivityStack stack = mStackSupervisor.getStack(stackId);
2217            if (stack != null) {
2218                ActivityRecord r = stack.topRunningActivityLocked(null);
2219                if (r != null) {
2220                    setFocusedActivityLocked(r);
2221                }
2222            }
2223        }
2224    }
2225
2226    @Override
2227    public void notifyActivityDrawn(IBinder token) {
2228        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2229        synchronized (this) {
2230            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2231            if (r != null) {
2232                r.task.stack.notifyActivityDrawnLocked(r);
2233            }
2234        }
2235    }
2236
2237    final void applyUpdateLockStateLocked(ActivityRecord r) {
2238        // Modifications to the UpdateLock state are done on our handler, outside
2239        // the activity manager's locks.  The new state is determined based on the
2240        // state *now* of the relevant activity record.  The object is passed to
2241        // the handler solely for logging detail, not to be consulted/modified.
2242        final boolean nextState = r != null && r.immersive;
2243        mHandler.sendMessage(
2244                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2245    }
2246
2247    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2248        Message msg = Message.obtain();
2249        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2250        msg.obj = r.task.askedCompatMode ? null : r;
2251        mHandler.sendMessage(msg);
2252    }
2253
2254    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2255            String what, Object obj, ProcessRecord srcApp) {
2256        app.lastActivityTime = now;
2257
2258        if (app.activities.size() > 0) {
2259            // Don't want to touch dependent processes that are hosting activities.
2260            return index;
2261        }
2262
2263        int lrui = mLruProcesses.lastIndexOf(app);
2264        if (lrui < 0) {
2265            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2266                    + what + " " + obj + " from " + srcApp);
2267            return index;
2268        }
2269
2270        if (lrui >= index) {
2271            // Don't want to cause this to move dependent processes *back* in the
2272            // list as if they were less frequently used.
2273            return index;
2274        }
2275
2276        if (lrui >= mLruProcessActivityStart) {
2277            // Don't want to touch dependent processes that are hosting activities.
2278            return index;
2279        }
2280
2281        mLruProcesses.remove(lrui);
2282        if (index > 0) {
2283            index--;
2284        }
2285        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2286                + " in LRU list: " + app);
2287        mLruProcesses.add(index, app);
2288        return index;
2289    }
2290
2291    final void removeLruProcessLocked(ProcessRecord app) {
2292        int lrui = mLruProcesses.lastIndexOf(app);
2293        if (lrui >= 0) {
2294            if (lrui <= mLruProcessActivityStart) {
2295                mLruProcessActivityStart--;
2296            }
2297            if (lrui <= mLruProcessServiceStart) {
2298                mLruProcessServiceStart--;
2299            }
2300            mLruProcesses.remove(lrui);
2301        }
2302    }
2303
2304    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2305            ProcessRecord client) {
2306        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2307        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2308        if (!activityChange && hasActivity) {
2309            // The process has activties, so we are only going to allow activity-based
2310            // adjustments move it.  It should be kept in the front of the list with other
2311            // processes that have activities, and we don't want those to change their
2312            // order except due to activity operations.
2313            return;
2314        }
2315
2316        mLruSeq++;
2317        final long now = SystemClock.uptimeMillis();
2318        app.lastActivityTime = now;
2319
2320        // First a quick reject: if the app is already at the position we will
2321        // put it, then there is nothing to do.
2322        if (hasActivity) {
2323            final int N = mLruProcesses.size();
2324            if (N > 0 && mLruProcesses.get(N-1) == app) {
2325                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2326                return;
2327            }
2328        } else {
2329            if (mLruProcessServiceStart > 0
2330                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2331                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2332                return;
2333            }
2334        }
2335
2336        int lrui = mLruProcesses.lastIndexOf(app);
2337
2338        if (app.persistent && lrui >= 0) {
2339            // We don't care about the position of persistent processes, as long as
2340            // they are in the list.
2341            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2342            return;
2343        }
2344
2345        /* In progress: compute new position first, so we can avoid doing work
2346           if the process is not actually going to move.  Not yet working.
2347        int addIndex;
2348        int nextIndex;
2349        boolean inActivity = false, inService = false;
2350        if (hasActivity) {
2351            // Process has activities, put it at the very tipsy-top.
2352            addIndex = mLruProcesses.size();
2353            nextIndex = mLruProcessServiceStart;
2354            inActivity = true;
2355        } else if (hasService) {
2356            // Process has services, put it at the top of the service list.
2357            addIndex = mLruProcessActivityStart;
2358            nextIndex = mLruProcessServiceStart;
2359            inActivity = true;
2360            inService = true;
2361        } else  {
2362            // Process not otherwise of interest, it goes to the top of the non-service area.
2363            addIndex = mLruProcessServiceStart;
2364            if (client != null) {
2365                int clientIndex = mLruProcesses.lastIndexOf(client);
2366                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2367                        + app);
2368                if (clientIndex >= 0 && addIndex > clientIndex) {
2369                    addIndex = clientIndex;
2370                }
2371            }
2372            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2373        }
2374
2375        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2376                + mLruProcessActivityStart + "): " + app);
2377        */
2378
2379        if (lrui >= 0) {
2380            if (lrui < mLruProcessActivityStart) {
2381                mLruProcessActivityStart--;
2382            }
2383            if (lrui < mLruProcessServiceStart) {
2384                mLruProcessServiceStart--;
2385            }
2386            /*
2387            if (addIndex > lrui) {
2388                addIndex--;
2389            }
2390            if (nextIndex > lrui) {
2391                nextIndex--;
2392            }
2393            */
2394            mLruProcesses.remove(lrui);
2395        }
2396
2397        /*
2398        mLruProcesses.add(addIndex, app);
2399        if (inActivity) {
2400            mLruProcessActivityStart++;
2401        }
2402        if (inService) {
2403            mLruProcessActivityStart++;
2404        }
2405        */
2406
2407        int nextIndex;
2408        if (hasActivity) {
2409            final int N = mLruProcesses.size();
2410            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2411                // Process doesn't have activities, but has clients with
2412                // activities...  move it up, but one below the top (the top
2413                // should always have a real activity).
2414                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2415                mLruProcesses.add(N-1, app);
2416                // To keep it from spamming the LRU list (by making a bunch of clients),
2417                // we will push down any other entries owned by the app.
2418                final int uid = app.info.uid;
2419                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2420                    ProcessRecord subProc = mLruProcesses.get(i);
2421                    if (subProc.info.uid == uid) {
2422                        // We want to push this one down the list.  If the process after
2423                        // it is for the same uid, however, don't do so, because we don't
2424                        // want them internally to be re-ordered.
2425                        if (mLruProcesses.get(i-1).info.uid != uid) {
2426                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2427                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2428                            ProcessRecord tmp = mLruProcesses.get(i);
2429                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2430                            mLruProcesses.set(i-1, tmp);
2431                            i--;
2432                        }
2433                    } else {
2434                        // A gap, we can stop here.
2435                        break;
2436                    }
2437                }
2438            } else {
2439                // Process has activities, put it at the very tipsy-top.
2440                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2441                mLruProcesses.add(app);
2442            }
2443            nextIndex = mLruProcessServiceStart;
2444        } else if (hasService) {
2445            // Process has services, put it at the top of the service list.
2446            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2447            mLruProcesses.add(mLruProcessActivityStart, app);
2448            nextIndex = mLruProcessServiceStart;
2449            mLruProcessActivityStart++;
2450        } else  {
2451            // Process not otherwise of interest, it goes to the top of the non-service area.
2452            int index = mLruProcessServiceStart;
2453            if (client != null) {
2454                // If there is a client, don't allow the process to be moved up higher
2455                // in the list than that client.
2456                int clientIndex = mLruProcesses.lastIndexOf(client);
2457                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2458                        + " when updating " + app);
2459                if (clientIndex <= lrui) {
2460                    // Don't allow the client index restriction to push it down farther in the
2461                    // list than it already is.
2462                    clientIndex = lrui;
2463                }
2464                if (clientIndex >= 0 && index > clientIndex) {
2465                    index = clientIndex;
2466                }
2467            }
2468            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2469            mLruProcesses.add(index, app);
2470            nextIndex = index-1;
2471            mLruProcessActivityStart++;
2472            mLruProcessServiceStart++;
2473        }
2474
2475        // If the app is currently using a content provider or service,
2476        // bump those processes as well.
2477        for (int j=app.connections.size()-1; j>=0; j--) {
2478            ConnectionRecord cr = app.connections.valueAt(j);
2479            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2480                    && cr.binding.service.app != null
2481                    && cr.binding.service.app.lruSeq != mLruSeq
2482                    && !cr.binding.service.app.persistent) {
2483                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2484                        "service connection", cr, app);
2485            }
2486        }
2487        for (int j=app.conProviders.size()-1; j>=0; j--) {
2488            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2489            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2490                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2491                        "provider reference", cpr, app);
2492            }
2493        }
2494    }
2495
2496    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2497        if (uid == Process.SYSTEM_UID) {
2498            // The system gets to run in any process.  If there are multiple
2499            // processes with the same uid, just pick the first (this
2500            // should never happen).
2501            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2502            if (procs == null) return null;
2503            final int N = procs.size();
2504            for (int i = 0; i < N; i++) {
2505                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2506            }
2507        }
2508        ProcessRecord proc = mProcessNames.get(processName, uid);
2509        if (false && proc != null && !keepIfLarge
2510                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2511                && proc.lastCachedPss >= 4000) {
2512            // Turn this condition on to cause killing to happen regularly, for testing.
2513            if (proc.baseProcessTracker != null) {
2514                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2515            }
2516            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2517                    + "k from cached");
2518        } else if (proc != null && !keepIfLarge
2519                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2520                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2521            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2522            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2523                if (proc.baseProcessTracker != null) {
2524                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2525                }
2526                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2527                        + "k from cached");
2528            }
2529        }
2530        return proc;
2531    }
2532
2533    void ensurePackageDexOpt(String packageName) {
2534        IPackageManager pm = AppGlobals.getPackageManager();
2535        try {
2536            if (pm.performDexOpt(packageName)) {
2537                mDidDexOpt = true;
2538            }
2539        } catch (RemoteException e) {
2540        }
2541    }
2542
2543    boolean isNextTransitionForward() {
2544        int transit = mWindowManager.getPendingAppTransition();
2545        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2546                || transit == AppTransition.TRANSIT_TASK_OPEN
2547                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2548    }
2549
2550    final ProcessRecord startProcessLocked(String processName,
2551            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2552            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2553            boolean isolated, boolean keepIfLarge) {
2554        ProcessRecord app;
2555        if (!isolated) {
2556            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2557        } else {
2558            // If this is an isolated process, it can't re-use an existing process.
2559            app = null;
2560        }
2561        // We don't have to do anything more if:
2562        // (1) There is an existing application record; and
2563        // (2) The caller doesn't think it is dead, OR there is no thread
2564        //     object attached to it so we know it couldn't have crashed; and
2565        // (3) There is a pid assigned to it, so it is either starting or
2566        //     already running.
2567        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2568                + " app=" + app + " knownToBeDead=" + knownToBeDead
2569                + " thread=" + (app != null ? app.thread : null)
2570                + " pid=" + (app != null ? app.pid : -1));
2571        if (app != null && app.pid > 0) {
2572            if (!knownToBeDead || app.thread == null) {
2573                // We already have the app running, or are waiting for it to
2574                // come up (we have a pid but not yet its thread), so keep it.
2575                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2576                // If this is a new package in the process, add the package to the list
2577                app.addPackage(info.packageName, mProcessStats);
2578                return app;
2579            }
2580
2581            // An application record is attached to a previous process,
2582            // clean it up now.
2583            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2584            handleAppDiedLocked(app, true, true);
2585        }
2586
2587        String hostingNameStr = hostingName != null
2588                ? hostingName.flattenToShortString() : null;
2589
2590        if (!isolated) {
2591            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2592                // If we are in the background, then check to see if this process
2593                // is bad.  If so, we will just silently fail.
2594                if (mBadProcesses.get(info.processName, info.uid) != null) {
2595                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2596                            + "/" + info.processName);
2597                    return null;
2598                }
2599            } else {
2600                // When the user is explicitly starting a process, then clear its
2601                // crash count so that we won't make it bad until they see at
2602                // least one crash dialog again, and make the process good again
2603                // if it had been bad.
2604                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2605                        + "/" + info.processName);
2606                mProcessCrashTimes.remove(info.processName, info.uid);
2607                if (mBadProcesses.get(info.processName, info.uid) != null) {
2608                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2609                            UserHandle.getUserId(info.uid), info.uid,
2610                            info.processName);
2611                    mBadProcesses.remove(info.processName, info.uid);
2612                    if (app != null) {
2613                        app.bad = false;
2614                    }
2615                }
2616            }
2617        }
2618
2619        if (app == null) {
2620            app = newProcessRecordLocked(info, processName, isolated);
2621            if (app == null) {
2622                Slog.w(TAG, "Failed making new process record for "
2623                        + processName + "/" + info.uid + " isolated=" + isolated);
2624                return null;
2625            }
2626            mProcessNames.put(processName, app.uid, app);
2627            if (isolated) {
2628                mIsolatedProcesses.put(app.uid, app);
2629            }
2630        } else {
2631            // If this is a new package in the process, add the package to the list
2632            app.addPackage(info.packageName, mProcessStats);
2633        }
2634
2635        // If the system is not ready yet, then hold off on starting this
2636        // process until it is.
2637        if (!mProcessesReady
2638                && !isAllowedWhileBooting(info)
2639                && !allowWhileBooting) {
2640            if (!mProcessesOnHold.contains(app)) {
2641                mProcessesOnHold.add(app);
2642            }
2643            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2644            return app;
2645        }
2646
2647        startProcessLocked(app, hostingType, hostingNameStr);
2648        return (app.pid != 0) ? app : null;
2649    }
2650
2651    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2652        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2653    }
2654
2655    private final void startProcessLocked(ProcessRecord app,
2656            String hostingType, String hostingNameStr) {
2657        if (app.pid > 0 && app.pid != MY_PID) {
2658            synchronized (mPidsSelfLocked) {
2659                mPidsSelfLocked.remove(app.pid);
2660                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2661            }
2662            app.setPid(0);
2663        }
2664
2665        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2666                "startProcessLocked removing on hold: " + app);
2667        mProcessesOnHold.remove(app);
2668
2669        updateCpuStats();
2670
2671        try {
2672            int uid = app.uid;
2673
2674            int[] gids = null;
2675            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2676            if (!app.isolated) {
2677                int[] permGids = null;
2678                try {
2679                    final PackageManager pm = mContext.getPackageManager();
2680                    permGids = pm.getPackageGids(app.info.packageName);
2681
2682                    if (Environment.isExternalStorageEmulated()) {
2683                        if (pm.checkPermission(
2684                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2685                                app.info.packageName) == PERMISSION_GRANTED) {
2686                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2687                        } else {
2688                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2689                        }
2690                    }
2691                } catch (PackageManager.NameNotFoundException e) {
2692                    Slog.w(TAG, "Unable to retrieve gids", e);
2693                }
2694
2695                /*
2696                 * Add shared application GID so applications can share some
2697                 * resources like shared libraries
2698                 */
2699                if (permGids == null) {
2700                    gids = new int[1];
2701                } else {
2702                    gids = new int[permGids.length + 1];
2703                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2704                }
2705                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2706            }
2707            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2708                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2709                        && mTopComponent != null
2710                        && app.processName.equals(mTopComponent.getPackageName())) {
2711                    uid = 0;
2712                }
2713                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2714                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2715                    uid = 0;
2716                }
2717            }
2718            int debugFlags = 0;
2719            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2720                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2721                // Also turn on CheckJNI for debuggable apps. It's quite
2722                // awkward to turn on otherwise.
2723                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2724            }
2725            // Run the app in safe mode if its manifest requests so or the
2726            // system is booted in safe mode.
2727            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2728                mSafeMode == true) {
2729                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2730            }
2731            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2732                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2733            }
2734            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2735                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2736            }
2737            if ("1".equals(SystemProperties.get("debug.assert"))) {
2738                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2739            }
2740
2741            // Start the process.  It will either succeed and return a result containing
2742            // the PID of the new process, or else throw a RuntimeException.
2743            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2744                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2745                    app.info.targetSdkVersion, app.info.seinfo, null);
2746
2747            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2748            synchronized (bs) {
2749                if (bs.isOnBattery()) {
2750                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2751                }
2752            }
2753
2754            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2755                    UserHandle.getUserId(uid), startResult.pid, uid,
2756                    app.processName, hostingType,
2757                    hostingNameStr != null ? hostingNameStr : "");
2758
2759            if (app.persistent) {
2760                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2761            }
2762
2763            StringBuilder buf = mStringBuilder;
2764            buf.setLength(0);
2765            buf.append("Start proc ");
2766            buf.append(app.processName);
2767            buf.append(" for ");
2768            buf.append(hostingType);
2769            if (hostingNameStr != null) {
2770                buf.append(" ");
2771                buf.append(hostingNameStr);
2772            }
2773            buf.append(": pid=");
2774            buf.append(startResult.pid);
2775            buf.append(" uid=");
2776            buf.append(uid);
2777            buf.append(" gids={");
2778            if (gids != null) {
2779                for (int gi=0; gi<gids.length; gi++) {
2780                    if (gi != 0) buf.append(", ");
2781                    buf.append(gids[gi]);
2782
2783                }
2784            }
2785            buf.append("}");
2786            Slog.i(TAG, buf.toString());
2787            app.setPid(startResult.pid);
2788            app.usingWrapper = startResult.usingWrapper;
2789            app.removed = false;
2790            synchronized (mPidsSelfLocked) {
2791                this.mPidsSelfLocked.put(startResult.pid, app);
2792                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2793                msg.obj = app;
2794                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2795                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2796            }
2797        } catch (RuntimeException e) {
2798            // XXX do better error recovery.
2799            app.setPid(0);
2800            Slog.e(TAG, "Failure starting process " + app.processName, e);
2801        }
2802    }
2803
2804    void updateUsageStats(ActivityRecord component, boolean resumed) {
2805        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2806        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2807        if (resumed) {
2808            mUsageStatsService.noteResumeComponent(component.realActivity);
2809            synchronized (stats) {
2810                stats.noteActivityResumedLocked(component.app.uid);
2811            }
2812        } else {
2813            mUsageStatsService.notePauseComponent(component.realActivity);
2814            synchronized (stats) {
2815                stats.noteActivityPausedLocked(component.app.uid);
2816            }
2817        }
2818    }
2819
2820    Intent getHomeIntent() {
2821        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2822        intent.setComponent(mTopComponent);
2823        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2824            intent.addCategory(Intent.CATEGORY_HOME);
2825        }
2826        return intent;
2827    }
2828
2829    boolean startHomeActivityLocked(int userId) {
2830        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2831                && mTopAction == null) {
2832            // We are running in factory test mode, but unable to find
2833            // the factory test app, so just sit around displaying the
2834            // error message and don't try to start anything.
2835            return false;
2836        }
2837        Intent intent = getHomeIntent();
2838        ActivityInfo aInfo =
2839            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2840        if (aInfo != null) {
2841            intent.setComponent(new ComponentName(
2842                    aInfo.applicationInfo.packageName, aInfo.name));
2843            // Don't do this if the home app is currently being
2844            // instrumented.
2845            aInfo = new ActivityInfo(aInfo);
2846            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2847            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2848                    aInfo.applicationInfo.uid, true);
2849            if (app == null || app.instrumentationClass == null) {
2850                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2851                mStackSupervisor.startHomeActivity(intent, aInfo);
2852            }
2853        }
2854
2855        return true;
2856    }
2857
2858    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2859        ActivityInfo ai = null;
2860        ComponentName comp = intent.getComponent();
2861        try {
2862            if (comp != null) {
2863                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2864            } else {
2865                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2866                        intent,
2867                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2868                            flags, userId);
2869
2870                if (info != null) {
2871                    ai = info.activityInfo;
2872                }
2873            }
2874        } catch (RemoteException e) {
2875            // ignore
2876        }
2877
2878        return ai;
2879    }
2880
2881    /**
2882     * Starts the "new version setup screen" if appropriate.
2883     */
2884    void startSetupActivityLocked() {
2885        // Only do this once per boot.
2886        if (mCheckedForSetup) {
2887            return;
2888        }
2889
2890        // We will show this screen if the current one is a different
2891        // version than the last one shown, and we are not running in
2892        // low-level factory test mode.
2893        final ContentResolver resolver = mContext.getContentResolver();
2894        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2895                Settings.Global.getInt(resolver,
2896                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2897            mCheckedForSetup = true;
2898
2899            // See if we should be showing the platform update setup UI.
2900            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2901            List<ResolveInfo> ris = mContext.getPackageManager()
2902                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2903
2904            // We don't allow third party apps to replace this.
2905            ResolveInfo ri = null;
2906            for (int i=0; ris != null && i<ris.size(); i++) {
2907                if ((ris.get(i).activityInfo.applicationInfo.flags
2908                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2909                    ri = ris.get(i);
2910                    break;
2911                }
2912            }
2913
2914            if (ri != null) {
2915                String vers = ri.activityInfo.metaData != null
2916                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2917                        : null;
2918                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2919                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2920                            Intent.METADATA_SETUP_VERSION);
2921                }
2922                String lastVers = Settings.Secure.getString(
2923                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2924                if (vers != null && !vers.equals(lastVers)) {
2925                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2926                    intent.setComponent(new ComponentName(
2927                            ri.activityInfo.packageName, ri.activityInfo.name));
2928                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2929                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2930                }
2931            }
2932        }
2933    }
2934
2935    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2936        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2937    }
2938
2939    void enforceNotIsolatedCaller(String caller) {
2940        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2941            throw new SecurityException("Isolated process not allowed to call " + caller);
2942        }
2943    }
2944
2945    @Override
2946    public int getFrontActivityScreenCompatMode() {
2947        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2948        synchronized (this) {
2949            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2950        }
2951    }
2952
2953    @Override
2954    public void setFrontActivityScreenCompatMode(int mode) {
2955        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2956                "setFrontActivityScreenCompatMode");
2957        synchronized (this) {
2958            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2959        }
2960    }
2961
2962    @Override
2963    public int getPackageScreenCompatMode(String packageName) {
2964        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2965        synchronized (this) {
2966            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2967        }
2968    }
2969
2970    @Override
2971    public void setPackageScreenCompatMode(String packageName, int mode) {
2972        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2973                "setPackageScreenCompatMode");
2974        synchronized (this) {
2975            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2976        }
2977    }
2978
2979    @Override
2980    public boolean getPackageAskScreenCompat(String packageName) {
2981        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2982        synchronized (this) {
2983            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2984        }
2985    }
2986
2987    @Override
2988    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2989        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2990                "setPackageAskScreenCompat");
2991        synchronized (this) {
2992            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2993        }
2994    }
2995
2996    private void dispatchProcessesChanged() {
2997        int N;
2998        synchronized (this) {
2999            N = mPendingProcessChanges.size();
3000            if (mActiveProcessChanges.length < N) {
3001                mActiveProcessChanges = new ProcessChangeItem[N];
3002            }
3003            mPendingProcessChanges.toArray(mActiveProcessChanges);
3004            mAvailProcessChanges.addAll(mPendingProcessChanges);
3005            mPendingProcessChanges.clear();
3006            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3007        }
3008
3009        int i = mProcessObservers.beginBroadcast();
3010        while (i > 0) {
3011            i--;
3012            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3013            if (observer != null) {
3014                try {
3015                    for (int j=0; j<N; j++) {
3016                        ProcessChangeItem item = mActiveProcessChanges[j];
3017                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3018                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3019                                    + item.pid + " uid=" + item.uid + ": "
3020                                    + item.foregroundActivities);
3021                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3022                                    item.foregroundActivities);
3023                        }
3024                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3025                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3026                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3027                            observer.onImportanceChanged(item.pid, item.uid,
3028                                    item.importance);
3029                        }
3030                    }
3031                } catch (RemoteException e) {
3032                }
3033            }
3034        }
3035        mProcessObservers.finishBroadcast();
3036    }
3037
3038    private void dispatchProcessDied(int pid, int uid) {
3039        int i = mProcessObservers.beginBroadcast();
3040        while (i > 0) {
3041            i--;
3042            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3043            if (observer != null) {
3044                try {
3045                    observer.onProcessDied(pid, uid);
3046                } catch (RemoteException e) {
3047                }
3048            }
3049        }
3050        mProcessObservers.finishBroadcast();
3051    }
3052
3053    final void doPendingActivityLaunchesLocked(boolean doResume) {
3054        final int N = mPendingActivityLaunches.size();
3055        if (N <= 0) {
3056            return;
3057        }
3058        for (int i=0; i<N; i++) {
3059            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3060            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3061                    doResume && i == (N-1), null);
3062        }
3063        mPendingActivityLaunches.clear();
3064    }
3065
3066    @Override
3067    public final int startActivity(IApplicationThread caller, String callingPackage,
3068            Intent intent, String resolvedType, IBinder resultTo,
3069            String resultWho, int requestCode, int startFlags,
3070            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3071        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3072                resultWho, requestCode,
3073                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3074    }
3075
3076    @Override
3077    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3078            Intent intent, String resolvedType, IBinder resultTo,
3079            String resultWho, int requestCode, int startFlags,
3080            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3081        enforceNotIsolatedCaller("startActivity");
3082        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3083                false, true, "startActivity", null);
3084        // TODO: Switch to user app stacks here.
3085        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3086                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3087                null, null, options, userId, null);
3088    }
3089
3090    @Override
3091    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3092            Intent intent, String resolvedType, IBinder resultTo,
3093            String resultWho, int requestCode, int startFlags, String profileFile,
3094            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3095        enforceNotIsolatedCaller("startActivityAndWait");
3096        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3097                false, true, "startActivityAndWait", null);
3098        WaitResult res = new WaitResult();
3099        // TODO: Switch to user app stacks here.
3100        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3101                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3102                res, null, options, UserHandle.getCallingUserId(), null);
3103        return res;
3104    }
3105
3106    @Override
3107    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3108            Intent intent, String resolvedType, IBinder resultTo,
3109            String resultWho, int requestCode, int startFlags, Configuration config,
3110            Bundle options, int userId) {
3111        enforceNotIsolatedCaller("startActivityWithConfig");
3112        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3113                false, true, "startActivityWithConfig", null);
3114        // TODO: Switch to user app stacks here.
3115        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3116                resolvedType, resultTo, resultWho, requestCode, startFlags,
3117                null, null, null, config, options, userId, null);
3118        return ret;
3119    }
3120
3121    @Override
3122    public int startActivityIntentSender(IApplicationThread caller,
3123            IntentSender intent, Intent fillInIntent, String resolvedType,
3124            IBinder resultTo, String resultWho, int requestCode,
3125            int flagsMask, int flagsValues, Bundle options) {
3126        enforceNotIsolatedCaller("startActivityIntentSender");
3127        // Refuse possible leaked file descriptors
3128        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3129            throw new IllegalArgumentException("File descriptors passed in Intent");
3130        }
3131
3132        IIntentSender sender = intent.getTarget();
3133        if (!(sender instanceof PendingIntentRecord)) {
3134            throw new IllegalArgumentException("Bad PendingIntent object");
3135        }
3136
3137        PendingIntentRecord pir = (PendingIntentRecord)sender;
3138
3139        synchronized (this) {
3140            // If this is coming from the currently resumed activity, it is
3141            // effectively saying that app switches are allowed at this point.
3142            final ActivityStack stack = getFocusedStack();
3143            if (stack.mResumedActivity != null &&
3144                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3145                mAppSwitchesAllowedTime = 0;
3146            }
3147        }
3148        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3149                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3150        return ret;
3151    }
3152
3153    @Override
3154    public boolean startNextMatchingActivity(IBinder callingActivity,
3155            Intent intent, Bundle options) {
3156        // Refuse possible leaked file descriptors
3157        if (intent != null && intent.hasFileDescriptors() == true) {
3158            throw new IllegalArgumentException("File descriptors passed in Intent");
3159        }
3160
3161        synchronized (this) {
3162            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3163            if (r == null) {
3164                ActivityOptions.abort(options);
3165                return false;
3166            }
3167            if (r.app == null || r.app.thread == null) {
3168                // The caller is not running...  d'oh!
3169                ActivityOptions.abort(options);
3170                return false;
3171            }
3172            intent = new Intent(intent);
3173            // The caller is not allowed to change the data.
3174            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3175            // And we are resetting to find the next component...
3176            intent.setComponent(null);
3177
3178            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3179
3180            ActivityInfo aInfo = null;
3181            try {
3182                List<ResolveInfo> resolves =
3183                    AppGlobals.getPackageManager().queryIntentActivities(
3184                            intent, r.resolvedType,
3185                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3186                            UserHandle.getCallingUserId());
3187
3188                // Look for the original activity in the list...
3189                final int N = resolves != null ? resolves.size() : 0;
3190                for (int i=0; i<N; i++) {
3191                    ResolveInfo rInfo = resolves.get(i);
3192                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3193                            && rInfo.activityInfo.name.equals(r.info.name)) {
3194                        // We found the current one...  the next matching is
3195                        // after it.
3196                        i++;
3197                        if (i<N) {
3198                            aInfo = resolves.get(i).activityInfo;
3199                        }
3200                        if (debug) {
3201                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3202                                    + "/" + r.info.name);
3203                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3204                                    + "/" + aInfo.name);
3205                        }
3206                        break;
3207                    }
3208                }
3209            } catch (RemoteException e) {
3210            }
3211
3212            if (aInfo == null) {
3213                // Nobody who is next!
3214                ActivityOptions.abort(options);
3215                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3216                return false;
3217            }
3218
3219            intent.setComponent(new ComponentName(
3220                    aInfo.applicationInfo.packageName, aInfo.name));
3221            intent.setFlags(intent.getFlags()&~(
3222                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3223                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3224                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3225                    Intent.FLAG_ACTIVITY_NEW_TASK));
3226
3227            // Okay now we need to start the new activity, replacing the
3228            // currently running activity.  This is a little tricky because
3229            // we want to start the new one as if the current one is finished,
3230            // but not finish the current one first so that there is no flicker.
3231            // And thus...
3232            final boolean wasFinishing = r.finishing;
3233            r.finishing = true;
3234
3235            // Propagate reply information over to the new activity.
3236            final ActivityRecord resultTo = r.resultTo;
3237            final String resultWho = r.resultWho;
3238            final int requestCode = r.requestCode;
3239            r.resultTo = null;
3240            if (resultTo != null) {
3241                resultTo.removeResultsLocked(r, resultWho, requestCode);
3242            }
3243
3244            final long origId = Binder.clearCallingIdentity();
3245            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3246                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3247                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3248                    options, false, null, null);
3249            Binder.restoreCallingIdentity(origId);
3250
3251            r.finishing = wasFinishing;
3252            if (res != ActivityManager.START_SUCCESS) {
3253                return false;
3254            }
3255            return true;
3256        }
3257    }
3258
3259    final int startActivityInPackage(int uid, String callingPackage,
3260            Intent intent, String resolvedType, IBinder resultTo,
3261            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3262                    IActivityContainer container) {
3263
3264        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3265                false, true, "startActivityInPackage", null);
3266
3267        // TODO: Switch to user app stacks here.
3268        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3269                resultTo, resultWho, requestCode, startFlags,
3270                null, null, null, null, options, userId, container);
3271        return ret;
3272    }
3273
3274    @Override
3275    public final int startActivities(IApplicationThread caller, String callingPackage,
3276            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3277            int userId) {
3278        enforceNotIsolatedCaller("startActivities");
3279        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3280                false, true, "startActivity", null);
3281        // TODO: Switch to user app stacks here.
3282        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3283                resolvedTypes, resultTo, options, userId);
3284        return ret;
3285    }
3286
3287    final int startActivitiesInPackage(int uid, String callingPackage,
3288            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3289            Bundle options, int userId) {
3290
3291        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3292                false, true, "startActivityInPackage", null);
3293        // TODO: Switch to user app stacks here.
3294        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3295                resultTo, options, userId);
3296        return ret;
3297    }
3298
3299    final void addRecentTaskLocked(TaskRecord task) {
3300        int N = mRecentTasks.size();
3301        // Quick case: check if the top-most recent task is the same.
3302        if (N > 0 && mRecentTasks.get(0) == task) {
3303            return;
3304        }
3305        // Remove any existing entries that are the same kind of task.
3306        for (int i=0; i<N; i++) {
3307            TaskRecord tr = mRecentTasks.get(i);
3308            if (task.userId == tr.userId
3309                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3310                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3311                tr.disposeThumbnail();
3312                mRecentTasks.remove(i);
3313                i--;
3314                N--;
3315                if (task.intent == null) {
3316                    // If the new recent task we are adding is not fully
3317                    // specified, then replace it with the existing recent task.
3318                    task = tr;
3319                }
3320            }
3321        }
3322        if (N >= MAX_RECENT_TASKS) {
3323            mRecentTasks.remove(N-1).disposeThumbnail();
3324        }
3325        mRecentTasks.add(0, task);
3326    }
3327
3328    @Override
3329    public void reportActivityFullyDrawn(IBinder token) {
3330        synchronized (this) {
3331            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3332            if (r == null) {
3333                return;
3334            }
3335            r.reportFullyDrawnLocked();
3336        }
3337    }
3338
3339    @Override
3340    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3341        synchronized (this) {
3342            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3343            if (r == null) {
3344                return;
3345            }
3346            final long origId = Binder.clearCallingIdentity();
3347            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3348            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3349                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3350            if (config != null) {
3351                r.frozenBeforeDestroy = true;
3352                if (!updateConfigurationLocked(config, r, false, false)) {
3353                    mStackSupervisor.resumeTopActivitiesLocked();
3354                }
3355            }
3356            Binder.restoreCallingIdentity(origId);
3357        }
3358    }
3359
3360    @Override
3361    public int getRequestedOrientation(IBinder token) {
3362        synchronized (this) {
3363            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3364            if (r == null) {
3365                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3366            }
3367            return mWindowManager.getAppOrientation(r.appToken);
3368        }
3369    }
3370
3371    /**
3372     * This is the internal entry point for handling Activity.finish().
3373     *
3374     * @param token The Binder token referencing the Activity we want to finish.
3375     * @param resultCode Result code, if any, from this Activity.
3376     * @param resultData Result data (Intent), if any, from this Activity.
3377     *
3378     * @return Returns true if the activity successfully finished, or false if it is still running.
3379     */
3380    @Override
3381    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3382        // Refuse possible leaked file descriptors
3383        if (resultData != null && resultData.hasFileDescriptors() == true) {
3384            throw new IllegalArgumentException("File descriptors passed in Intent");
3385        }
3386
3387        synchronized(this) {
3388            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3389            if (r == null) {
3390                return true;
3391            }
3392            if (mController != null) {
3393                // Find the first activity that is not finishing.
3394                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3395                if (next != null) {
3396                    // ask watcher if this is allowed
3397                    boolean resumeOK = true;
3398                    try {
3399                        resumeOK = mController.activityResuming(next.packageName);
3400                    } catch (RemoteException e) {
3401                        mController = null;
3402                        Watchdog.getInstance().setActivityController(null);
3403                    }
3404
3405                    if (!resumeOK) {
3406                        return false;
3407                    }
3408                }
3409            }
3410            final long origId = Binder.clearCallingIdentity();
3411            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3412                    resultData, "app-request", true);
3413            Binder.restoreCallingIdentity(origId);
3414            return res;
3415        }
3416    }
3417
3418    @Override
3419    public final void finishHeavyWeightApp() {
3420        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3421                != PackageManager.PERMISSION_GRANTED) {
3422            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3423                    + Binder.getCallingPid()
3424                    + ", uid=" + Binder.getCallingUid()
3425                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3426            Slog.w(TAG, msg);
3427            throw new SecurityException(msg);
3428        }
3429
3430        synchronized(this) {
3431            if (mHeavyWeightProcess == null) {
3432                return;
3433            }
3434
3435            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3436                    mHeavyWeightProcess.activities);
3437            for (int i=0; i<activities.size(); i++) {
3438                ActivityRecord r = activities.get(i);
3439                if (!r.finishing) {
3440                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3441                            null, "finish-heavy", true);
3442                }
3443            }
3444
3445            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3446                    mHeavyWeightProcess.userId, 0));
3447            mHeavyWeightProcess = null;
3448        }
3449    }
3450
3451    @Override
3452    public void crashApplication(int uid, int initialPid, String packageName,
3453            String message) {
3454        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3455                != PackageManager.PERMISSION_GRANTED) {
3456            String msg = "Permission Denial: crashApplication() from pid="
3457                    + Binder.getCallingPid()
3458                    + ", uid=" + Binder.getCallingUid()
3459                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3460            Slog.w(TAG, msg);
3461            throw new SecurityException(msg);
3462        }
3463
3464        synchronized(this) {
3465            ProcessRecord proc = null;
3466
3467            // Figure out which process to kill.  We don't trust that initialPid
3468            // still has any relation to current pids, so must scan through the
3469            // list.
3470            synchronized (mPidsSelfLocked) {
3471                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3472                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3473                    if (p.uid != uid) {
3474                        continue;
3475                    }
3476                    if (p.pid == initialPid) {
3477                        proc = p;
3478                        break;
3479                    }
3480                    if (p.pkgList.containsKey(packageName)) {
3481                        proc = p;
3482                    }
3483                }
3484            }
3485
3486            if (proc == null) {
3487                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3488                        + " initialPid=" + initialPid
3489                        + " packageName=" + packageName);
3490                return;
3491            }
3492
3493            if (proc.thread != null) {
3494                if (proc.pid == Process.myPid()) {
3495                    Log.w(TAG, "crashApplication: trying to crash self!");
3496                    return;
3497                }
3498                long ident = Binder.clearCallingIdentity();
3499                try {
3500                    proc.thread.scheduleCrash(message);
3501                } catch (RemoteException e) {
3502                }
3503                Binder.restoreCallingIdentity(ident);
3504            }
3505        }
3506    }
3507
3508    @Override
3509    public final void finishSubActivity(IBinder token, String resultWho,
3510            int requestCode) {
3511        synchronized(this) {
3512            final long origId = Binder.clearCallingIdentity();
3513            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3514            if (r != null) {
3515                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3516            }
3517            Binder.restoreCallingIdentity(origId);
3518        }
3519    }
3520
3521    @Override
3522    public boolean finishActivityAffinity(IBinder token) {
3523        synchronized(this) {
3524            final long origId = Binder.clearCallingIdentity();
3525            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3526            boolean res = false;
3527            if (r != null) {
3528                res = r.task.stack.finishActivityAffinityLocked(r);
3529            }
3530            Binder.restoreCallingIdentity(origId);
3531            return res;
3532        }
3533    }
3534
3535    @Override
3536    public boolean willActivityBeVisible(IBinder token) {
3537        synchronized(this) {
3538            ActivityStack stack = ActivityRecord.getStackLocked(token);
3539            if (stack != null) {
3540                return stack.willActivityBeVisibleLocked(token);
3541            }
3542            return false;
3543        }
3544    }
3545
3546    @Override
3547    public void overridePendingTransition(IBinder token, String packageName,
3548            int enterAnim, int exitAnim) {
3549        synchronized(this) {
3550            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3551            if (self == null) {
3552                return;
3553            }
3554
3555            final long origId = Binder.clearCallingIdentity();
3556
3557            if (self.state == ActivityState.RESUMED
3558                    || self.state == ActivityState.PAUSING) {
3559                mWindowManager.overridePendingAppTransition(packageName,
3560                        enterAnim, exitAnim, null);
3561            }
3562
3563            Binder.restoreCallingIdentity(origId);
3564        }
3565    }
3566
3567    /**
3568     * Main function for removing an existing process from the activity manager
3569     * as a result of that process going away.  Clears out all connections
3570     * to the process.
3571     */
3572    private final void handleAppDiedLocked(ProcessRecord app,
3573            boolean restarting, boolean allowRestart) {
3574        int pid = app.pid;
3575        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3576        if (!restarting) {
3577            removeLruProcessLocked(app);
3578            if (pid > 0) {
3579                ProcessList.remove(pid);
3580            }
3581        }
3582
3583        if (mProfileProc == app) {
3584            clearProfilerLocked();
3585        }
3586
3587        // Remove this application's activities from active lists.
3588        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3589
3590        app.activities.clear();
3591
3592        if (app.instrumentationClass != null) {
3593            Slog.w(TAG, "Crash of app " + app.processName
3594                  + " running instrumentation " + app.instrumentationClass);
3595            Bundle info = new Bundle();
3596            info.putString("shortMsg", "Process crashed.");
3597            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3598        }
3599
3600        if (!restarting) {
3601            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3602                // If there was nothing to resume, and we are not already
3603                // restarting this process, but there is a visible activity that
3604                // is hosted by the process...  then make sure all visible
3605                // activities are running, taking care of restarting this
3606                // process.
3607                if (hasVisibleActivities) {
3608                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3609                }
3610            }
3611        }
3612    }
3613
3614    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3615        IBinder threadBinder = thread.asBinder();
3616        // Find the application record.
3617        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3618            ProcessRecord rec = mLruProcesses.get(i);
3619            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3620                return i;
3621            }
3622        }
3623        return -1;
3624    }
3625
3626    final ProcessRecord getRecordForAppLocked(
3627            IApplicationThread thread) {
3628        if (thread == null) {
3629            return null;
3630        }
3631
3632        int appIndex = getLRURecordIndexForAppLocked(thread);
3633        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3634    }
3635
3636    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3637        // If there are no longer any background processes running,
3638        // and the app that died was not running instrumentation,
3639        // then tell everyone we are now low on memory.
3640        boolean haveBg = false;
3641        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3642            ProcessRecord rec = mLruProcesses.get(i);
3643            if (rec.thread != null
3644                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3645                haveBg = true;
3646                break;
3647            }
3648        }
3649
3650        if (!haveBg) {
3651            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3652            if (doReport) {
3653                long now = SystemClock.uptimeMillis();
3654                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3655                    doReport = false;
3656                } else {
3657                    mLastMemUsageReportTime = now;
3658                }
3659            }
3660            final ArrayList<ProcessMemInfo> memInfos
3661                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3662            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3663            long now = SystemClock.uptimeMillis();
3664            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3665                ProcessRecord rec = mLruProcesses.get(i);
3666                if (rec == dyingProc || rec.thread == null) {
3667                    continue;
3668                }
3669                if (doReport) {
3670                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3671                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3672                }
3673                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3674                    // The low memory report is overriding any current
3675                    // state for a GC request.  Make sure to do
3676                    // heavy/important/visible/foreground processes first.
3677                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3678                        rec.lastRequestedGc = 0;
3679                    } else {
3680                        rec.lastRequestedGc = rec.lastLowMemory;
3681                    }
3682                    rec.reportLowMemory = true;
3683                    rec.lastLowMemory = now;
3684                    mProcessesToGc.remove(rec);
3685                    addProcessToGcListLocked(rec);
3686                }
3687            }
3688            if (doReport) {
3689                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3690                mHandler.sendMessage(msg);
3691            }
3692            scheduleAppGcsLocked();
3693        }
3694    }
3695
3696    final void appDiedLocked(ProcessRecord app, int pid,
3697            IApplicationThread thread) {
3698
3699        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3700        synchronized (stats) {
3701            stats.noteProcessDiedLocked(app.info.uid, pid);
3702        }
3703
3704        // Clean up already done if the process has been re-started.
3705        if (app.pid == pid && app.thread != null &&
3706                app.thread.asBinder() == thread.asBinder()) {
3707            boolean doLowMem = app.instrumentationClass == null;
3708            boolean doOomAdj = doLowMem;
3709            if (!app.killedByAm) {
3710                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3711                        + ") has died.");
3712                mAllowLowerMemLevel = true;
3713            } else {
3714                // Note that we always want to do oom adj to update our state with the
3715                // new number of procs.
3716                mAllowLowerMemLevel = false;
3717                doLowMem = false;
3718            }
3719            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3720            if (DEBUG_CLEANUP) Slog.v(
3721                TAG, "Dying app: " + app + ", pid: " + pid
3722                + ", thread: " + thread.asBinder());
3723            handleAppDiedLocked(app, false, true);
3724
3725            if (doOomAdj) {
3726                updateOomAdjLocked();
3727            }
3728            if (doLowMem) {
3729                doLowMemReportIfNeededLocked(app);
3730            }
3731        } else if (app.pid != pid) {
3732            // A new process has already been started.
3733            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3734                    + ") has died and restarted (pid " + app.pid + ").");
3735            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3736        } else if (DEBUG_PROCESSES) {
3737            Slog.d(TAG, "Received spurious death notification for thread "
3738                    + thread.asBinder());
3739        }
3740    }
3741
3742    /**
3743     * If a stack trace dump file is configured, dump process stack traces.
3744     * @param clearTraces causes the dump file to be erased prior to the new
3745     *    traces being written, if true; when false, the new traces will be
3746     *    appended to any existing file content.
3747     * @param firstPids of dalvik VM processes to dump stack traces for first
3748     * @param lastPids of dalvik VM processes to dump stack traces for last
3749     * @param nativeProcs optional list of native process names to dump stack crawls
3750     * @return file containing stack traces, or null if no dump file is configured
3751     */
3752    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3753            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3754        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3755        if (tracesPath == null || tracesPath.length() == 0) {
3756            return null;
3757        }
3758
3759        File tracesFile = new File(tracesPath);
3760        try {
3761            File tracesDir = tracesFile.getParentFile();
3762            if (!tracesDir.exists()) {
3763                tracesFile.mkdirs();
3764                if (!SELinux.restorecon(tracesDir)) {
3765                    return null;
3766                }
3767            }
3768            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3769
3770            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3771            tracesFile.createNewFile();
3772            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3773        } catch (IOException e) {
3774            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3775            return null;
3776        }
3777
3778        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3779        return tracesFile;
3780    }
3781
3782    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3783            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3784        // Use a FileObserver to detect when traces finish writing.
3785        // The order of traces is considered important to maintain for legibility.
3786        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3787            @Override
3788            public synchronized void onEvent(int event, String path) { notify(); }
3789        };
3790
3791        try {
3792            observer.startWatching();
3793
3794            // First collect all of the stacks of the most important pids.
3795            if (firstPids != null) {
3796                try {
3797                    int num = firstPids.size();
3798                    for (int i = 0; i < num; i++) {
3799                        synchronized (observer) {
3800                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3801                            observer.wait(200);  // Wait for write-close, give up after 200msec
3802                        }
3803                    }
3804                } catch (InterruptedException e) {
3805                    Log.wtf(TAG, e);
3806                }
3807            }
3808
3809            // Next collect the stacks of the native pids
3810            if (nativeProcs != null) {
3811                int[] pids = Process.getPidsForCommands(nativeProcs);
3812                if (pids != null) {
3813                    for (int pid : pids) {
3814                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3815                    }
3816                }
3817            }
3818
3819            // Lastly, measure CPU usage.
3820            if (processCpuTracker != null) {
3821                processCpuTracker.init();
3822                System.gc();
3823                processCpuTracker.update();
3824                try {
3825                    synchronized (processCpuTracker) {
3826                        processCpuTracker.wait(500); // measure over 1/2 second.
3827                    }
3828                } catch (InterruptedException e) {
3829                }
3830                processCpuTracker.update();
3831
3832                // We'll take the stack crawls of just the top apps using CPU.
3833                final int N = processCpuTracker.countWorkingStats();
3834                int numProcs = 0;
3835                for (int i=0; i<N && numProcs<5; i++) {
3836                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3837                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3838                        numProcs++;
3839                        try {
3840                            synchronized (observer) {
3841                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3842                                observer.wait(200);  // Wait for write-close, give up after 200msec
3843                            }
3844                        } catch (InterruptedException e) {
3845                            Log.wtf(TAG, e);
3846                        }
3847
3848                    }
3849                }
3850            }
3851        } finally {
3852            observer.stopWatching();
3853        }
3854    }
3855
3856    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3857        if (true || IS_USER_BUILD) {
3858            return;
3859        }
3860        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3861        if (tracesPath == null || tracesPath.length() == 0) {
3862            return;
3863        }
3864
3865        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3866        StrictMode.allowThreadDiskWrites();
3867        try {
3868            final File tracesFile = new File(tracesPath);
3869            final File tracesDir = tracesFile.getParentFile();
3870            final File tracesTmp = new File(tracesDir, "__tmp__");
3871            try {
3872                if (!tracesDir.exists()) {
3873                    tracesFile.mkdirs();
3874                    if (!SELinux.restorecon(tracesDir.getPath())) {
3875                        return;
3876                    }
3877                }
3878                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3879
3880                if (tracesFile.exists()) {
3881                    tracesTmp.delete();
3882                    tracesFile.renameTo(tracesTmp);
3883                }
3884                StringBuilder sb = new StringBuilder();
3885                Time tobj = new Time();
3886                tobj.set(System.currentTimeMillis());
3887                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3888                sb.append(": ");
3889                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3890                sb.append(" since ");
3891                sb.append(msg);
3892                FileOutputStream fos = new FileOutputStream(tracesFile);
3893                fos.write(sb.toString().getBytes());
3894                if (app == null) {
3895                    fos.write("\n*** No application process!".getBytes());
3896                }
3897                fos.close();
3898                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3899            } catch (IOException e) {
3900                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3901                return;
3902            }
3903
3904            if (app != null) {
3905                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3906                firstPids.add(app.pid);
3907                dumpStackTraces(tracesPath, firstPids, null, null, null);
3908            }
3909
3910            File lastTracesFile = null;
3911            File curTracesFile = null;
3912            for (int i=9; i>=0; i--) {
3913                String name = String.format(Locale.US, "slow%02d.txt", i);
3914                curTracesFile = new File(tracesDir, name);
3915                if (curTracesFile.exists()) {
3916                    if (lastTracesFile != null) {
3917                        curTracesFile.renameTo(lastTracesFile);
3918                    } else {
3919                        curTracesFile.delete();
3920                    }
3921                }
3922                lastTracesFile = curTracesFile;
3923            }
3924            tracesFile.renameTo(curTracesFile);
3925            if (tracesTmp.exists()) {
3926                tracesTmp.renameTo(tracesFile);
3927            }
3928        } finally {
3929            StrictMode.setThreadPolicy(oldPolicy);
3930        }
3931    }
3932
3933    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3934            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3935        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3936        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3937
3938        if (mController != null) {
3939            try {
3940                // 0 == continue, -1 = kill process immediately
3941                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3942                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3943            } catch (RemoteException e) {
3944                mController = null;
3945                Watchdog.getInstance().setActivityController(null);
3946            }
3947        }
3948
3949        long anrTime = SystemClock.uptimeMillis();
3950        if (MONITOR_CPU_USAGE) {
3951            updateCpuStatsNow();
3952        }
3953
3954        synchronized (this) {
3955            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3956            if (mShuttingDown) {
3957                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3958                return;
3959            } else if (app.notResponding) {
3960                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3961                return;
3962            } else if (app.crashing) {
3963                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3964                return;
3965            }
3966
3967            // In case we come through here for the same app before completing
3968            // this one, mark as anring now so we will bail out.
3969            app.notResponding = true;
3970
3971            // Log the ANR to the event log.
3972            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3973                    app.processName, app.info.flags, annotation);
3974
3975            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3976            firstPids.add(app.pid);
3977
3978            int parentPid = app.pid;
3979            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3980            if (parentPid != app.pid) firstPids.add(parentPid);
3981
3982            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3983
3984            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3985                ProcessRecord r = mLruProcesses.get(i);
3986                if (r != null && r.thread != null) {
3987                    int pid = r.pid;
3988                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3989                        if (r.persistent) {
3990                            firstPids.add(pid);
3991                        } else {
3992                            lastPids.put(pid, Boolean.TRUE);
3993                        }
3994                    }
3995                }
3996            }
3997        }
3998
3999        // Log the ANR to the main log.
4000        StringBuilder info = new StringBuilder();
4001        info.setLength(0);
4002        info.append("ANR in ").append(app.processName);
4003        if (activity != null && activity.shortComponentName != null) {
4004            info.append(" (").append(activity.shortComponentName).append(")");
4005        }
4006        info.append("\n");
4007        info.append("PID: ").append(app.pid).append("\n");
4008        if (annotation != null) {
4009            info.append("Reason: ").append(annotation).append("\n");
4010        }
4011        if (parent != null && parent != activity) {
4012            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4013        }
4014
4015        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4016
4017        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4018                NATIVE_STACKS_OF_INTEREST);
4019
4020        String cpuInfo = null;
4021        if (MONITOR_CPU_USAGE) {
4022            updateCpuStatsNow();
4023            synchronized (mProcessCpuThread) {
4024                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4025            }
4026            info.append(processCpuTracker.printCurrentLoad());
4027            info.append(cpuInfo);
4028        }
4029
4030        info.append(processCpuTracker.printCurrentState(anrTime));
4031
4032        Slog.e(TAG, info.toString());
4033        if (tracesFile == null) {
4034            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4035            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4036        }
4037
4038        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4039                cpuInfo, tracesFile, null);
4040
4041        if (mController != null) {
4042            try {
4043                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4044                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4045                if (res != 0) {
4046                    if (res < 0 && app.pid != MY_PID) {
4047                        Process.killProcess(app.pid);
4048                    } else {
4049                        synchronized (this) {
4050                            mServices.scheduleServiceTimeoutLocked(app);
4051                        }
4052                    }
4053                    return;
4054                }
4055            } catch (RemoteException e) {
4056                mController = null;
4057                Watchdog.getInstance().setActivityController(null);
4058            }
4059        }
4060
4061        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4062        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4063                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4064
4065        synchronized (this) {
4066            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4067                killUnneededProcessLocked(app, "background ANR");
4068                return;
4069            }
4070
4071            // Set the app's notResponding state, and look up the errorReportReceiver
4072            makeAppNotRespondingLocked(app,
4073                    activity != null ? activity.shortComponentName : null,
4074                    annotation != null ? "ANR " + annotation : "ANR",
4075                    info.toString());
4076
4077            // Bring up the infamous App Not Responding dialog
4078            Message msg = Message.obtain();
4079            HashMap<String, Object> map = new HashMap<String, Object>();
4080            msg.what = SHOW_NOT_RESPONDING_MSG;
4081            msg.obj = map;
4082            msg.arg1 = aboveSystem ? 1 : 0;
4083            map.put("app", app);
4084            if (activity != null) {
4085                map.put("activity", activity);
4086            }
4087
4088            mHandler.sendMessage(msg);
4089        }
4090    }
4091
4092    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4093        if (!mLaunchWarningShown) {
4094            mLaunchWarningShown = true;
4095            mHandler.post(new Runnable() {
4096                @Override
4097                public void run() {
4098                    synchronized (ActivityManagerService.this) {
4099                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4100                        d.show();
4101                        mHandler.postDelayed(new Runnable() {
4102                            @Override
4103                            public void run() {
4104                                synchronized (ActivityManagerService.this) {
4105                                    d.dismiss();
4106                                    mLaunchWarningShown = false;
4107                                }
4108                            }
4109                        }, 4000);
4110                    }
4111                }
4112            });
4113        }
4114    }
4115
4116    @Override
4117    public boolean clearApplicationUserData(final String packageName,
4118            final IPackageDataObserver observer, int userId) {
4119        enforceNotIsolatedCaller("clearApplicationUserData");
4120        int uid = Binder.getCallingUid();
4121        int pid = Binder.getCallingPid();
4122        userId = handleIncomingUser(pid, uid,
4123                userId, false, true, "clearApplicationUserData", null);
4124        long callingId = Binder.clearCallingIdentity();
4125        try {
4126            IPackageManager pm = AppGlobals.getPackageManager();
4127            int pkgUid = -1;
4128            synchronized(this) {
4129                try {
4130                    pkgUid = pm.getPackageUid(packageName, userId);
4131                } catch (RemoteException e) {
4132                }
4133                if (pkgUid == -1) {
4134                    Slog.w(TAG, "Invalid packageName: " + packageName);
4135                    if (observer != null) {
4136                        try {
4137                            observer.onRemoveCompleted(packageName, false);
4138                        } catch (RemoteException e) {
4139                            Slog.i(TAG, "Observer no longer exists.");
4140                        }
4141                    }
4142                    return false;
4143                }
4144                if (uid == pkgUid || checkComponentPermission(
4145                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4146                        pid, uid, -1, true)
4147                        == PackageManager.PERMISSION_GRANTED) {
4148                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4149                } else {
4150                    throw new SecurityException("PID " + pid + " does not have permission "
4151                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4152                                    + " of package " + packageName);
4153                }
4154            }
4155
4156            try {
4157                // Clear application user data
4158                pm.clearApplicationUserData(packageName, observer, userId);
4159
4160                // Remove all permissions granted from/to this package
4161                removeUriPermissionsForPackageLocked(packageName, userId, true);
4162
4163                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4164                        Uri.fromParts("package", packageName, null));
4165                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4166                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4167                        null, null, 0, null, null, null, false, false, userId);
4168            } catch (RemoteException e) {
4169            }
4170        } finally {
4171            Binder.restoreCallingIdentity(callingId);
4172        }
4173        return true;
4174    }
4175
4176    @Override
4177    public void killBackgroundProcesses(final String packageName, int userId) {
4178        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4179                != PackageManager.PERMISSION_GRANTED &&
4180                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4181                        != PackageManager.PERMISSION_GRANTED) {
4182            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4183                    + Binder.getCallingPid()
4184                    + ", uid=" + Binder.getCallingUid()
4185                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4186            Slog.w(TAG, msg);
4187            throw new SecurityException(msg);
4188        }
4189
4190        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4191                userId, true, true, "killBackgroundProcesses", null);
4192        long callingId = Binder.clearCallingIdentity();
4193        try {
4194            IPackageManager pm = AppGlobals.getPackageManager();
4195            synchronized(this) {
4196                int appId = -1;
4197                try {
4198                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4199                } catch (RemoteException e) {
4200                }
4201                if (appId == -1) {
4202                    Slog.w(TAG, "Invalid packageName: " + packageName);
4203                    return;
4204                }
4205                killPackageProcessesLocked(packageName, appId, userId,
4206                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4207            }
4208        } finally {
4209            Binder.restoreCallingIdentity(callingId);
4210        }
4211    }
4212
4213    @Override
4214    public void killAllBackgroundProcesses() {
4215        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4216                != PackageManager.PERMISSION_GRANTED) {
4217            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4218                    + Binder.getCallingPid()
4219                    + ", uid=" + Binder.getCallingUid()
4220                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4221            Slog.w(TAG, msg);
4222            throw new SecurityException(msg);
4223        }
4224
4225        long callingId = Binder.clearCallingIdentity();
4226        try {
4227            synchronized(this) {
4228                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4229                final int NP = mProcessNames.getMap().size();
4230                for (int ip=0; ip<NP; ip++) {
4231                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4232                    final int NA = apps.size();
4233                    for (int ia=0; ia<NA; ia++) {
4234                        ProcessRecord app = apps.valueAt(ia);
4235                        if (app.persistent) {
4236                            // we don't kill persistent processes
4237                            continue;
4238                        }
4239                        if (app.removed) {
4240                            procs.add(app);
4241                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4242                            app.removed = true;
4243                            procs.add(app);
4244                        }
4245                    }
4246                }
4247
4248                int N = procs.size();
4249                for (int i=0; i<N; i++) {
4250                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4251                }
4252                mAllowLowerMemLevel = true;
4253                updateOomAdjLocked();
4254                doLowMemReportIfNeededLocked(null);
4255            }
4256        } finally {
4257            Binder.restoreCallingIdentity(callingId);
4258        }
4259    }
4260
4261    @Override
4262    public void forceStopPackage(final String packageName, int userId) {
4263        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4264                != PackageManager.PERMISSION_GRANTED) {
4265            String msg = "Permission Denial: forceStopPackage() from pid="
4266                    + Binder.getCallingPid()
4267                    + ", uid=" + Binder.getCallingUid()
4268                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4269            Slog.w(TAG, msg);
4270            throw new SecurityException(msg);
4271        }
4272        final int callingPid = Binder.getCallingPid();
4273        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4274                userId, true, true, "forceStopPackage", null);
4275        long callingId = Binder.clearCallingIdentity();
4276        try {
4277            IPackageManager pm = AppGlobals.getPackageManager();
4278            synchronized(this) {
4279                int[] users = userId == UserHandle.USER_ALL
4280                        ? getUsersLocked() : new int[] { userId };
4281                for (int user : users) {
4282                    int pkgUid = -1;
4283                    try {
4284                        pkgUid = pm.getPackageUid(packageName, user);
4285                    } catch (RemoteException e) {
4286                    }
4287                    if (pkgUid == -1) {
4288                        Slog.w(TAG, "Invalid packageName: " + packageName);
4289                        continue;
4290                    }
4291                    try {
4292                        pm.setPackageStoppedState(packageName, true, user);
4293                    } catch (RemoteException e) {
4294                    } catch (IllegalArgumentException e) {
4295                        Slog.w(TAG, "Failed trying to unstop package "
4296                                + packageName + ": " + e);
4297                    }
4298                    if (isUserRunningLocked(user, false)) {
4299                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4300                    }
4301                }
4302            }
4303        } finally {
4304            Binder.restoreCallingIdentity(callingId);
4305        }
4306    }
4307
4308    /*
4309     * The pkg name and app id have to be specified.
4310     */
4311    @Override
4312    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4313        if (pkg == null) {
4314            return;
4315        }
4316        // Make sure the uid is valid.
4317        if (appid < 0) {
4318            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4319            return;
4320        }
4321        int callerUid = Binder.getCallingUid();
4322        // Only the system server can kill an application
4323        if (callerUid == Process.SYSTEM_UID) {
4324            // Post an aysnc message to kill the application
4325            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4326            msg.arg1 = appid;
4327            msg.arg2 = 0;
4328            Bundle bundle = new Bundle();
4329            bundle.putString("pkg", pkg);
4330            bundle.putString("reason", reason);
4331            msg.obj = bundle;
4332            mHandler.sendMessage(msg);
4333        } else {
4334            throw new SecurityException(callerUid + " cannot kill pkg: " +
4335                    pkg);
4336        }
4337    }
4338
4339    @Override
4340    public void closeSystemDialogs(String reason) {
4341        enforceNotIsolatedCaller("closeSystemDialogs");
4342
4343        final int pid = Binder.getCallingPid();
4344        final int uid = Binder.getCallingUid();
4345        final long origId = Binder.clearCallingIdentity();
4346        try {
4347            synchronized (this) {
4348                // Only allow this from foreground processes, so that background
4349                // applications can't abuse it to prevent system UI from being shown.
4350                if (uid >= Process.FIRST_APPLICATION_UID) {
4351                    ProcessRecord proc;
4352                    synchronized (mPidsSelfLocked) {
4353                        proc = mPidsSelfLocked.get(pid);
4354                    }
4355                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4356                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4357                                + " from background process " + proc);
4358                        return;
4359                    }
4360                }
4361                closeSystemDialogsLocked(reason);
4362            }
4363        } finally {
4364            Binder.restoreCallingIdentity(origId);
4365        }
4366    }
4367
4368    void closeSystemDialogsLocked(String reason) {
4369        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4370        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4371                | Intent.FLAG_RECEIVER_FOREGROUND);
4372        if (reason != null) {
4373            intent.putExtra("reason", reason);
4374        }
4375        mWindowManager.closeSystemDialogs(reason);
4376
4377        mStackSupervisor.closeSystemDialogsLocked();
4378
4379        broadcastIntentLocked(null, null, intent, null,
4380                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4381                Process.SYSTEM_UID, UserHandle.USER_ALL);
4382    }
4383
4384    @Override
4385    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4386        enforceNotIsolatedCaller("getProcessMemoryInfo");
4387        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4388        for (int i=pids.length-1; i>=0; i--) {
4389            ProcessRecord proc;
4390            int oomAdj;
4391            synchronized (this) {
4392                synchronized (mPidsSelfLocked) {
4393                    proc = mPidsSelfLocked.get(pids[i]);
4394                    oomAdj = proc != null ? proc.setAdj : 0;
4395                }
4396            }
4397            infos[i] = new Debug.MemoryInfo();
4398            Debug.getMemoryInfo(pids[i], infos[i]);
4399            if (proc != null) {
4400                synchronized (this) {
4401                    if (proc.thread != null && proc.setAdj == oomAdj) {
4402                        // Record this for posterity if the process has been stable.
4403                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4404                                infos[i].getTotalUss(), false, proc.pkgList);
4405                    }
4406                }
4407            }
4408        }
4409        return infos;
4410    }
4411
4412    @Override
4413    public long[] getProcessPss(int[] pids) {
4414        enforceNotIsolatedCaller("getProcessPss");
4415        long[] pss = new long[pids.length];
4416        for (int i=pids.length-1; i>=0; i--) {
4417            ProcessRecord proc;
4418            int oomAdj;
4419            synchronized (this) {
4420                synchronized (mPidsSelfLocked) {
4421                    proc = mPidsSelfLocked.get(pids[i]);
4422                    oomAdj = proc != null ? proc.setAdj : 0;
4423                }
4424            }
4425            long[] tmpUss = new long[1];
4426            pss[i] = Debug.getPss(pids[i], tmpUss);
4427            if (proc != null) {
4428                synchronized (this) {
4429                    if (proc.thread != null && proc.setAdj == oomAdj) {
4430                        // Record this for posterity if the process has been stable.
4431                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4432                    }
4433                }
4434            }
4435        }
4436        return pss;
4437    }
4438
4439    @Override
4440    public void killApplicationProcess(String processName, int uid) {
4441        if (processName == null) {
4442            return;
4443        }
4444
4445        int callerUid = Binder.getCallingUid();
4446        // Only the system server can kill an application
4447        if (callerUid == Process.SYSTEM_UID) {
4448            synchronized (this) {
4449                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4450                if (app != null && app.thread != null) {
4451                    try {
4452                        app.thread.scheduleSuicide();
4453                    } catch (RemoteException e) {
4454                        // If the other end already died, then our work here is done.
4455                    }
4456                } else {
4457                    Slog.w(TAG, "Process/uid not found attempting kill of "
4458                            + processName + " / " + uid);
4459                }
4460            }
4461        } else {
4462            throw new SecurityException(callerUid + " cannot kill app process: " +
4463                    processName);
4464        }
4465    }
4466
4467    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4468        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4469                false, true, false, UserHandle.getUserId(uid), reason);
4470        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4471                Uri.fromParts("package", packageName, null));
4472        if (!mProcessesReady) {
4473            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4474                    | Intent.FLAG_RECEIVER_FOREGROUND);
4475        }
4476        intent.putExtra(Intent.EXTRA_UID, uid);
4477        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4478        broadcastIntentLocked(null, null, intent,
4479                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4480                false, false,
4481                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4482    }
4483
4484    private void forceStopUserLocked(int userId, String reason) {
4485        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
4486        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4487        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4488                | Intent.FLAG_RECEIVER_FOREGROUND);
4489        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4490        broadcastIntentLocked(null, null, intent,
4491                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4492                false, false,
4493                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4494    }
4495
4496    private final boolean killPackageProcessesLocked(String packageName, int appId,
4497            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4498            boolean doit, boolean evenPersistent, String reason) {
4499        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4500
4501        // Remove all processes this package may have touched: all with the
4502        // same UID (except for the system or root user), and all whose name
4503        // matches the package name.
4504        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4505        final int NP = mProcessNames.getMap().size();
4506        for (int ip=0; ip<NP; ip++) {
4507            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4508            final int NA = apps.size();
4509            for (int ia=0; ia<NA; ia++) {
4510                ProcessRecord app = apps.valueAt(ia);
4511                if (app.persistent && !evenPersistent) {
4512                    // we don't kill persistent processes
4513                    continue;
4514                }
4515                if (app.removed) {
4516                    if (doit) {
4517                        procs.add(app);
4518                    }
4519                    continue;
4520                }
4521
4522                // Skip process if it doesn't meet our oom adj requirement.
4523                if (app.setAdj < minOomAdj) {
4524                    continue;
4525                }
4526
4527                // If no package is specified, we call all processes under the
4528                // give user id.
4529                if (packageName == null) {
4530                    if (app.userId != userId) {
4531                        continue;
4532                    }
4533                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4534                        continue;
4535                    }
4536                // Package has been specified, we want to hit all processes
4537                // that match it.  We need to qualify this by the processes
4538                // that are running under the specified app and user ID.
4539                } else {
4540                    if (UserHandle.getAppId(app.uid) != appId) {
4541                        continue;
4542                    }
4543                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4544                        continue;
4545                    }
4546                    if (!app.pkgList.containsKey(packageName)) {
4547                        continue;
4548                    }
4549                }
4550
4551                // Process has passed all conditions, kill it!
4552                if (!doit) {
4553                    return true;
4554                }
4555                app.removed = true;
4556                procs.add(app);
4557            }
4558        }
4559
4560        int N = procs.size();
4561        for (int i=0; i<N; i++) {
4562            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4563        }
4564        updateOomAdjLocked();
4565        return N > 0;
4566    }
4567
4568    private final boolean forceStopPackageLocked(String name, int appId,
4569            boolean callerWillRestart, boolean purgeCache, boolean doit,
4570            boolean evenPersistent, int userId, String reason) {
4571        int i;
4572        int N;
4573
4574        if (userId == UserHandle.USER_ALL && name == null) {
4575            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4576        }
4577
4578        if (appId < 0 && name != null) {
4579            try {
4580                appId = UserHandle.getAppId(
4581                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4582            } catch (RemoteException e) {
4583            }
4584        }
4585
4586        if (doit) {
4587            if (name != null) {
4588                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4589                        + " user=" + userId + ": " + reason);
4590            } else {
4591                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4592            }
4593
4594            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4595            for (int ip=pmap.size()-1; ip>=0; ip--) {
4596                SparseArray<Long> ba = pmap.valueAt(ip);
4597                for (i=ba.size()-1; i>=0; i--) {
4598                    boolean remove = false;
4599                    final int entUid = ba.keyAt(i);
4600                    if (name != null) {
4601                        if (userId == UserHandle.USER_ALL) {
4602                            if (UserHandle.getAppId(entUid) == appId) {
4603                                remove = true;
4604                            }
4605                        } else {
4606                            if (entUid == UserHandle.getUid(userId, appId)) {
4607                                remove = true;
4608                            }
4609                        }
4610                    } else if (UserHandle.getUserId(entUid) == userId) {
4611                        remove = true;
4612                    }
4613                    if (remove) {
4614                        ba.removeAt(i);
4615                    }
4616                }
4617                if (ba.size() == 0) {
4618                    pmap.removeAt(ip);
4619                }
4620            }
4621        }
4622
4623        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4624                -100, callerWillRestart, true, doit, evenPersistent,
4625                name == null ? ("stop user " + userId) : ("stop " + name));
4626
4627        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4628            if (!doit) {
4629                return true;
4630            }
4631            didSomething = true;
4632        }
4633
4634        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4635            if (!doit) {
4636                return true;
4637            }
4638            didSomething = true;
4639        }
4640
4641        if (name == null) {
4642            // Remove all sticky broadcasts from this user.
4643            mStickyBroadcasts.remove(userId);
4644        }
4645
4646        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4647        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4648                userId, providers)) {
4649            if (!doit) {
4650                return true;
4651            }
4652            didSomething = true;
4653        }
4654        N = providers.size();
4655        for (i=0; i<N; i++) {
4656            removeDyingProviderLocked(null, providers.get(i), true);
4657        }
4658
4659        // Remove transient permissions granted from/to this package/user
4660        removeUriPermissionsForPackageLocked(name, userId, false);
4661
4662        if (name == null) {
4663            // Remove pending intents.  For now we only do this when force
4664            // stopping users, because we have some problems when doing this
4665            // for packages -- app widgets are not currently cleaned up for
4666            // such packages, so they can be left with bad pending intents.
4667            if (mIntentSenderRecords.size() > 0) {
4668                Iterator<WeakReference<PendingIntentRecord>> it
4669                        = mIntentSenderRecords.values().iterator();
4670                while (it.hasNext()) {
4671                    WeakReference<PendingIntentRecord> wpir = it.next();
4672                    if (wpir == null) {
4673                        it.remove();
4674                        continue;
4675                    }
4676                    PendingIntentRecord pir = wpir.get();
4677                    if (pir == null) {
4678                        it.remove();
4679                        continue;
4680                    }
4681                    if (name == null) {
4682                        // Stopping user, remove all objects for the user.
4683                        if (pir.key.userId != userId) {
4684                            // Not the same user, skip it.
4685                            continue;
4686                        }
4687                    } else {
4688                        if (UserHandle.getAppId(pir.uid) != appId) {
4689                            // Different app id, skip it.
4690                            continue;
4691                        }
4692                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4693                            // Different user, skip it.
4694                            continue;
4695                        }
4696                        if (!pir.key.packageName.equals(name)) {
4697                            // Different package, skip it.
4698                            continue;
4699                        }
4700                    }
4701                    if (!doit) {
4702                        return true;
4703                    }
4704                    didSomething = true;
4705                    it.remove();
4706                    pir.canceled = true;
4707                    if (pir.key.activity != null) {
4708                        pir.key.activity.pendingResults.remove(pir.ref);
4709                    }
4710                }
4711            }
4712        }
4713
4714        if (doit) {
4715            if (purgeCache && name != null) {
4716                AttributeCache ac = AttributeCache.instance();
4717                if (ac != null) {
4718                    ac.removePackage(name);
4719                }
4720            }
4721            if (mBooted) {
4722                mStackSupervisor.resumeTopActivitiesLocked();
4723                mStackSupervisor.scheduleIdleLocked();
4724            }
4725        }
4726
4727        return didSomething;
4728    }
4729
4730    private final boolean removeProcessLocked(ProcessRecord app,
4731            boolean callerWillRestart, boolean allowRestart, String reason) {
4732        final String name = app.processName;
4733        final int uid = app.uid;
4734        if (DEBUG_PROCESSES) Slog.d(
4735            TAG, "Force removing proc " + app.toShortString() + " (" + name
4736            + "/" + uid + ")");
4737
4738        mProcessNames.remove(name, uid);
4739        mIsolatedProcesses.remove(app.uid);
4740        if (mHeavyWeightProcess == app) {
4741            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4742                    mHeavyWeightProcess.userId, 0));
4743            mHeavyWeightProcess = null;
4744        }
4745        boolean needRestart = false;
4746        if (app.pid > 0 && app.pid != MY_PID) {
4747            int pid = app.pid;
4748            synchronized (mPidsSelfLocked) {
4749                mPidsSelfLocked.remove(pid);
4750                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4751            }
4752            killUnneededProcessLocked(app, reason);
4753            handleAppDiedLocked(app, true, allowRestart);
4754            removeLruProcessLocked(app);
4755
4756            if (app.persistent && !app.isolated) {
4757                if (!callerWillRestart) {
4758                    addAppLocked(app.info, false);
4759                } else {
4760                    needRestart = true;
4761                }
4762            }
4763        } else {
4764            mRemovedProcesses.add(app);
4765        }
4766
4767        return needRestart;
4768    }
4769
4770    private final void processStartTimedOutLocked(ProcessRecord app) {
4771        final int pid = app.pid;
4772        boolean gone = false;
4773        synchronized (mPidsSelfLocked) {
4774            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4775            if (knownApp != null && knownApp.thread == null) {
4776                mPidsSelfLocked.remove(pid);
4777                gone = true;
4778            }
4779        }
4780
4781        if (gone) {
4782            Slog.w(TAG, "Process " + app + " failed to attach");
4783            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4784                    pid, app.uid, app.processName);
4785            mProcessNames.remove(app.processName, app.uid);
4786            mIsolatedProcesses.remove(app.uid);
4787            if (mHeavyWeightProcess == app) {
4788                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4789                        mHeavyWeightProcess.userId, 0));
4790                mHeavyWeightProcess = null;
4791            }
4792            // Take care of any launching providers waiting for this process.
4793            checkAppInLaunchingProvidersLocked(app, true);
4794            // Take care of any services that are waiting for the process.
4795            mServices.processStartTimedOutLocked(app);
4796            killUnneededProcessLocked(app, "start timeout");
4797            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4798                Slog.w(TAG, "Unattached app died before backup, skipping");
4799                try {
4800                    IBackupManager bm = IBackupManager.Stub.asInterface(
4801                            ServiceManager.getService(Context.BACKUP_SERVICE));
4802                    bm.agentDisconnected(app.info.packageName);
4803                } catch (RemoteException e) {
4804                    // Can't happen; the backup manager is local
4805                }
4806            }
4807            if (isPendingBroadcastProcessLocked(pid)) {
4808                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4809                skipPendingBroadcastLocked(pid);
4810            }
4811        } else {
4812            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4813        }
4814    }
4815
4816    private final boolean attachApplicationLocked(IApplicationThread thread,
4817            int pid) {
4818
4819        // Find the application record that is being attached...  either via
4820        // the pid if we are running in multiple processes, or just pull the
4821        // next app record if we are emulating process with anonymous threads.
4822        ProcessRecord app;
4823        if (pid != MY_PID && pid >= 0) {
4824            synchronized (mPidsSelfLocked) {
4825                app = mPidsSelfLocked.get(pid);
4826            }
4827        } else {
4828            app = null;
4829        }
4830
4831        if (app == null) {
4832            Slog.w(TAG, "No pending application record for pid " + pid
4833                    + " (IApplicationThread " + thread + "); dropping process");
4834            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4835            if (pid > 0 && pid != MY_PID) {
4836                Process.killProcessQuiet(pid);
4837            } else {
4838                try {
4839                    thread.scheduleExit();
4840                } catch (Exception e) {
4841                    // Ignore exceptions.
4842                }
4843            }
4844            return false;
4845        }
4846
4847        // If this application record is still attached to a previous
4848        // process, clean it up now.
4849        if (app.thread != null) {
4850            handleAppDiedLocked(app, true, true);
4851        }
4852
4853        // Tell the process all about itself.
4854
4855        if (localLOGV) Slog.v(
4856                TAG, "Binding process pid " + pid + " to record " + app);
4857
4858        final String processName = app.processName;
4859        try {
4860            AppDeathRecipient adr = new AppDeathRecipient(
4861                    app, pid, thread);
4862            thread.asBinder().linkToDeath(adr, 0);
4863            app.deathRecipient = adr;
4864        } catch (RemoteException e) {
4865            app.resetPackageList(mProcessStats);
4866            startProcessLocked(app, "link fail", processName);
4867            return false;
4868        }
4869
4870        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4871
4872        app.makeActive(thread, mProcessStats);
4873        app.curAdj = app.setAdj = -100;
4874        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4875        app.forcingToForeground = null;
4876        app.foregroundServices = false;
4877        app.hasShownUi = false;
4878        app.debugging = false;
4879        app.cached = false;
4880
4881        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4882
4883        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4884        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4885
4886        if (!normalMode) {
4887            Slog.i(TAG, "Launching preboot mode app: " + app);
4888        }
4889
4890        if (localLOGV) Slog.v(
4891            TAG, "New app record " + app
4892            + " thread=" + thread.asBinder() + " pid=" + pid);
4893        try {
4894            int testMode = IApplicationThread.DEBUG_OFF;
4895            if (mDebugApp != null && mDebugApp.equals(processName)) {
4896                testMode = mWaitForDebugger
4897                    ? IApplicationThread.DEBUG_WAIT
4898                    : IApplicationThread.DEBUG_ON;
4899                app.debugging = true;
4900                if (mDebugTransient) {
4901                    mDebugApp = mOrigDebugApp;
4902                    mWaitForDebugger = mOrigWaitForDebugger;
4903                }
4904            }
4905            String profileFile = app.instrumentationProfileFile;
4906            ParcelFileDescriptor profileFd = null;
4907            boolean profileAutoStop = false;
4908            if (mProfileApp != null && mProfileApp.equals(processName)) {
4909                mProfileProc = app;
4910                profileFile = mProfileFile;
4911                profileFd = mProfileFd;
4912                profileAutoStop = mAutoStopProfiler;
4913            }
4914            boolean enableOpenGlTrace = false;
4915            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4916                enableOpenGlTrace = true;
4917                mOpenGlTraceApp = null;
4918            }
4919
4920            // If the app is being launched for restore or full backup, set it up specially
4921            boolean isRestrictedBackupMode = false;
4922            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4923                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4924                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4925                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4926            }
4927
4928            ensurePackageDexOpt(app.instrumentationInfo != null
4929                    ? app.instrumentationInfo.packageName
4930                    : app.info.packageName);
4931            if (app.instrumentationClass != null) {
4932                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4933            }
4934            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4935                    + processName + " with config " + mConfiguration);
4936            ApplicationInfo appInfo = app.instrumentationInfo != null
4937                    ? app.instrumentationInfo : app.info;
4938            app.compat = compatibilityInfoForPackageLocked(appInfo);
4939            if (profileFd != null) {
4940                profileFd = profileFd.dup();
4941            }
4942            thread.bindApplication(processName, appInfo, providers,
4943                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4944                    app.instrumentationArguments, app.instrumentationWatcher,
4945                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4946                    isRestrictedBackupMode || !normalMode, app.persistent,
4947                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4948                    mCoreSettingsObserver.getCoreSettingsLocked());
4949            updateLruProcessLocked(app, false, null);
4950            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4951        } catch (Exception e) {
4952            // todo: Yikes!  What should we do?  For now we will try to
4953            // start another process, but that could easily get us in
4954            // an infinite loop of restarting processes...
4955            Slog.w(TAG, "Exception thrown during bind!", e);
4956
4957            app.resetPackageList(mProcessStats);
4958            app.unlinkDeathRecipient();
4959            startProcessLocked(app, "bind fail", processName);
4960            return false;
4961        }
4962
4963        // Remove this record from the list of starting applications.
4964        mPersistentStartingProcesses.remove(app);
4965        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4966                "Attach application locked removing on hold: " + app);
4967        mProcessesOnHold.remove(app);
4968
4969        boolean badApp = false;
4970        boolean didSomething = false;
4971
4972        // See if the top visible activity is waiting to run in this process...
4973        if (normalMode) {
4974            try {
4975                if (mStackSupervisor.attachApplicationLocked(app)) {
4976                    didSomething = true;
4977                }
4978            } catch (Exception e) {
4979                badApp = true;
4980            }
4981        }
4982
4983        // Find any services that should be running in this process...
4984        if (!badApp) {
4985            try {
4986                didSomething |= mServices.attachApplicationLocked(app, processName);
4987            } catch (Exception e) {
4988                badApp = true;
4989            }
4990        }
4991
4992        // Check if a next-broadcast receiver is in this process...
4993        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4994            try {
4995                didSomething |= sendPendingBroadcastsLocked(app);
4996            } catch (Exception e) {
4997                // If the app died trying to launch the receiver we declare it 'bad'
4998                badApp = true;
4999            }
5000        }
5001
5002        // Check whether the next backup agent is in this process...
5003        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5004            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5005            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5006            try {
5007                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5008                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5009                        mBackupTarget.backupMode);
5010            } catch (Exception e) {
5011                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5012                e.printStackTrace();
5013            }
5014        }
5015
5016        if (badApp) {
5017            // todo: Also need to kill application to deal with all
5018            // kinds of exceptions.
5019            handleAppDiedLocked(app, false, true);
5020            return false;
5021        }
5022
5023        if (!didSomething) {
5024            updateOomAdjLocked();
5025        }
5026
5027        return true;
5028    }
5029
5030    @Override
5031    public final void attachApplication(IApplicationThread thread) {
5032        synchronized (this) {
5033            int callingPid = Binder.getCallingPid();
5034            final long origId = Binder.clearCallingIdentity();
5035            attachApplicationLocked(thread, callingPid);
5036            Binder.restoreCallingIdentity(origId);
5037        }
5038    }
5039
5040    @Override
5041    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5042        final long origId = Binder.clearCallingIdentity();
5043        synchronized (this) {
5044            ActivityStack stack = ActivityRecord.getStackLocked(token);
5045            if (stack != null) {
5046                ActivityRecord r =
5047                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5048                if (stopProfiling) {
5049                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5050                        try {
5051                            mProfileFd.close();
5052                        } catch (IOException e) {
5053                        }
5054                        clearProfilerLocked();
5055                    }
5056                }
5057            }
5058        }
5059        Binder.restoreCallingIdentity(origId);
5060    }
5061
5062    void enableScreenAfterBoot() {
5063        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5064                SystemClock.uptimeMillis());
5065        mWindowManager.enableScreenAfterBoot();
5066
5067        synchronized (this) {
5068            updateEventDispatchingLocked();
5069        }
5070    }
5071
5072    @Override
5073    public void showBootMessage(final CharSequence msg, final boolean always) {
5074        enforceNotIsolatedCaller("showBootMessage");
5075        mWindowManager.showBootMessage(msg, always);
5076    }
5077
5078    @Override
5079    public void dismissKeyguardOnNextActivity() {
5080        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5081        final long token = Binder.clearCallingIdentity();
5082        try {
5083            synchronized (this) {
5084                if (DEBUG_LOCKSCREEN) logLockScreen("");
5085                if (mLockScreenShown) {
5086                    mLockScreenShown = false;
5087                    comeOutOfSleepIfNeededLocked();
5088                }
5089                mStackSupervisor.setDismissKeyguard(true);
5090            }
5091        } finally {
5092            Binder.restoreCallingIdentity(token);
5093        }
5094    }
5095
5096    final void finishBooting() {
5097        IntentFilter pkgFilter = new IntentFilter();
5098        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5099        pkgFilter.addDataScheme("package");
5100        mContext.registerReceiver(new BroadcastReceiver() {
5101            @Override
5102            public void onReceive(Context context, Intent intent) {
5103                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5104                if (pkgs != null) {
5105                    for (String pkg : pkgs) {
5106                        synchronized (ActivityManagerService.this) {
5107                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
5108                                    "finished booting")) {
5109                                setResultCode(Activity.RESULT_OK);
5110                                return;
5111                            }
5112                        }
5113                    }
5114                }
5115            }
5116        }, pkgFilter);
5117
5118        synchronized (this) {
5119            // Ensure that any processes we had put on hold are now started
5120            // up.
5121            final int NP = mProcessesOnHold.size();
5122            if (NP > 0) {
5123                ArrayList<ProcessRecord> procs =
5124                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5125                for (int ip=0; ip<NP; ip++) {
5126                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5127                            + procs.get(ip));
5128                    startProcessLocked(procs.get(ip), "on-hold", null);
5129                }
5130            }
5131
5132            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5133                // Start looking for apps that are abusing wake locks.
5134                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5135                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5136                // Tell anyone interested that we are done booting!
5137                SystemProperties.set("sys.boot_completed", "1");
5138                SystemProperties.set("dev.bootcomplete", "1");
5139                for (int i=0; i<mStartedUsers.size(); i++) {
5140                    UserStartedState uss = mStartedUsers.valueAt(i);
5141                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5142                        uss.mState = UserStartedState.STATE_RUNNING;
5143                        final int userId = mStartedUsers.keyAt(i);
5144                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5145                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5146                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5147                        broadcastIntentLocked(null, null, intent, null,
5148                                new IIntentReceiver.Stub() {
5149                                    @Override
5150                                    public void performReceive(Intent intent, int resultCode,
5151                                            String data, Bundle extras, boolean ordered,
5152                                            boolean sticky, int sendingUser) {
5153                                        synchronized (ActivityManagerService.this) {
5154                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5155                                                    true, false);
5156                                        }
5157                                    }
5158                                },
5159                                0, null, null,
5160                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5161                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5162                                userId);
5163                    }
5164                }
5165            }
5166        }
5167    }
5168
5169    final void ensureBootCompleted() {
5170        boolean booting;
5171        boolean enableScreen;
5172        synchronized (this) {
5173            booting = mBooting;
5174            mBooting = false;
5175            enableScreen = !mBooted;
5176            mBooted = true;
5177        }
5178
5179        if (booting) {
5180            finishBooting();
5181        }
5182
5183        if (enableScreen) {
5184            enableScreenAfterBoot();
5185        }
5186    }
5187
5188    @Override
5189    public final void activityResumed(IBinder token) {
5190        final long origId = Binder.clearCallingIdentity();
5191        synchronized(this) {
5192            ActivityStack stack = ActivityRecord.getStackLocked(token);
5193            if (stack != null) {
5194                ActivityRecord.activityResumedLocked(token);
5195            }
5196        }
5197        Binder.restoreCallingIdentity(origId);
5198    }
5199
5200    @Override
5201    public final void activityPaused(IBinder token) {
5202        final long origId = Binder.clearCallingIdentity();
5203        synchronized(this) {
5204            ActivityStack stack = ActivityRecord.getStackLocked(token);
5205            if (stack != null) {
5206                stack.activityPausedLocked(token, false);
5207            }
5208        }
5209        Binder.restoreCallingIdentity(origId);
5210    }
5211
5212    @Override
5213    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5214            CharSequence description) {
5215        if (localLOGV) Slog.v(
5216            TAG, "Activity stopped: token=" + token);
5217
5218        // Refuse possible leaked file descriptors
5219        if (icicle != null && icicle.hasFileDescriptors()) {
5220            throw new IllegalArgumentException("File descriptors passed in Bundle");
5221        }
5222
5223        ActivityRecord r = null;
5224
5225        final long origId = Binder.clearCallingIdentity();
5226
5227        synchronized (this) {
5228            r = ActivityRecord.isInStackLocked(token);
5229            if (r != null) {
5230                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5231            }
5232        }
5233
5234        if (r != null) {
5235            sendPendingThumbnail(r, null, null, null, false);
5236        }
5237
5238        trimApplications();
5239
5240        Binder.restoreCallingIdentity(origId);
5241    }
5242
5243    @Override
5244    public final void activityDestroyed(IBinder token) {
5245        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5246        synchronized (this) {
5247            ActivityStack stack = ActivityRecord.getStackLocked(token);
5248            if (stack != null) {
5249                stack.activityDestroyedLocked(token);
5250            }
5251        }
5252    }
5253
5254    @Override
5255    public String getCallingPackage(IBinder token) {
5256        synchronized (this) {
5257            ActivityRecord r = getCallingRecordLocked(token);
5258            return r != null ? r.info.packageName : null;
5259        }
5260    }
5261
5262    @Override
5263    public ComponentName getCallingActivity(IBinder token) {
5264        synchronized (this) {
5265            ActivityRecord r = getCallingRecordLocked(token);
5266            return r != null ? r.intent.getComponent() : null;
5267        }
5268    }
5269
5270    private ActivityRecord getCallingRecordLocked(IBinder token) {
5271        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5272        if (r == null) {
5273            return null;
5274        }
5275        return r.resultTo;
5276    }
5277
5278    @Override
5279    public ComponentName getActivityClassForToken(IBinder token) {
5280        synchronized(this) {
5281            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5282            if (r == null) {
5283                return null;
5284            }
5285            return r.intent.getComponent();
5286        }
5287    }
5288
5289    @Override
5290    public String getPackageForToken(IBinder token) {
5291        synchronized(this) {
5292            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5293            if (r == null) {
5294                return null;
5295            }
5296            return r.packageName;
5297        }
5298    }
5299
5300    @Override
5301    public IIntentSender getIntentSender(int type,
5302            String packageName, IBinder token, String resultWho,
5303            int requestCode, Intent[] intents, String[] resolvedTypes,
5304            int flags, Bundle options, int userId) {
5305        enforceNotIsolatedCaller("getIntentSender");
5306        // Refuse possible leaked file descriptors
5307        if (intents != null) {
5308            if (intents.length < 1) {
5309                throw new IllegalArgumentException("Intents array length must be >= 1");
5310            }
5311            for (int i=0; i<intents.length; i++) {
5312                Intent intent = intents[i];
5313                if (intent != null) {
5314                    if (intent.hasFileDescriptors()) {
5315                        throw new IllegalArgumentException("File descriptors passed in Intent");
5316                    }
5317                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5318                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5319                        throw new IllegalArgumentException(
5320                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5321                    }
5322                    intents[i] = new Intent(intent);
5323                }
5324            }
5325            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5326                throw new IllegalArgumentException(
5327                        "Intent array length does not match resolvedTypes length");
5328            }
5329        }
5330        if (options != null) {
5331            if (options.hasFileDescriptors()) {
5332                throw new IllegalArgumentException("File descriptors passed in options");
5333            }
5334        }
5335
5336        synchronized(this) {
5337            int callingUid = Binder.getCallingUid();
5338            int origUserId = userId;
5339            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5340                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5341                    "getIntentSender", null);
5342            if (origUserId == UserHandle.USER_CURRENT) {
5343                // We don't want to evaluate this until the pending intent is
5344                // actually executed.  However, we do want to always do the
5345                // security checking for it above.
5346                userId = UserHandle.USER_CURRENT;
5347            }
5348            try {
5349                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5350                    int uid = AppGlobals.getPackageManager()
5351                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5352                    if (!UserHandle.isSameApp(callingUid, uid)) {
5353                        String msg = "Permission Denial: getIntentSender() from pid="
5354                            + Binder.getCallingPid()
5355                            + ", uid=" + Binder.getCallingUid()
5356                            + ", (need uid=" + uid + ")"
5357                            + " is not allowed to send as package " + packageName;
5358                        Slog.w(TAG, msg);
5359                        throw new SecurityException(msg);
5360                    }
5361                }
5362
5363                return getIntentSenderLocked(type, packageName, callingUid, userId,
5364                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5365
5366            } catch (RemoteException e) {
5367                throw new SecurityException(e);
5368            }
5369        }
5370    }
5371
5372    IIntentSender getIntentSenderLocked(int type, String packageName,
5373            int callingUid, int userId, IBinder token, String resultWho,
5374            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5375            Bundle options) {
5376        if (DEBUG_MU)
5377            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5378        ActivityRecord activity = null;
5379        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5380            activity = ActivityRecord.isInStackLocked(token);
5381            if (activity == null) {
5382                return null;
5383            }
5384            if (activity.finishing) {
5385                return null;
5386            }
5387        }
5388
5389        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5390        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5391        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5392        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5393                |PendingIntent.FLAG_UPDATE_CURRENT);
5394
5395        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5396                type, packageName, activity, resultWho,
5397                requestCode, intents, resolvedTypes, flags, options, userId);
5398        WeakReference<PendingIntentRecord> ref;
5399        ref = mIntentSenderRecords.get(key);
5400        PendingIntentRecord rec = ref != null ? ref.get() : null;
5401        if (rec != null) {
5402            if (!cancelCurrent) {
5403                if (updateCurrent) {
5404                    if (rec.key.requestIntent != null) {
5405                        rec.key.requestIntent.replaceExtras(intents != null ?
5406                                intents[intents.length - 1] : null);
5407                    }
5408                    if (intents != null) {
5409                        intents[intents.length-1] = rec.key.requestIntent;
5410                        rec.key.allIntents = intents;
5411                        rec.key.allResolvedTypes = resolvedTypes;
5412                    } else {
5413                        rec.key.allIntents = null;
5414                        rec.key.allResolvedTypes = null;
5415                    }
5416                }
5417                return rec;
5418            }
5419            rec.canceled = true;
5420            mIntentSenderRecords.remove(key);
5421        }
5422        if (noCreate) {
5423            return rec;
5424        }
5425        rec = new PendingIntentRecord(this, key, callingUid);
5426        mIntentSenderRecords.put(key, rec.ref);
5427        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5428            if (activity.pendingResults == null) {
5429                activity.pendingResults
5430                        = new HashSet<WeakReference<PendingIntentRecord>>();
5431            }
5432            activity.pendingResults.add(rec.ref);
5433        }
5434        return rec;
5435    }
5436
5437    @Override
5438    public void cancelIntentSender(IIntentSender sender) {
5439        if (!(sender instanceof PendingIntentRecord)) {
5440            return;
5441        }
5442        synchronized(this) {
5443            PendingIntentRecord rec = (PendingIntentRecord)sender;
5444            try {
5445                int uid = AppGlobals.getPackageManager()
5446                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5447                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5448                    String msg = "Permission Denial: cancelIntentSender() from pid="
5449                        + Binder.getCallingPid()
5450                        + ", uid=" + Binder.getCallingUid()
5451                        + " is not allowed to cancel packges "
5452                        + rec.key.packageName;
5453                    Slog.w(TAG, msg);
5454                    throw new SecurityException(msg);
5455                }
5456            } catch (RemoteException e) {
5457                throw new SecurityException(e);
5458            }
5459            cancelIntentSenderLocked(rec, true);
5460        }
5461    }
5462
5463    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5464        rec.canceled = true;
5465        mIntentSenderRecords.remove(rec.key);
5466        if (cleanActivity && rec.key.activity != null) {
5467            rec.key.activity.pendingResults.remove(rec.ref);
5468        }
5469    }
5470
5471    @Override
5472    public String getPackageForIntentSender(IIntentSender pendingResult) {
5473        if (!(pendingResult instanceof PendingIntentRecord)) {
5474            return null;
5475        }
5476        try {
5477            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5478            return res.key.packageName;
5479        } catch (ClassCastException e) {
5480        }
5481        return null;
5482    }
5483
5484    @Override
5485    public int getUidForIntentSender(IIntentSender sender) {
5486        if (sender instanceof PendingIntentRecord) {
5487            try {
5488                PendingIntentRecord res = (PendingIntentRecord)sender;
5489                return res.uid;
5490            } catch (ClassCastException e) {
5491            }
5492        }
5493        return -1;
5494    }
5495
5496    @Override
5497    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5498        if (!(pendingResult instanceof PendingIntentRecord)) {
5499            return false;
5500        }
5501        try {
5502            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5503            if (res.key.allIntents == null) {
5504                return false;
5505            }
5506            for (int i=0; i<res.key.allIntents.length; i++) {
5507                Intent intent = res.key.allIntents[i];
5508                if (intent.getPackage() != null && intent.getComponent() != null) {
5509                    return false;
5510                }
5511            }
5512            return true;
5513        } catch (ClassCastException e) {
5514        }
5515        return false;
5516    }
5517
5518    @Override
5519    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5520        if (!(pendingResult instanceof PendingIntentRecord)) {
5521            return false;
5522        }
5523        try {
5524            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5525            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5526                return true;
5527            }
5528            return false;
5529        } catch (ClassCastException e) {
5530        }
5531        return false;
5532    }
5533
5534    @Override
5535    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5536        if (!(pendingResult instanceof PendingIntentRecord)) {
5537            return null;
5538        }
5539        try {
5540            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5541            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5542        } catch (ClassCastException e) {
5543        }
5544        return null;
5545    }
5546
5547    @Override
5548    public void setProcessLimit(int max) {
5549        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5550                "setProcessLimit()");
5551        synchronized (this) {
5552            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5553            mProcessLimitOverride = max;
5554        }
5555        trimApplications();
5556    }
5557
5558    @Override
5559    public int getProcessLimit() {
5560        synchronized (this) {
5561            return mProcessLimitOverride;
5562        }
5563    }
5564
5565    void foregroundTokenDied(ForegroundToken token) {
5566        synchronized (ActivityManagerService.this) {
5567            synchronized (mPidsSelfLocked) {
5568                ForegroundToken cur
5569                    = mForegroundProcesses.get(token.pid);
5570                if (cur != token) {
5571                    return;
5572                }
5573                mForegroundProcesses.remove(token.pid);
5574                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5575                if (pr == null) {
5576                    return;
5577                }
5578                pr.forcingToForeground = null;
5579                pr.foregroundServices = false;
5580            }
5581            updateOomAdjLocked();
5582        }
5583    }
5584
5585    @Override
5586    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5587        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5588                "setProcessForeground()");
5589        synchronized(this) {
5590            boolean changed = false;
5591
5592            synchronized (mPidsSelfLocked) {
5593                ProcessRecord pr = mPidsSelfLocked.get(pid);
5594                if (pr == null && isForeground) {
5595                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5596                    return;
5597                }
5598                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5599                if (oldToken != null) {
5600                    oldToken.token.unlinkToDeath(oldToken, 0);
5601                    mForegroundProcesses.remove(pid);
5602                    if (pr != null) {
5603                        pr.forcingToForeground = null;
5604                    }
5605                    changed = true;
5606                }
5607                if (isForeground && token != null) {
5608                    ForegroundToken newToken = new ForegroundToken() {
5609                        @Override
5610                        public void binderDied() {
5611                            foregroundTokenDied(this);
5612                        }
5613                    };
5614                    newToken.pid = pid;
5615                    newToken.token = token;
5616                    try {
5617                        token.linkToDeath(newToken, 0);
5618                        mForegroundProcesses.put(pid, newToken);
5619                        pr.forcingToForeground = token;
5620                        changed = true;
5621                    } catch (RemoteException e) {
5622                        // If the process died while doing this, we will later
5623                        // do the cleanup with the process death link.
5624                    }
5625                }
5626            }
5627
5628            if (changed) {
5629                updateOomAdjLocked();
5630            }
5631        }
5632    }
5633
5634    // =========================================================
5635    // PERMISSIONS
5636    // =========================================================
5637
5638    static class PermissionController extends IPermissionController.Stub {
5639        ActivityManagerService mActivityManagerService;
5640        PermissionController(ActivityManagerService activityManagerService) {
5641            mActivityManagerService = activityManagerService;
5642        }
5643
5644        @Override
5645        public boolean checkPermission(String permission, int pid, int uid) {
5646            return mActivityManagerService.checkPermission(permission, pid,
5647                    uid) == PackageManager.PERMISSION_GRANTED;
5648        }
5649    }
5650
5651    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5652        @Override
5653        public int checkComponentPermission(String permission, int pid, int uid,
5654                int owningUid, boolean exported) {
5655            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5656                    owningUid, exported);
5657        }
5658
5659        @Override
5660        public Object getAMSLock() {
5661            return ActivityManagerService.this;
5662        }
5663    }
5664
5665    /**
5666     * This can be called with or without the global lock held.
5667     */
5668    int checkComponentPermission(String permission, int pid, int uid,
5669            int owningUid, boolean exported) {
5670        // We might be performing an operation on behalf of an indirect binder
5671        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5672        // client identity accordingly before proceeding.
5673        Identity tlsIdentity = sCallerIdentity.get();
5674        if (tlsIdentity != null) {
5675            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5676                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5677            uid = tlsIdentity.uid;
5678            pid = tlsIdentity.pid;
5679        }
5680
5681        if (pid == MY_PID) {
5682            return PackageManager.PERMISSION_GRANTED;
5683        }
5684
5685        return ActivityManager.checkComponentPermission(permission, uid,
5686                owningUid, exported);
5687    }
5688
5689    /**
5690     * As the only public entry point for permissions checking, this method
5691     * can enforce the semantic that requesting a check on a null global
5692     * permission is automatically denied.  (Internally a null permission
5693     * string is used when calling {@link #checkComponentPermission} in cases
5694     * when only uid-based security is needed.)
5695     *
5696     * This can be called with or without the global lock held.
5697     */
5698    @Override
5699    public int checkPermission(String permission, int pid, int uid) {
5700        if (permission == null) {
5701            return PackageManager.PERMISSION_DENIED;
5702        }
5703        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5704    }
5705
5706    /**
5707     * Binder IPC calls go through the public entry point.
5708     * This can be called with or without the global lock held.
5709     */
5710    int checkCallingPermission(String permission) {
5711        return checkPermission(permission,
5712                Binder.getCallingPid(),
5713                UserHandle.getAppId(Binder.getCallingUid()));
5714    }
5715
5716    /**
5717     * This can be called with or without the global lock held.
5718     */
5719    void enforceCallingPermission(String permission, String func) {
5720        if (checkCallingPermission(permission)
5721                == PackageManager.PERMISSION_GRANTED) {
5722            return;
5723        }
5724
5725        String msg = "Permission Denial: " + func + " from pid="
5726                + Binder.getCallingPid()
5727                + ", uid=" + Binder.getCallingUid()
5728                + " requires " + permission;
5729        Slog.w(TAG, msg);
5730        throw new SecurityException(msg);
5731    }
5732
5733    /**
5734     * Determine if UID is holding permissions required to access {@link Uri} in
5735     * the given {@link ProviderInfo}. Final permission checking is always done
5736     * in {@link ContentProvider}.
5737     */
5738    private final boolean checkHoldingPermissionsLocked(
5739            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5740        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5741                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5742
5743        if (pi.applicationInfo.uid == uid) {
5744            return true;
5745        } else if (!pi.exported) {
5746            return false;
5747        }
5748
5749        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5750        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5751        try {
5752            // check if target holds top-level <provider> permissions
5753            if (!readMet && pi.readPermission != null
5754                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5755                readMet = true;
5756            }
5757            if (!writeMet && pi.writePermission != null
5758                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5759                writeMet = true;
5760            }
5761
5762            // track if unprotected read/write is allowed; any denied
5763            // <path-permission> below removes this ability
5764            boolean allowDefaultRead = pi.readPermission == null;
5765            boolean allowDefaultWrite = pi.writePermission == null;
5766
5767            // check if target holds any <path-permission> that match uri
5768            final PathPermission[] pps = pi.pathPermissions;
5769            if (pps != null) {
5770                final String path = uri.getPath();
5771                int i = pps.length;
5772                while (i > 0 && (!readMet || !writeMet)) {
5773                    i--;
5774                    PathPermission pp = pps[i];
5775                    if (pp.match(path)) {
5776                        if (!readMet) {
5777                            final String pprperm = pp.getReadPermission();
5778                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5779                                    + pprperm + " for " + pp.getPath()
5780                                    + ": match=" + pp.match(path)
5781                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5782                            if (pprperm != null) {
5783                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5784                                    readMet = true;
5785                                } else {
5786                                    allowDefaultRead = false;
5787                                }
5788                            }
5789                        }
5790                        if (!writeMet) {
5791                            final String ppwperm = pp.getWritePermission();
5792                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5793                                    + ppwperm + " for " + pp.getPath()
5794                                    + ": match=" + pp.match(path)
5795                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5796                            if (ppwperm != null) {
5797                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5798                                    writeMet = true;
5799                                } else {
5800                                    allowDefaultWrite = false;
5801                                }
5802                            }
5803                        }
5804                    }
5805                }
5806            }
5807
5808            // grant unprotected <provider> read/write, if not blocked by
5809            // <path-permission> above
5810            if (allowDefaultRead) readMet = true;
5811            if (allowDefaultWrite) writeMet = true;
5812
5813        } catch (RemoteException e) {
5814            return false;
5815        }
5816
5817        return readMet && writeMet;
5818    }
5819
5820    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5821        ProviderInfo pi = null;
5822        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5823        if (cpr != null) {
5824            pi = cpr.info;
5825        } else {
5826            try {
5827                pi = AppGlobals.getPackageManager().resolveContentProvider(
5828                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5829            } catch (RemoteException ex) {
5830            }
5831        }
5832        return pi;
5833    }
5834
5835    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5836        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5837        if (targetUris != null) {
5838            return targetUris.get(uri);
5839        } else {
5840            return null;
5841        }
5842    }
5843
5844    private UriPermission findOrCreateUriPermissionLocked(
5845            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5846        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5847        if (targetUris == null) {
5848            targetUris = Maps.newArrayMap();
5849            mGrantedUriPermissions.put(targetUid, targetUris);
5850        }
5851
5852        UriPermission perm = targetUris.get(uri);
5853        if (perm == null) {
5854            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5855            targetUris.put(uri, perm);
5856        }
5857
5858        return perm;
5859    }
5860
5861    private final boolean checkUriPermissionLocked(
5862            Uri uri, int uid, int modeFlags, int minStrength) {
5863        // Root gets to do everything.
5864        if (uid == 0) {
5865            return true;
5866        }
5867        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5868        if (perms == null) return false;
5869        UriPermission perm = perms.get(uri);
5870        if (perm == null) return false;
5871        return perm.getStrength(modeFlags) >= minStrength;
5872    }
5873
5874    @Override
5875    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5876        enforceNotIsolatedCaller("checkUriPermission");
5877
5878        // Another redirected-binder-call permissions check as in
5879        // {@link checkComponentPermission}.
5880        Identity tlsIdentity = sCallerIdentity.get();
5881        if (tlsIdentity != null) {
5882            uid = tlsIdentity.uid;
5883            pid = tlsIdentity.pid;
5884        }
5885
5886        // Our own process gets to do everything.
5887        if (pid == MY_PID) {
5888            return PackageManager.PERMISSION_GRANTED;
5889        }
5890        synchronized(this) {
5891            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5892                    ? PackageManager.PERMISSION_GRANTED
5893                    : PackageManager.PERMISSION_DENIED;
5894        }
5895    }
5896
5897    /**
5898     * Check if the targetPkg can be granted permission to access uri by
5899     * the callingUid using the given modeFlags.  Throws a security exception
5900     * if callingUid is not allowed to do this.  Returns the uid of the target
5901     * if the URI permission grant should be performed; returns -1 if it is not
5902     * needed (for example targetPkg already has permission to access the URI).
5903     * If you already know the uid of the target, you can supply it in
5904     * lastTargetUid else set that to -1.
5905     */
5906    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5907            Uri uri, int modeFlags, int lastTargetUid) {
5908        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5909        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5910                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5911        if (modeFlags == 0) {
5912            return -1;
5913        }
5914
5915        if (targetPkg != null) {
5916            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5917                    "Checking grant " + targetPkg + " permission to " + uri);
5918        }
5919
5920        final IPackageManager pm = AppGlobals.getPackageManager();
5921
5922        // If this is not a content: uri, we can't do anything with it.
5923        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5924            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5925                    "Can't grant URI permission for non-content URI: " + uri);
5926            return -1;
5927        }
5928
5929        final String authority = uri.getAuthority();
5930        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5931        if (pi == null) {
5932            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5933            return -1;
5934        }
5935
5936        int targetUid = lastTargetUid;
5937        if (targetUid < 0 && targetPkg != null) {
5938            try {
5939                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5940                if (targetUid < 0) {
5941                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5942                            "Can't grant URI permission no uid for: " + targetPkg);
5943                    return -1;
5944                }
5945            } catch (RemoteException ex) {
5946                return -1;
5947            }
5948        }
5949
5950        if (targetUid >= 0) {
5951            // First...  does the target actually need this permission?
5952            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5953                // No need to grant the target this permission.
5954                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5955                        "Target " + targetPkg + " already has full permission to " + uri);
5956                return -1;
5957            }
5958        } else {
5959            // First...  there is no target package, so can anyone access it?
5960            boolean allowed = pi.exported;
5961            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5962                if (pi.readPermission != null) {
5963                    allowed = false;
5964                }
5965            }
5966            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5967                if (pi.writePermission != null) {
5968                    allowed = false;
5969                }
5970            }
5971            if (allowed) {
5972                return -1;
5973            }
5974        }
5975
5976        // Second...  is the provider allowing granting of URI permissions?
5977        if (!pi.grantUriPermissions) {
5978            throw new SecurityException("Provider " + pi.packageName
5979                    + "/" + pi.name
5980                    + " does not allow granting of Uri permissions (uri "
5981                    + uri + ")");
5982        }
5983        if (pi.uriPermissionPatterns != null) {
5984            final int N = pi.uriPermissionPatterns.length;
5985            boolean allowed = false;
5986            for (int i=0; i<N; i++) {
5987                if (pi.uriPermissionPatterns[i] != null
5988                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5989                    allowed = true;
5990                    break;
5991                }
5992            }
5993            if (!allowed) {
5994                throw new SecurityException("Provider " + pi.packageName
5995                        + "/" + pi.name
5996                        + " does not allow granting of permission to path of Uri "
5997                        + uri);
5998            }
5999        }
6000
6001        // Third...  does the caller itself have permission to access
6002        // this uri?
6003        if (callingUid != Process.myUid()) {
6004            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6005                // Require they hold a strong enough Uri permission
6006                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6007                        : UriPermission.STRENGTH_OWNED;
6008                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6009                    throw new SecurityException("Uid " + callingUid
6010                            + " does not have permission to uri " + uri);
6011                }
6012            }
6013        }
6014
6015        return targetUid;
6016    }
6017
6018    @Override
6019    public int checkGrantUriPermission(int callingUid, String targetPkg,
6020            Uri uri, int modeFlags) {
6021        enforceNotIsolatedCaller("checkGrantUriPermission");
6022        synchronized(this) {
6023            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6024        }
6025    }
6026
6027    void grantUriPermissionUncheckedLocked(
6028            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6029        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6030        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6031                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6032        if (modeFlags == 0) {
6033            return;
6034        }
6035
6036        // So here we are: the caller has the assumed permission
6037        // to the uri, and the target doesn't.  Let's now give this to
6038        // the target.
6039
6040        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6041                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6042
6043        final String authority = uri.getAuthority();
6044        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6045        if (pi == null) {
6046            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6047            return;
6048        }
6049
6050        final UriPermission perm = findOrCreateUriPermissionLocked(
6051                pi.packageName, targetPkg, targetUid, uri);
6052        perm.grantModes(modeFlags, persistable, owner);
6053    }
6054
6055    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6056            int modeFlags, UriPermissionOwner owner) {
6057        if (targetPkg == null) {
6058            throw new NullPointerException("targetPkg");
6059        }
6060
6061        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6062        if (targetUid < 0) {
6063            return;
6064        }
6065
6066        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6067    }
6068
6069    static class NeededUriGrants extends ArrayList<Uri> {
6070        final String targetPkg;
6071        final int targetUid;
6072        final int flags;
6073
6074        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6075            this.targetPkg = targetPkg;
6076            this.targetUid = targetUid;
6077            this.flags = flags;
6078        }
6079    }
6080
6081    /**
6082     * Like checkGrantUriPermissionLocked, but takes an Intent.
6083     */
6084    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6085            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6086        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6087                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6088                + " clip=" + (intent != null ? intent.getClipData() : null)
6089                + " from " + intent + "; flags=0x"
6090                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6091
6092        if (targetPkg == null) {
6093            throw new NullPointerException("targetPkg");
6094        }
6095
6096        if (intent == null) {
6097            return null;
6098        }
6099        Uri data = intent.getData();
6100        ClipData clip = intent.getClipData();
6101        if (data == null && clip == null) {
6102            return null;
6103        }
6104
6105        if (data != null) {
6106            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6107                mode, needed != null ? needed.targetUid : -1);
6108            if (targetUid > 0) {
6109                if (needed == null) {
6110                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6111                }
6112                needed.add(data);
6113            }
6114        }
6115        if (clip != null) {
6116            for (int i=0; i<clip.getItemCount(); i++) {
6117                Uri uri = clip.getItemAt(i).getUri();
6118                if (uri != null) {
6119                    int targetUid = -1;
6120                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6121                            mode, needed != null ? needed.targetUid : -1);
6122                    if (targetUid > 0) {
6123                        if (needed == null) {
6124                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6125                        }
6126                        needed.add(uri);
6127                    }
6128                } else {
6129                    Intent clipIntent = clip.getItemAt(i).getIntent();
6130                    if (clipIntent != null) {
6131                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6132                                callingUid, targetPkg, clipIntent, mode, needed);
6133                        if (newNeeded != null) {
6134                            needed = newNeeded;
6135                        }
6136                    }
6137                }
6138            }
6139        }
6140
6141        return needed;
6142    }
6143
6144    /**
6145     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6146     */
6147    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6148            UriPermissionOwner owner) {
6149        if (needed != null) {
6150            for (int i=0; i<needed.size(); i++) {
6151                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6152                        needed.get(i), needed.flags, owner);
6153            }
6154        }
6155    }
6156
6157    void grantUriPermissionFromIntentLocked(int callingUid,
6158            String targetPkg, Intent intent, UriPermissionOwner owner) {
6159        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6160                intent, intent != null ? intent.getFlags() : 0, null);
6161        if (needed == null) {
6162            return;
6163        }
6164
6165        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6166    }
6167
6168    @Override
6169    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6170            Uri uri, int modeFlags) {
6171        enforceNotIsolatedCaller("grantUriPermission");
6172        synchronized(this) {
6173            final ProcessRecord r = getRecordForAppLocked(caller);
6174            if (r == null) {
6175                throw new SecurityException("Unable to find app for caller "
6176                        + caller
6177                        + " when granting permission to uri " + uri);
6178            }
6179            if (targetPkg == null) {
6180                throw new IllegalArgumentException("null target");
6181            }
6182            if (uri == null) {
6183                throw new IllegalArgumentException("null uri");
6184            }
6185
6186            // Persistable only supported through Intents
6187            Preconditions.checkFlagsArgument(modeFlags,
6188                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6189
6190            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6191                    null);
6192        }
6193    }
6194
6195    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6196        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6197                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6198            ArrayMap<Uri, UriPermission> perms
6199                    = mGrantedUriPermissions.get(perm.targetUid);
6200            if (perms != null) {
6201                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6202                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6203                perms.remove(perm.uri);
6204                if (perms.size() == 0) {
6205                    mGrantedUriPermissions.remove(perm.targetUid);
6206                }
6207            }
6208        }
6209    }
6210
6211    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6212        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6213
6214        final IPackageManager pm = AppGlobals.getPackageManager();
6215        final String authority = uri.getAuthority();
6216        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6217        if (pi == null) {
6218            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6219            return;
6220        }
6221
6222        // Does the caller have this permission on the URI?
6223        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6224            // Right now, if you are not the original owner of the permission,
6225            // you are not allowed to revoke it.
6226            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6227                throw new SecurityException("Uid " + callingUid
6228                        + " does not have permission to uri " + uri);
6229            //}
6230        }
6231
6232        boolean persistChanged = false;
6233
6234        // Go through all of the permissions and remove any that match.
6235        final List<String> SEGMENTS = uri.getPathSegments();
6236        if (SEGMENTS != null) {
6237            final int NS = SEGMENTS.size();
6238            int N = mGrantedUriPermissions.size();
6239            for (int i=0; i<N; i++) {
6240                ArrayMap<Uri, UriPermission> perms
6241                        = mGrantedUriPermissions.valueAt(i);
6242                Iterator<UriPermission> it = perms.values().iterator();
6243            toploop:
6244                while (it.hasNext()) {
6245                    UriPermission perm = it.next();
6246                    Uri targetUri = perm.uri;
6247                    if (!authority.equals(targetUri.getAuthority())) {
6248                        continue;
6249                    }
6250                    List<String> targetSegments = targetUri.getPathSegments();
6251                    if (targetSegments == null) {
6252                        continue;
6253                    }
6254                    if (targetSegments.size() < NS) {
6255                        continue;
6256                    }
6257                    for (int j=0; j<NS; j++) {
6258                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6259                            continue toploop;
6260                        }
6261                    }
6262                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6263                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6264                    persistChanged |= perm.clearModes(modeFlags, true);
6265                    if (perm.modeFlags == 0) {
6266                        it.remove();
6267                    }
6268                }
6269                if (perms.size() == 0) {
6270                    mGrantedUriPermissions.remove(
6271                            mGrantedUriPermissions.keyAt(i));
6272                    N--;
6273                    i--;
6274                }
6275            }
6276        }
6277
6278        if (persistChanged) {
6279            schedulePersistUriGrants();
6280        }
6281    }
6282
6283    @Override
6284    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6285            int modeFlags) {
6286        enforceNotIsolatedCaller("revokeUriPermission");
6287        synchronized(this) {
6288            final ProcessRecord r = getRecordForAppLocked(caller);
6289            if (r == null) {
6290                throw new SecurityException("Unable to find app for caller "
6291                        + caller
6292                        + " when revoking permission to uri " + uri);
6293            }
6294            if (uri == null) {
6295                Slog.w(TAG, "revokeUriPermission: null uri");
6296                return;
6297            }
6298
6299            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6300                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6301            if (modeFlags == 0) {
6302                return;
6303            }
6304
6305            final IPackageManager pm = AppGlobals.getPackageManager();
6306            final String authority = uri.getAuthority();
6307            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6308            if (pi == null) {
6309                Slog.w(TAG, "No content provider found for permission revoke: "
6310                        + uri.toSafeString());
6311                return;
6312            }
6313
6314            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6315        }
6316    }
6317
6318    /**
6319     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6320     * given package.
6321     *
6322     * @param packageName Package name to match, or {@code null} to apply to all
6323     *            packages.
6324     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6325     *            to all users.
6326     * @param persistable If persistable grants should be removed.
6327     */
6328    private void removeUriPermissionsForPackageLocked(
6329            String packageName, int userHandle, boolean persistable) {
6330        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6331            throw new IllegalArgumentException("Must narrow by either package or user");
6332        }
6333
6334        boolean persistChanged = false;
6335
6336        final int size = mGrantedUriPermissions.size();
6337        for (int i = 0; i < size; i++) {
6338            // Only inspect grants matching user
6339            if (userHandle == UserHandle.USER_ALL
6340                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6341                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6342                        .values().iterator();
6343                while (it.hasNext()) {
6344                    final UriPermission perm = it.next();
6345
6346                    // Only inspect grants matching package
6347                    if (packageName == null || perm.sourcePkg.equals(packageName)
6348                            || perm.targetPkg.equals(packageName)) {
6349                        persistChanged |= perm.clearModes(~0, persistable);
6350
6351                        // Only remove when no modes remain; any persisted grants
6352                        // will keep this alive.
6353                        if (perm.modeFlags == 0) {
6354                            it.remove();
6355                        }
6356                    }
6357                }
6358            }
6359        }
6360
6361        if (persistChanged) {
6362            schedulePersistUriGrants();
6363        }
6364    }
6365
6366    @Override
6367    public IBinder newUriPermissionOwner(String name) {
6368        enforceNotIsolatedCaller("newUriPermissionOwner");
6369        synchronized(this) {
6370            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6371            return owner.getExternalTokenLocked();
6372        }
6373    }
6374
6375    @Override
6376    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6377            Uri uri, int modeFlags) {
6378        synchronized(this) {
6379            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6380            if (owner == null) {
6381                throw new IllegalArgumentException("Unknown owner: " + token);
6382            }
6383            if (fromUid != Binder.getCallingUid()) {
6384                if (Binder.getCallingUid() != Process.myUid()) {
6385                    // Only system code can grant URI permissions on behalf
6386                    // of other users.
6387                    throw new SecurityException("nice try");
6388                }
6389            }
6390            if (targetPkg == null) {
6391                throw new IllegalArgumentException("null target");
6392            }
6393            if (uri == null) {
6394                throw new IllegalArgumentException("null uri");
6395            }
6396
6397            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6398        }
6399    }
6400
6401    @Override
6402    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6403        synchronized(this) {
6404            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6405            if (owner == null) {
6406                throw new IllegalArgumentException("Unknown owner: " + token);
6407            }
6408
6409            if (uri == null) {
6410                owner.removeUriPermissionsLocked(mode);
6411            } else {
6412                owner.removeUriPermissionLocked(uri, mode);
6413            }
6414        }
6415    }
6416
6417    private void schedulePersistUriGrants() {
6418        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6419            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6420                    10 * DateUtils.SECOND_IN_MILLIS);
6421        }
6422    }
6423
6424    private void writeGrantedUriPermissions() {
6425        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6426
6427        // Snapshot permissions so we can persist without lock
6428        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6429        synchronized (this) {
6430            final int size = mGrantedUriPermissions.size();
6431            for (int i = 0 ; i < size; i++) {
6432                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6433                    if (perm.persistedModeFlags != 0) {
6434                        persist.add(perm.snapshot());
6435                    }
6436                }
6437            }
6438        }
6439
6440        FileOutputStream fos = null;
6441        try {
6442            fos = mGrantFile.startWrite();
6443
6444            XmlSerializer out = new FastXmlSerializer();
6445            out.setOutput(fos, "utf-8");
6446            out.startDocument(null, true);
6447            out.startTag(null, TAG_URI_GRANTS);
6448            for (UriPermission.Snapshot perm : persist) {
6449                out.startTag(null, TAG_URI_GRANT);
6450                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6451                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6452                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6453                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6454                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6455                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6456                out.endTag(null, TAG_URI_GRANT);
6457            }
6458            out.endTag(null, TAG_URI_GRANTS);
6459            out.endDocument();
6460
6461            mGrantFile.finishWrite(fos);
6462        } catch (IOException e) {
6463            if (fos != null) {
6464                mGrantFile.failWrite(fos);
6465            }
6466        }
6467    }
6468
6469    private void readGrantedUriPermissionsLocked() {
6470        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6471
6472        final long now = System.currentTimeMillis();
6473
6474        FileInputStream fis = null;
6475        try {
6476            fis = mGrantFile.openRead();
6477            final XmlPullParser in = Xml.newPullParser();
6478            in.setInput(fis, null);
6479
6480            int type;
6481            while ((type = in.next()) != END_DOCUMENT) {
6482                final String tag = in.getName();
6483                if (type == START_TAG) {
6484                    if (TAG_URI_GRANT.equals(tag)) {
6485                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6486                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6487                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6488                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6489                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6490                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6491
6492                        // Sanity check that provider still belongs to source package
6493                        final ProviderInfo pi = getProviderInfoLocked(
6494                                uri.getAuthority(), userHandle);
6495                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6496                            int targetUid = -1;
6497                            try {
6498                                targetUid = AppGlobals.getPackageManager()
6499                                        .getPackageUid(targetPkg, userHandle);
6500                            } catch (RemoteException e) {
6501                            }
6502                            if (targetUid != -1) {
6503                                final UriPermission perm = findOrCreateUriPermissionLocked(
6504                                        sourcePkg, targetPkg, targetUid, uri);
6505                                perm.initPersistedModes(modeFlags, createdTime);
6506                            }
6507                        } else {
6508                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6509                                    + " but instead found " + pi);
6510                        }
6511                    }
6512                }
6513            }
6514        } catch (FileNotFoundException e) {
6515            // Missing grants is okay
6516        } catch (IOException e) {
6517            Log.wtf(TAG, "Failed reading Uri grants", e);
6518        } catch (XmlPullParserException e) {
6519            Log.wtf(TAG, "Failed reading Uri grants", e);
6520        } finally {
6521            IoUtils.closeQuietly(fis);
6522        }
6523    }
6524
6525    @Override
6526    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6527        enforceNotIsolatedCaller("takePersistableUriPermission");
6528
6529        Preconditions.checkFlagsArgument(modeFlags,
6530                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6531
6532        synchronized (this) {
6533            final int callingUid = Binder.getCallingUid();
6534            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6535            if (perm == null) {
6536                throw new SecurityException("No permission grant found for UID " + callingUid
6537                        + " and Uri " + uri.toSafeString());
6538            }
6539
6540            boolean persistChanged = perm.takePersistableModes(modeFlags);
6541            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6542
6543            if (persistChanged) {
6544                schedulePersistUriGrants();
6545            }
6546        }
6547    }
6548
6549    @Override
6550    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6551        enforceNotIsolatedCaller("releasePersistableUriPermission");
6552
6553        Preconditions.checkFlagsArgument(modeFlags,
6554                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6555
6556        synchronized (this) {
6557            final int callingUid = Binder.getCallingUid();
6558
6559            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6560            if (perm == null) {
6561                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6562                        + uri.toSafeString());
6563                return;
6564            }
6565
6566            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6567            removeUriPermissionIfNeededLocked(perm);
6568            if (persistChanged) {
6569                schedulePersistUriGrants();
6570            }
6571        }
6572    }
6573
6574    /**
6575     * Prune any older {@link UriPermission} for the given UID until outstanding
6576     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6577     *
6578     * @return if any mutations occured that require persisting.
6579     */
6580    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6581        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6582        if (perms == null) return false;
6583        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6584
6585        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6586        for (UriPermission perm : perms.values()) {
6587            if (perm.persistedModeFlags != 0) {
6588                persisted.add(perm);
6589            }
6590        }
6591
6592        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6593        if (trimCount <= 0) return false;
6594
6595        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6596        for (int i = 0; i < trimCount; i++) {
6597            final UriPermission perm = persisted.get(i);
6598
6599            if (DEBUG_URI_PERMISSION) {
6600                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6601            }
6602
6603            perm.releasePersistableModes(~0);
6604            removeUriPermissionIfNeededLocked(perm);
6605        }
6606
6607        return true;
6608    }
6609
6610    @Override
6611    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6612            String packageName, boolean incoming) {
6613        enforceNotIsolatedCaller("getPersistedUriPermissions");
6614        Preconditions.checkNotNull(packageName, "packageName");
6615
6616        final int callingUid = Binder.getCallingUid();
6617        final IPackageManager pm = AppGlobals.getPackageManager();
6618        try {
6619            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6620            if (packageUid != callingUid) {
6621                throw new SecurityException(
6622                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6623            }
6624        } catch (RemoteException e) {
6625            throw new SecurityException("Failed to verify package name ownership");
6626        }
6627
6628        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6629        synchronized (this) {
6630            if (incoming) {
6631                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6632                if (perms == null) {
6633                    Slog.w(TAG, "No permission grants found for " + packageName);
6634                } else {
6635                    final int size = perms.size();
6636                    for (int i = 0; i < size; i++) {
6637                        final UriPermission perm = perms.valueAt(i);
6638                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6639                            result.add(perm.buildPersistedPublicApiObject());
6640                        }
6641                    }
6642                }
6643            } else {
6644                final int size = mGrantedUriPermissions.size();
6645                for (int i = 0; i < size; i++) {
6646                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6647                    final int permsSize = perms.size();
6648                    for (int j = 0; j < permsSize; j++) {
6649                        final UriPermission perm = perms.valueAt(j);
6650                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6651                            result.add(perm.buildPersistedPublicApiObject());
6652                        }
6653                    }
6654                }
6655            }
6656        }
6657        return new ParceledListSlice<android.content.UriPermission>(result);
6658    }
6659
6660    @Override
6661    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6662        synchronized (this) {
6663            ProcessRecord app =
6664                who != null ? getRecordForAppLocked(who) : null;
6665            if (app == null) return;
6666
6667            Message msg = Message.obtain();
6668            msg.what = WAIT_FOR_DEBUGGER_MSG;
6669            msg.obj = app;
6670            msg.arg1 = waiting ? 1 : 0;
6671            mHandler.sendMessage(msg);
6672        }
6673    }
6674
6675    @Override
6676    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6677        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6678        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6679        outInfo.availMem = Process.getFreeMemory();
6680        outInfo.totalMem = Process.getTotalMemory();
6681        outInfo.threshold = homeAppMem;
6682        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6683        outInfo.hiddenAppThreshold = cachedAppMem;
6684        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6685                ProcessList.SERVICE_ADJ);
6686        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6687                ProcessList.VISIBLE_APP_ADJ);
6688        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6689                ProcessList.FOREGROUND_APP_ADJ);
6690    }
6691
6692    // =========================================================
6693    // TASK MANAGEMENT
6694    // =========================================================
6695
6696    @Override
6697    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6698                         IThumbnailReceiver receiver) {
6699        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6700
6701        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6702        ActivityRecord topRecord = null;
6703
6704        synchronized(this) {
6705            if (localLOGV) Slog.v(
6706                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6707                + ", receiver=" + receiver);
6708
6709            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6710                    != PackageManager.PERMISSION_GRANTED) {
6711                if (receiver != null) {
6712                    // If the caller wants to wait for pending thumbnails,
6713                    // it ain't gonna get them.
6714                    try {
6715                        receiver.finished();
6716                    } catch (RemoteException ex) {
6717                    }
6718                }
6719                String msg = "Permission Denial: getTasks() from pid="
6720                        + Binder.getCallingPid()
6721                        + ", uid=" + Binder.getCallingUid()
6722                        + " requires " + android.Manifest.permission.GET_TASKS;
6723                Slog.w(TAG, msg);
6724                throw new SecurityException(msg);
6725            }
6726
6727            // TODO: Improve with MRU list from all ActivityStacks.
6728            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6729
6730            if (!pending.pendingRecords.isEmpty()) {
6731                mPendingThumbnails.add(pending);
6732            }
6733        }
6734
6735        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6736
6737        if (topRecord != null) {
6738            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6739            try {
6740                IApplicationThread topThumbnail = topRecord.app.thread;
6741                topThumbnail.requestThumbnail(topRecord.appToken);
6742            } catch (Exception e) {
6743                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6744                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6745            }
6746        }
6747
6748        if (pending == null && receiver != null) {
6749            // In this case all thumbnails were available and the client
6750            // is being asked to be told when the remaining ones come in...
6751            // which is unusually, since the top-most currently running
6752            // activity should never have a canned thumbnail!  Oh well.
6753            try {
6754                receiver.finished();
6755            } catch (RemoteException ex) {
6756            }
6757        }
6758
6759        return list;
6760    }
6761
6762    TaskRecord getMostRecentTask() {
6763        return mRecentTasks.get(0);
6764    }
6765
6766    @Override
6767    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6768            int flags, int userId) {
6769        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6770                false, true, "getRecentTasks", null);
6771
6772        synchronized (this) {
6773            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6774                    "getRecentTasks()");
6775            final boolean detailed = checkCallingPermission(
6776                    android.Manifest.permission.GET_DETAILED_TASKS)
6777                    == PackageManager.PERMISSION_GRANTED;
6778
6779            IPackageManager pm = AppGlobals.getPackageManager();
6780
6781            final int N = mRecentTasks.size();
6782            ArrayList<ActivityManager.RecentTaskInfo> res
6783                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6784                            maxNum < N ? maxNum : N);
6785            for (int i=0; i<N && maxNum > 0; i++) {
6786                TaskRecord tr = mRecentTasks.get(i);
6787                // Only add calling user's recent tasks
6788                if (tr.userId != userId) continue;
6789                // Return the entry if desired by the caller.  We always return
6790                // the first entry, because callers always expect this to be the
6791                // foreground app.  We may filter others if the caller has
6792                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6793                // we should exclude the entry.
6794
6795                if (i == 0
6796                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6797                        || (tr.intent == null)
6798                        || ((tr.intent.getFlags()
6799                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6800                    ActivityManager.RecentTaskInfo rti
6801                            = new ActivityManager.RecentTaskInfo();
6802                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6803                    rti.persistentId = tr.taskId;
6804                    rti.baseIntent = new Intent(
6805                            tr.intent != null ? tr.intent : tr.affinityIntent);
6806                    if (!detailed) {
6807                        rti.baseIntent.replaceExtras((Bundle)null);
6808                    }
6809                    rti.origActivity = tr.origActivity;
6810                    rti.description = tr.lastDescription;
6811                    rti.stackId = tr.stack.mStackId;
6812
6813                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6814                        // Check whether this activity is currently available.
6815                        try {
6816                            if (rti.origActivity != null) {
6817                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6818                                        == null) {
6819                                    continue;
6820                                }
6821                            } else if (rti.baseIntent != null) {
6822                                if (pm.queryIntentActivities(rti.baseIntent,
6823                                        null, 0, userId) == null) {
6824                                    continue;
6825                                }
6826                            }
6827                        } catch (RemoteException e) {
6828                            // Will never happen.
6829                        }
6830                    }
6831
6832                    res.add(rti);
6833                    maxNum--;
6834                }
6835            }
6836            return res;
6837        }
6838    }
6839
6840    private TaskRecord recentTaskForIdLocked(int id) {
6841        final int N = mRecentTasks.size();
6842            for (int i=0; i<N; i++) {
6843                TaskRecord tr = mRecentTasks.get(i);
6844                if (tr.taskId == id) {
6845                    return tr;
6846                }
6847            }
6848            return null;
6849    }
6850
6851    @Override
6852    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6853        synchronized (this) {
6854            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6855                    "getTaskThumbnails()");
6856            TaskRecord tr = recentTaskForIdLocked(id);
6857            if (tr != null) {
6858                return tr.getTaskThumbnailsLocked();
6859            }
6860        }
6861        return null;
6862    }
6863
6864    @Override
6865    public Bitmap getTaskTopThumbnail(int id) {
6866        synchronized (this) {
6867            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6868                    "getTaskTopThumbnail()");
6869            TaskRecord tr = recentTaskForIdLocked(id);
6870            if (tr != null) {
6871                return tr.getTaskTopThumbnailLocked();
6872            }
6873        }
6874        return null;
6875    }
6876
6877    @Override
6878    public boolean removeSubTask(int taskId, int subTaskIndex) {
6879        synchronized (this) {
6880            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6881                    "removeSubTask()");
6882            long ident = Binder.clearCallingIdentity();
6883            try {
6884                TaskRecord tr = recentTaskForIdLocked(taskId);
6885                if (tr != null) {
6886                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6887                }
6888                return false;
6889            } finally {
6890                Binder.restoreCallingIdentity(ident);
6891            }
6892        }
6893    }
6894
6895    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6896        if (!pr.killedByAm) {
6897            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6898            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6899                    pr.processName, pr.setAdj, reason);
6900            pr.killedByAm = true;
6901            Process.killProcessQuiet(pr.pid);
6902        }
6903    }
6904
6905    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6906        tr.disposeThumbnail();
6907        mRecentTasks.remove(tr);
6908        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6909        Intent baseIntent = new Intent(
6910                tr.intent != null ? tr.intent : tr.affinityIntent);
6911        ComponentName component = baseIntent.getComponent();
6912        if (component == null) {
6913            Slog.w(TAG, "Now component for base intent of task: " + tr);
6914            return;
6915        }
6916
6917        // Find any running services associated with this app.
6918        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6919
6920        if (killProcesses) {
6921            // Find any running processes associated with this app.
6922            final String pkg = component.getPackageName();
6923            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6924            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6925            for (int i=0; i<pmap.size(); i++) {
6926                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6927                for (int j=0; j<uids.size(); j++) {
6928                    ProcessRecord proc = uids.valueAt(j);
6929                    if (proc.userId != tr.userId) {
6930                        continue;
6931                    }
6932                    if (!proc.pkgList.containsKey(pkg)) {
6933                        continue;
6934                    }
6935                    procs.add(proc);
6936                }
6937            }
6938
6939            // Kill the running processes.
6940            for (int i=0; i<procs.size(); i++) {
6941                ProcessRecord pr = procs.get(i);
6942                if (pr == mHomeProcess) {
6943                    // Don't kill the home process along with tasks from the same package.
6944                    continue;
6945                }
6946                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6947                    killUnneededProcessLocked(pr, "remove task");
6948                } else {
6949                    pr.waitingToKill = "remove task";
6950                }
6951            }
6952        }
6953    }
6954
6955    @Override
6956    public boolean removeTask(int taskId, int flags) {
6957        synchronized (this) {
6958            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6959                    "removeTask()");
6960            long ident = Binder.clearCallingIdentity();
6961            try {
6962                TaskRecord tr = recentTaskForIdLocked(taskId);
6963                if (tr != null) {
6964                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6965                    if (r != null) {
6966                        cleanUpRemovedTaskLocked(tr, flags);
6967                        return true;
6968                    }
6969                    if (tr.mActivities.size() == 0) {
6970                        // Caller is just removing a recent task that is
6971                        // not actively running.  That is easy!
6972                        cleanUpRemovedTaskLocked(tr, flags);
6973                        return true;
6974                    }
6975                    Slog.w(TAG, "removeTask: task " + taskId
6976                            + " does not have activities to remove, "
6977                            + " but numActivities=" + tr.numActivities
6978                            + ": " + tr);
6979                }
6980            } finally {
6981                Binder.restoreCallingIdentity(ident);
6982            }
6983        }
6984        return false;
6985    }
6986
6987    /**
6988     * TODO: Add mController hook
6989     */
6990    @Override
6991    public void moveTaskToFront(int task, int flags, Bundle options) {
6992        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6993                "moveTaskToFront()");
6994
6995        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
6996        synchronized(this) {
6997            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6998                    Binder.getCallingUid(), "Task to front")) {
6999                ActivityOptions.abort(options);
7000                return;
7001            }
7002            final long origId = Binder.clearCallingIdentity();
7003            try {
7004                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7005            } finally {
7006                Binder.restoreCallingIdentity(origId);
7007            }
7008            ActivityOptions.abort(options);
7009        }
7010    }
7011
7012    @Override
7013    public void moveTaskToBack(int taskId) {
7014        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7015                "moveTaskToBack()");
7016
7017        synchronized(this) {
7018            TaskRecord tr = recentTaskForIdLocked(taskId);
7019            if (tr != null) {
7020                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7021                ActivityStack stack = tr.stack;
7022                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7023                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7024                            Binder.getCallingUid(), "Task to back")) {
7025                        return;
7026                    }
7027                }
7028                final long origId = Binder.clearCallingIdentity();
7029                try {
7030                    stack.moveTaskToBackLocked(taskId, null);
7031                } finally {
7032                    Binder.restoreCallingIdentity(origId);
7033                }
7034            }
7035        }
7036    }
7037
7038    /**
7039     * Moves an activity, and all of the other activities within the same task, to the bottom
7040     * of the history stack.  The activity's order within the task is unchanged.
7041     *
7042     * @param token A reference to the activity we wish to move
7043     * @param nonRoot If false then this only works if the activity is the root
7044     *                of a task; if true it will work for any activity in a task.
7045     * @return Returns true if the move completed, false if not.
7046     */
7047    @Override
7048    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7049        enforceNotIsolatedCaller("moveActivityTaskToBack");
7050        synchronized(this) {
7051            final long origId = Binder.clearCallingIdentity();
7052            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7053            if (taskId >= 0) {
7054                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7055            }
7056            Binder.restoreCallingIdentity(origId);
7057        }
7058        return false;
7059    }
7060
7061    @Override
7062    public void moveTaskBackwards(int task) {
7063        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7064                "moveTaskBackwards()");
7065
7066        synchronized(this) {
7067            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7068                    Binder.getCallingUid(), "Task backwards")) {
7069                return;
7070            }
7071            final long origId = Binder.clearCallingIdentity();
7072            moveTaskBackwardsLocked(task);
7073            Binder.restoreCallingIdentity(origId);
7074        }
7075    }
7076
7077    private final void moveTaskBackwardsLocked(int task) {
7078        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7079    }
7080
7081    @Override
7082    public IBinder getHomeActivityToken() throws RemoteException {
7083        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7084                "getHomeActivityToken()");
7085        synchronized (this) {
7086            return mStackSupervisor.getHomeActivityToken();
7087        }
7088    }
7089
7090    @Override
7091    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7092            IActivityContainerCallback callback) throws RemoteException {
7093        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7094                "createActivityContainer()");
7095        synchronized (this) {
7096            if (parentActivityToken == null) {
7097                throw new IllegalArgumentException("parent token must not be null");
7098            }
7099            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7100            if (r == null) {
7101                return null;
7102            }
7103            return mStackSupervisor.createActivityContainer(r, callback);
7104        }
7105    }
7106
7107    @Override
7108    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7109        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7110                "deleteActivityContainer()");
7111        synchronized (this) {
7112            mStackSupervisor.deleteActivityContainer(container);
7113        }
7114    }
7115
7116    @Override
7117    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7118            throws RemoteException {
7119        synchronized (this) {
7120            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7121            if (stack != null) {
7122                return stack.mActivityContainer;
7123            }
7124            return null;
7125        }
7126    }
7127
7128    @Override
7129    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7130        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7131                "moveTaskToStack()");
7132        if (stackId == HOME_STACK_ID) {
7133            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7134                    new RuntimeException("here").fillInStackTrace());
7135        }
7136        synchronized (this) {
7137            long ident = Binder.clearCallingIdentity();
7138            try {
7139                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7140                        + stackId + " toTop=" + toTop);
7141                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7142            } finally {
7143                Binder.restoreCallingIdentity(ident);
7144            }
7145        }
7146    }
7147
7148    @Override
7149    public void resizeStack(int stackBoxId, Rect bounds) {
7150        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7151                "resizeStackBox()");
7152        long ident = Binder.clearCallingIdentity();
7153        try {
7154            mWindowManager.resizeStack(stackBoxId, bounds);
7155        } finally {
7156            Binder.restoreCallingIdentity(ident);
7157        }
7158    }
7159
7160    @Override
7161    public List<StackInfo> getAllStackInfos() {
7162        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7163                "getAllStackInfos()");
7164        long ident = Binder.clearCallingIdentity();
7165        try {
7166            synchronized (this) {
7167                return mStackSupervisor.getAllStackInfosLocked();
7168            }
7169        } finally {
7170            Binder.restoreCallingIdentity(ident);
7171        }
7172    }
7173
7174    @Override
7175    public StackInfo getStackInfo(int stackId) {
7176        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7177                "getStackInfo()");
7178        long ident = Binder.clearCallingIdentity();
7179        try {
7180            synchronized (this) {
7181                return mStackSupervisor.getStackInfoLocked(stackId);
7182            }
7183        } finally {
7184            Binder.restoreCallingIdentity(ident);
7185        }
7186    }
7187
7188    @Override
7189    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7190        synchronized(this) {
7191            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7192        }
7193    }
7194
7195    // =========================================================
7196    // THUMBNAILS
7197    // =========================================================
7198
7199    public void reportThumbnail(IBinder token,
7200            Bitmap thumbnail, CharSequence description) {
7201        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7202        final long origId = Binder.clearCallingIdentity();
7203        sendPendingThumbnail(null, token, thumbnail, description, true);
7204        Binder.restoreCallingIdentity(origId);
7205    }
7206
7207    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7208            Bitmap thumbnail, CharSequence description, boolean always) {
7209        TaskRecord task;
7210        ArrayList<PendingThumbnailsRecord> receivers = null;
7211
7212        //System.out.println("Send pending thumbnail: " + r);
7213
7214        synchronized(this) {
7215            if (r == null) {
7216                r = ActivityRecord.isInStackLocked(token);
7217                if (r == null) {
7218                    return;
7219                }
7220            }
7221            if (thumbnail == null && r.thumbHolder != null) {
7222                thumbnail = r.thumbHolder.lastThumbnail;
7223                description = r.thumbHolder.lastDescription;
7224            }
7225            if (thumbnail == null && !always) {
7226                // If there is no thumbnail, and this entry is not actually
7227                // going away, then abort for now and pick up the next
7228                // thumbnail we get.
7229                return;
7230            }
7231            task = r.task;
7232
7233            int N = mPendingThumbnails.size();
7234            int i=0;
7235            while (i<N) {
7236                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7237                //System.out.println("Looking in " + pr.pendingRecords);
7238                if (pr.pendingRecords.remove(r)) {
7239                    if (receivers == null) {
7240                        receivers = new ArrayList<PendingThumbnailsRecord>();
7241                    }
7242                    receivers.add(pr);
7243                    if (pr.pendingRecords.size() == 0) {
7244                        pr.finished = true;
7245                        mPendingThumbnails.remove(i);
7246                        N--;
7247                        continue;
7248                    }
7249                }
7250                i++;
7251            }
7252        }
7253
7254        if (receivers != null) {
7255            final int N = receivers.size();
7256            for (int i=0; i<N; i++) {
7257                try {
7258                    PendingThumbnailsRecord pr = receivers.get(i);
7259                    pr.receiver.newThumbnail(
7260                        task != null ? task.taskId : -1, thumbnail, description);
7261                    if (pr.finished) {
7262                        pr.receiver.finished();
7263                    }
7264                } catch (Exception e) {
7265                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7266                }
7267            }
7268        }
7269    }
7270
7271    // =========================================================
7272    // CONTENT PROVIDERS
7273    // =========================================================
7274
7275    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7276        List<ProviderInfo> providers = null;
7277        try {
7278            providers = AppGlobals.getPackageManager().
7279                queryContentProviders(app.processName, app.uid,
7280                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7281        } catch (RemoteException ex) {
7282        }
7283        if (DEBUG_MU)
7284            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7285        int userId = app.userId;
7286        if (providers != null) {
7287            int N = providers.size();
7288            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7289            for (int i=0; i<N; i++) {
7290                ProviderInfo cpi =
7291                    (ProviderInfo)providers.get(i);
7292                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7293                        cpi.name, cpi.flags);
7294                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7295                    // This is a singleton provider, but a user besides the
7296                    // default user is asking to initialize a process it runs
7297                    // in...  well, no, it doesn't actually run in this process,
7298                    // it runs in the process of the default user.  Get rid of it.
7299                    providers.remove(i);
7300                    N--;
7301                    i--;
7302                    continue;
7303                }
7304
7305                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7306                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7307                if (cpr == null) {
7308                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7309                    mProviderMap.putProviderByClass(comp, cpr);
7310                }
7311                if (DEBUG_MU)
7312                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7313                app.pubProviders.put(cpi.name, cpr);
7314                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7315                    // Don't add this if it is a platform component that is marked
7316                    // to run in multiple processes, because this is actually
7317                    // part of the framework so doesn't make sense to track as a
7318                    // separate apk in the process.
7319                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7320                }
7321                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7322            }
7323        }
7324        return providers;
7325    }
7326
7327    /**
7328     * Check if {@link ProcessRecord} has a possible chance at accessing the
7329     * given {@link ProviderInfo}. Final permission checking is always done
7330     * in {@link ContentProvider}.
7331     */
7332    private final String checkContentProviderPermissionLocked(
7333            ProviderInfo cpi, ProcessRecord r) {
7334        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7335        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7336        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7337                cpi.applicationInfo.uid, cpi.exported)
7338                == PackageManager.PERMISSION_GRANTED) {
7339            return null;
7340        }
7341        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7342                cpi.applicationInfo.uid, cpi.exported)
7343                == PackageManager.PERMISSION_GRANTED) {
7344            return null;
7345        }
7346
7347        PathPermission[] pps = cpi.pathPermissions;
7348        if (pps != null) {
7349            int i = pps.length;
7350            while (i > 0) {
7351                i--;
7352                PathPermission pp = pps[i];
7353                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7354                        cpi.applicationInfo.uid, cpi.exported)
7355                        == PackageManager.PERMISSION_GRANTED) {
7356                    return null;
7357                }
7358                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7359                        cpi.applicationInfo.uid, cpi.exported)
7360                        == PackageManager.PERMISSION_GRANTED) {
7361                    return null;
7362                }
7363            }
7364        }
7365
7366        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7367        if (perms != null) {
7368            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7369                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7370                    return null;
7371                }
7372            }
7373        }
7374
7375        String msg;
7376        if (!cpi.exported) {
7377            msg = "Permission Denial: opening provider " + cpi.name
7378                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7379                    + ", uid=" + callingUid + ") that is not exported from uid "
7380                    + cpi.applicationInfo.uid;
7381        } else {
7382            msg = "Permission Denial: opening provider " + cpi.name
7383                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7384                    + ", uid=" + callingUid + ") requires "
7385                    + cpi.readPermission + " or " + cpi.writePermission;
7386        }
7387        Slog.w(TAG, msg);
7388        return msg;
7389    }
7390
7391    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7392            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7393        if (r != null) {
7394            for (int i=0; i<r.conProviders.size(); i++) {
7395                ContentProviderConnection conn = r.conProviders.get(i);
7396                if (conn.provider == cpr) {
7397                    if (DEBUG_PROVIDER) Slog.v(TAG,
7398                            "Adding provider requested by "
7399                            + r.processName + " from process "
7400                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7401                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7402                    if (stable) {
7403                        conn.stableCount++;
7404                        conn.numStableIncs++;
7405                    } else {
7406                        conn.unstableCount++;
7407                        conn.numUnstableIncs++;
7408                    }
7409                    return conn;
7410                }
7411            }
7412            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7413            if (stable) {
7414                conn.stableCount = 1;
7415                conn.numStableIncs = 1;
7416            } else {
7417                conn.unstableCount = 1;
7418                conn.numUnstableIncs = 1;
7419            }
7420            cpr.connections.add(conn);
7421            r.conProviders.add(conn);
7422            return conn;
7423        }
7424        cpr.addExternalProcessHandleLocked(externalProcessToken);
7425        return null;
7426    }
7427
7428    boolean decProviderCountLocked(ContentProviderConnection conn,
7429            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7430        if (conn != null) {
7431            cpr = conn.provider;
7432            if (DEBUG_PROVIDER) Slog.v(TAG,
7433                    "Removing provider requested by "
7434                    + conn.client.processName + " from process "
7435                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7436                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7437            if (stable) {
7438                conn.stableCount--;
7439            } else {
7440                conn.unstableCount--;
7441            }
7442            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7443                cpr.connections.remove(conn);
7444                conn.client.conProviders.remove(conn);
7445                return true;
7446            }
7447            return false;
7448        }
7449        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7450        return false;
7451    }
7452
7453    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7454            String name, IBinder token, boolean stable, int userId) {
7455        ContentProviderRecord cpr;
7456        ContentProviderConnection conn = null;
7457        ProviderInfo cpi = null;
7458
7459        synchronized(this) {
7460            ProcessRecord r = null;
7461            if (caller != null) {
7462                r = getRecordForAppLocked(caller);
7463                if (r == null) {
7464                    throw new SecurityException(
7465                            "Unable to find app for caller " + caller
7466                          + " (pid=" + Binder.getCallingPid()
7467                          + ") when getting content provider " + name);
7468                }
7469            }
7470
7471            // First check if this content provider has been published...
7472            cpr = mProviderMap.getProviderByName(name, userId);
7473            boolean providerRunning = cpr != null;
7474            if (providerRunning) {
7475                cpi = cpr.info;
7476                String msg;
7477                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7478                    throw new SecurityException(msg);
7479                }
7480
7481                if (r != null && cpr.canRunHere(r)) {
7482                    // This provider has been published or is in the process
7483                    // of being published...  but it is also allowed to run
7484                    // in the caller's process, so don't make a connection
7485                    // and just let the caller instantiate its own instance.
7486                    ContentProviderHolder holder = cpr.newHolder(null);
7487                    // don't give caller the provider object, it needs
7488                    // to make its own.
7489                    holder.provider = null;
7490                    return holder;
7491                }
7492
7493                final long origId = Binder.clearCallingIdentity();
7494
7495                // In this case the provider instance already exists, so we can
7496                // return it right away.
7497                conn = incProviderCountLocked(r, cpr, token, stable);
7498                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7499                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7500                        // If this is a perceptible app accessing the provider,
7501                        // make sure to count it as being accessed and thus
7502                        // back up on the LRU list.  This is good because
7503                        // content providers are often expensive to start.
7504                        updateLruProcessLocked(cpr.proc, false, null);
7505                    }
7506                }
7507
7508                if (cpr.proc != null) {
7509                    if (false) {
7510                        if (cpr.name.flattenToShortString().equals(
7511                                "com.android.providers.calendar/.CalendarProvider2")) {
7512                            Slog.v(TAG, "****************** KILLING "
7513                                + cpr.name.flattenToShortString());
7514                            Process.killProcess(cpr.proc.pid);
7515                        }
7516                    }
7517                    boolean success = updateOomAdjLocked(cpr.proc);
7518                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7519                    // NOTE: there is still a race here where a signal could be
7520                    // pending on the process even though we managed to update its
7521                    // adj level.  Not sure what to do about this, but at least
7522                    // the race is now smaller.
7523                    if (!success) {
7524                        // Uh oh...  it looks like the provider's process
7525                        // has been killed on us.  We need to wait for a new
7526                        // process to be started, and make sure its death
7527                        // doesn't kill our process.
7528                        Slog.i(TAG,
7529                                "Existing provider " + cpr.name.flattenToShortString()
7530                                + " is crashing; detaching " + r);
7531                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7532                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7533                        if (!lastRef) {
7534                            // This wasn't the last ref our process had on
7535                            // the provider...  we have now been killed, bail.
7536                            return null;
7537                        }
7538                        providerRunning = false;
7539                        conn = null;
7540                    }
7541                }
7542
7543                Binder.restoreCallingIdentity(origId);
7544            }
7545
7546            boolean singleton;
7547            if (!providerRunning) {
7548                try {
7549                    cpi = AppGlobals.getPackageManager().
7550                        resolveContentProvider(name,
7551                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7552                } catch (RemoteException ex) {
7553                }
7554                if (cpi == null) {
7555                    return null;
7556                }
7557                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7558                        cpi.name, cpi.flags);
7559                if (singleton) {
7560                    userId = 0;
7561                }
7562                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7563
7564                String msg;
7565                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7566                    throw new SecurityException(msg);
7567                }
7568
7569                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7570                        && !cpi.processName.equals("system")) {
7571                    // If this content provider does not run in the system
7572                    // process, and the system is not yet ready to run other
7573                    // processes, then fail fast instead of hanging.
7574                    throw new IllegalArgumentException(
7575                            "Attempt to launch content provider before system ready");
7576                }
7577
7578                // Make sure that the user who owns this provider is started.  If not,
7579                // we don't want to allow it to run.
7580                if (mStartedUsers.get(userId) == null) {
7581                    Slog.w(TAG, "Unable to launch app "
7582                            + cpi.applicationInfo.packageName + "/"
7583                            + cpi.applicationInfo.uid + " for provider "
7584                            + name + ": user " + userId + " is stopped");
7585                    return null;
7586                }
7587
7588                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7589                cpr = mProviderMap.getProviderByClass(comp, userId);
7590                final boolean firstClass = cpr == null;
7591                if (firstClass) {
7592                    try {
7593                        ApplicationInfo ai =
7594                            AppGlobals.getPackageManager().
7595                                getApplicationInfo(
7596                                        cpi.applicationInfo.packageName,
7597                                        STOCK_PM_FLAGS, userId);
7598                        if (ai == null) {
7599                            Slog.w(TAG, "No package info for content provider "
7600                                    + cpi.name);
7601                            return null;
7602                        }
7603                        ai = getAppInfoForUser(ai, userId);
7604                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7605                    } catch (RemoteException ex) {
7606                        // pm is in same process, this will never happen.
7607                    }
7608                }
7609
7610                if (r != null && cpr.canRunHere(r)) {
7611                    // If this is a multiprocess provider, then just return its
7612                    // info and allow the caller to instantiate it.  Only do
7613                    // this if the provider is the same user as the caller's
7614                    // process, or can run as root (so can be in any process).
7615                    return cpr.newHolder(null);
7616                }
7617
7618                if (DEBUG_PROVIDER) {
7619                    RuntimeException e = new RuntimeException("here");
7620                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7621                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7622                }
7623
7624                // This is single process, and our app is now connecting to it.
7625                // See if we are already in the process of launching this
7626                // provider.
7627                final int N = mLaunchingProviders.size();
7628                int i;
7629                for (i=0; i<N; i++) {
7630                    if (mLaunchingProviders.get(i) == cpr) {
7631                        break;
7632                    }
7633                }
7634
7635                // If the provider is not already being launched, then get it
7636                // started.
7637                if (i >= N) {
7638                    final long origId = Binder.clearCallingIdentity();
7639
7640                    try {
7641                        // Content provider is now in use, its package can't be stopped.
7642                        try {
7643                            AppGlobals.getPackageManager().setPackageStoppedState(
7644                                    cpr.appInfo.packageName, false, userId);
7645                        } catch (RemoteException e) {
7646                        } catch (IllegalArgumentException e) {
7647                            Slog.w(TAG, "Failed trying to unstop package "
7648                                    + cpr.appInfo.packageName + ": " + e);
7649                        }
7650
7651                        // Use existing process if already started
7652                        ProcessRecord proc = getProcessRecordLocked(
7653                                cpi.processName, cpr.appInfo.uid, false);
7654                        if (proc != null && proc.thread != null) {
7655                            if (DEBUG_PROVIDER) {
7656                                Slog.d(TAG, "Installing in existing process " + proc);
7657                            }
7658                            proc.pubProviders.put(cpi.name, cpr);
7659                            try {
7660                                proc.thread.scheduleInstallProvider(cpi);
7661                            } catch (RemoteException e) {
7662                            }
7663                        } else {
7664                            proc = startProcessLocked(cpi.processName,
7665                                    cpr.appInfo, false, 0, "content provider",
7666                                    new ComponentName(cpi.applicationInfo.packageName,
7667                                            cpi.name), false, false, false);
7668                            if (proc == null) {
7669                                Slog.w(TAG, "Unable to launch app "
7670                                        + cpi.applicationInfo.packageName + "/"
7671                                        + cpi.applicationInfo.uid + " for provider "
7672                                        + name + ": process is bad");
7673                                return null;
7674                            }
7675                        }
7676                        cpr.launchingApp = proc;
7677                        mLaunchingProviders.add(cpr);
7678                    } finally {
7679                        Binder.restoreCallingIdentity(origId);
7680                    }
7681                }
7682
7683                // Make sure the provider is published (the same provider class
7684                // may be published under multiple names).
7685                if (firstClass) {
7686                    mProviderMap.putProviderByClass(comp, cpr);
7687                }
7688
7689                mProviderMap.putProviderByName(name, cpr);
7690                conn = incProviderCountLocked(r, cpr, token, stable);
7691                if (conn != null) {
7692                    conn.waiting = true;
7693                }
7694            }
7695        }
7696
7697        // Wait for the provider to be published...
7698        synchronized (cpr) {
7699            while (cpr.provider == null) {
7700                if (cpr.launchingApp == null) {
7701                    Slog.w(TAG, "Unable to launch app "
7702                            + cpi.applicationInfo.packageName + "/"
7703                            + cpi.applicationInfo.uid + " for provider "
7704                            + name + ": launching app became null");
7705                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7706                            UserHandle.getUserId(cpi.applicationInfo.uid),
7707                            cpi.applicationInfo.packageName,
7708                            cpi.applicationInfo.uid, name);
7709                    return null;
7710                }
7711                try {
7712                    if (DEBUG_MU) {
7713                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7714                                + cpr.launchingApp);
7715                    }
7716                    if (conn != null) {
7717                        conn.waiting = true;
7718                    }
7719                    cpr.wait();
7720                } catch (InterruptedException ex) {
7721                } finally {
7722                    if (conn != null) {
7723                        conn.waiting = false;
7724                    }
7725                }
7726            }
7727        }
7728        return cpr != null ? cpr.newHolder(conn) : null;
7729    }
7730
7731    public final ContentProviderHolder getContentProvider(
7732            IApplicationThread caller, String name, int userId, boolean stable) {
7733        enforceNotIsolatedCaller("getContentProvider");
7734        if (caller == null) {
7735            String msg = "null IApplicationThread when getting content provider "
7736                    + name;
7737            Slog.w(TAG, msg);
7738            throw new SecurityException(msg);
7739        }
7740
7741        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7742                false, true, "getContentProvider", null);
7743        return getContentProviderImpl(caller, name, null, stable, userId);
7744    }
7745
7746    public ContentProviderHolder getContentProviderExternal(
7747            String name, int userId, IBinder token) {
7748        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7749            "Do not have permission in call getContentProviderExternal()");
7750        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7751                false, true, "getContentProvider", null);
7752        return getContentProviderExternalUnchecked(name, token, userId);
7753    }
7754
7755    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7756            IBinder token, int userId) {
7757        return getContentProviderImpl(null, name, token, true, userId);
7758    }
7759
7760    /**
7761     * Drop a content provider from a ProcessRecord's bookkeeping
7762     */
7763    public void removeContentProvider(IBinder connection, boolean stable) {
7764        enforceNotIsolatedCaller("removeContentProvider");
7765        synchronized (this) {
7766            ContentProviderConnection conn;
7767            try {
7768                conn = (ContentProviderConnection)connection;
7769            } catch (ClassCastException e) {
7770                String msg ="removeContentProvider: " + connection
7771                        + " not a ContentProviderConnection";
7772                Slog.w(TAG, msg);
7773                throw new IllegalArgumentException(msg);
7774            }
7775            if (conn == null) {
7776                throw new NullPointerException("connection is null");
7777            }
7778            if (decProviderCountLocked(conn, null, null, stable)) {
7779                updateOomAdjLocked();
7780            }
7781        }
7782    }
7783
7784    public void removeContentProviderExternal(String name, IBinder token) {
7785        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7786            "Do not have permission in call removeContentProviderExternal()");
7787        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7788    }
7789
7790    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7791        synchronized (this) {
7792            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7793            if(cpr == null) {
7794                //remove from mProvidersByClass
7795                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7796                return;
7797            }
7798
7799            //update content provider record entry info
7800            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7801            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7802            if (localCpr.hasExternalProcessHandles()) {
7803                if (localCpr.removeExternalProcessHandleLocked(token)) {
7804                    updateOomAdjLocked();
7805                } else {
7806                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7807                            + " with no external reference for token: "
7808                            + token + ".");
7809                }
7810            } else {
7811                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7812                        + " with no external references.");
7813            }
7814        }
7815    }
7816
7817    public final void publishContentProviders(IApplicationThread caller,
7818            List<ContentProviderHolder> providers) {
7819        if (providers == null) {
7820            return;
7821        }
7822
7823        enforceNotIsolatedCaller("publishContentProviders");
7824        synchronized (this) {
7825            final ProcessRecord r = getRecordForAppLocked(caller);
7826            if (DEBUG_MU)
7827                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7828            if (r == null) {
7829                throw new SecurityException(
7830                        "Unable to find app for caller " + caller
7831                      + " (pid=" + Binder.getCallingPid()
7832                      + ") when publishing content providers");
7833            }
7834
7835            final long origId = Binder.clearCallingIdentity();
7836
7837            final int N = providers.size();
7838            for (int i=0; i<N; i++) {
7839                ContentProviderHolder src = providers.get(i);
7840                if (src == null || src.info == null || src.provider == null) {
7841                    continue;
7842                }
7843                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7844                if (DEBUG_MU)
7845                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7846                if (dst != null) {
7847                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7848                    mProviderMap.putProviderByClass(comp, dst);
7849                    String names[] = dst.info.authority.split(";");
7850                    for (int j = 0; j < names.length; j++) {
7851                        mProviderMap.putProviderByName(names[j], dst);
7852                    }
7853
7854                    int NL = mLaunchingProviders.size();
7855                    int j;
7856                    for (j=0; j<NL; j++) {
7857                        if (mLaunchingProviders.get(j) == dst) {
7858                            mLaunchingProviders.remove(j);
7859                            j--;
7860                            NL--;
7861                        }
7862                    }
7863                    synchronized (dst) {
7864                        dst.provider = src.provider;
7865                        dst.proc = r;
7866                        dst.notifyAll();
7867                    }
7868                    updateOomAdjLocked(r);
7869                }
7870            }
7871
7872            Binder.restoreCallingIdentity(origId);
7873        }
7874    }
7875
7876    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7877        ContentProviderConnection conn;
7878        try {
7879            conn = (ContentProviderConnection)connection;
7880        } catch (ClassCastException e) {
7881            String msg ="refContentProvider: " + connection
7882                    + " not a ContentProviderConnection";
7883            Slog.w(TAG, msg);
7884            throw new IllegalArgumentException(msg);
7885        }
7886        if (conn == null) {
7887            throw new NullPointerException("connection is null");
7888        }
7889
7890        synchronized (this) {
7891            if (stable > 0) {
7892                conn.numStableIncs += stable;
7893            }
7894            stable = conn.stableCount + stable;
7895            if (stable < 0) {
7896                throw new IllegalStateException("stableCount < 0: " + stable);
7897            }
7898
7899            if (unstable > 0) {
7900                conn.numUnstableIncs += unstable;
7901            }
7902            unstable = conn.unstableCount + unstable;
7903            if (unstable < 0) {
7904                throw new IllegalStateException("unstableCount < 0: " + unstable);
7905            }
7906
7907            if ((stable+unstable) <= 0) {
7908                throw new IllegalStateException("ref counts can't go to zero here: stable="
7909                        + stable + " unstable=" + unstable);
7910            }
7911            conn.stableCount = stable;
7912            conn.unstableCount = unstable;
7913            return !conn.dead;
7914        }
7915    }
7916
7917    public void unstableProviderDied(IBinder connection) {
7918        ContentProviderConnection conn;
7919        try {
7920            conn = (ContentProviderConnection)connection;
7921        } catch (ClassCastException e) {
7922            String msg ="refContentProvider: " + connection
7923                    + " not a ContentProviderConnection";
7924            Slog.w(TAG, msg);
7925            throw new IllegalArgumentException(msg);
7926        }
7927        if (conn == null) {
7928            throw new NullPointerException("connection is null");
7929        }
7930
7931        // Safely retrieve the content provider associated with the connection.
7932        IContentProvider provider;
7933        synchronized (this) {
7934            provider = conn.provider.provider;
7935        }
7936
7937        if (provider == null) {
7938            // Um, yeah, we're way ahead of you.
7939            return;
7940        }
7941
7942        // Make sure the caller is being honest with us.
7943        if (provider.asBinder().pingBinder()) {
7944            // Er, no, still looks good to us.
7945            synchronized (this) {
7946                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7947                        + " says " + conn + " died, but we don't agree");
7948                return;
7949            }
7950        }
7951
7952        // Well look at that!  It's dead!
7953        synchronized (this) {
7954            if (conn.provider.provider != provider) {
7955                // But something changed...  good enough.
7956                return;
7957            }
7958
7959            ProcessRecord proc = conn.provider.proc;
7960            if (proc == null || proc.thread == null) {
7961                // Seems like the process is already cleaned up.
7962                return;
7963            }
7964
7965            // As far as we're concerned, this is just like receiving a
7966            // death notification...  just a bit prematurely.
7967            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7968                    + ") early provider death");
7969            final long ident = Binder.clearCallingIdentity();
7970            try {
7971                appDiedLocked(proc, proc.pid, proc.thread);
7972            } finally {
7973                Binder.restoreCallingIdentity(ident);
7974            }
7975        }
7976    }
7977
7978    @Override
7979    public void appNotRespondingViaProvider(IBinder connection) {
7980        enforceCallingPermission(
7981                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7982
7983        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7984        if (conn == null) {
7985            Slog.w(TAG, "ContentProviderConnection is null");
7986            return;
7987        }
7988
7989        final ProcessRecord host = conn.provider.proc;
7990        if (host == null) {
7991            Slog.w(TAG, "Failed to find hosting ProcessRecord");
7992            return;
7993        }
7994
7995        final long token = Binder.clearCallingIdentity();
7996        try {
7997            appNotResponding(host, null, null, false, "ContentProvider not responding");
7998        } finally {
7999            Binder.restoreCallingIdentity(token);
8000        }
8001    }
8002
8003    public final void installSystemProviders() {
8004        List<ProviderInfo> providers;
8005        synchronized (this) {
8006            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8007            providers = generateApplicationProvidersLocked(app);
8008            if (providers != null) {
8009                for (int i=providers.size()-1; i>=0; i--) {
8010                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8011                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8012                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8013                                + ": not system .apk");
8014                        providers.remove(i);
8015                    }
8016                }
8017            }
8018        }
8019        if (providers != null) {
8020            mSystemThread.installSystemProviders(providers);
8021        }
8022
8023        mCoreSettingsObserver = new CoreSettingsObserver(this);
8024
8025        mUsageStatsService.monitorPackages();
8026    }
8027
8028    /**
8029     * Allows app to retrieve the MIME type of a URI without having permission
8030     * to access its content provider.
8031     *
8032     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8033     *
8034     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8035     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8036     */
8037    public String getProviderMimeType(Uri uri, int userId) {
8038        enforceNotIsolatedCaller("getProviderMimeType");
8039        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8040                userId, false, true, "getProviderMimeType", null);
8041        final String name = uri.getAuthority();
8042        final long ident = Binder.clearCallingIdentity();
8043        ContentProviderHolder holder = null;
8044
8045        try {
8046            holder = getContentProviderExternalUnchecked(name, null, userId);
8047            if (holder != null) {
8048                return holder.provider.getType(uri);
8049            }
8050        } catch (RemoteException e) {
8051            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8052            return null;
8053        } finally {
8054            if (holder != null) {
8055                removeContentProviderExternalUnchecked(name, null, userId);
8056            }
8057            Binder.restoreCallingIdentity(ident);
8058        }
8059
8060        return null;
8061    }
8062
8063    // =========================================================
8064    // GLOBAL MANAGEMENT
8065    // =========================================================
8066
8067    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8068            boolean isolated) {
8069        String proc = customProcess != null ? customProcess : info.processName;
8070        BatteryStatsImpl.Uid.Proc ps = null;
8071        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8072        int uid = info.uid;
8073        if (isolated) {
8074            int userId = UserHandle.getUserId(uid);
8075            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8076            while (true) {
8077                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8078                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8079                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8080                }
8081                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8082                mNextIsolatedProcessUid++;
8083                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8084                    // No process for this uid, use it.
8085                    break;
8086                }
8087                stepsLeft--;
8088                if (stepsLeft <= 0) {
8089                    return null;
8090                }
8091            }
8092        }
8093        return new ProcessRecord(stats, info, proc, uid);
8094    }
8095
8096    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8097        ProcessRecord app;
8098        if (!isolated) {
8099            app = getProcessRecordLocked(info.processName, info.uid, true);
8100        } else {
8101            app = null;
8102        }
8103
8104        if (app == null) {
8105            app = newProcessRecordLocked(info, null, isolated);
8106            mProcessNames.put(info.processName, app.uid, app);
8107            if (isolated) {
8108                mIsolatedProcesses.put(app.uid, app);
8109            }
8110            updateLruProcessLocked(app, false, null);
8111            updateOomAdjLocked();
8112        }
8113
8114        // This package really, really can not be stopped.
8115        try {
8116            AppGlobals.getPackageManager().setPackageStoppedState(
8117                    info.packageName, false, UserHandle.getUserId(app.uid));
8118        } catch (RemoteException e) {
8119        } catch (IllegalArgumentException e) {
8120            Slog.w(TAG, "Failed trying to unstop package "
8121                    + info.packageName + ": " + e);
8122        }
8123
8124        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8125                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8126            app.persistent = true;
8127            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8128        }
8129        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8130            mPersistentStartingProcesses.add(app);
8131            startProcessLocked(app, "added application", app.processName);
8132        }
8133
8134        return app;
8135    }
8136
8137    public void unhandledBack() {
8138        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8139                "unhandledBack()");
8140
8141        synchronized(this) {
8142            final long origId = Binder.clearCallingIdentity();
8143            try {
8144                getFocusedStack().unhandledBackLocked();
8145            } finally {
8146                Binder.restoreCallingIdentity(origId);
8147            }
8148        }
8149    }
8150
8151    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8152        enforceNotIsolatedCaller("openContentUri");
8153        final int userId = UserHandle.getCallingUserId();
8154        String name = uri.getAuthority();
8155        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8156        ParcelFileDescriptor pfd = null;
8157        if (cph != null) {
8158            // We record the binder invoker's uid in thread-local storage before
8159            // going to the content provider to open the file.  Later, in the code
8160            // that handles all permissions checks, we look for this uid and use
8161            // that rather than the Activity Manager's own uid.  The effect is that
8162            // we do the check against the caller's permissions even though it looks
8163            // to the content provider like the Activity Manager itself is making
8164            // the request.
8165            sCallerIdentity.set(new Identity(
8166                    Binder.getCallingPid(), Binder.getCallingUid()));
8167            try {
8168                pfd = cph.provider.openFile(null, uri, "r", null);
8169            } catch (FileNotFoundException e) {
8170                // do nothing; pfd will be returned null
8171            } finally {
8172                // Ensure that whatever happens, we clean up the identity state
8173                sCallerIdentity.remove();
8174            }
8175
8176            // We've got the fd now, so we're done with the provider.
8177            removeContentProviderExternalUnchecked(name, null, userId);
8178        } else {
8179            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8180        }
8181        return pfd;
8182    }
8183
8184    // Actually is sleeping or shutting down or whatever else in the future
8185    // is an inactive state.
8186    public boolean isSleepingOrShuttingDown() {
8187        return mSleeping || mShuttingDown;
8188    }
8189
8190    void goingToSleep() {
8191        synchronized(this) {
8192            mWentToSleep = true;
8193            updateEventDispatchingLocked();
8194
8195            if (!mSleeping) {
8196                mSleeping = true;
8197                mStackSupervisor.goingToSleepLocked();
8198
8199                // Initialize the wake times of all processes.
8200                checkExcessivePowerUsageLocked(false);
8201                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8202                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8203                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8204            }
8205        }
8206    }
8207
8208    @Override
8209    public boolean shutdown(int timeout) {
8210        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8211                != PackageManager.PERMISSION_GRANTED) {
8212            throw new SecurityException("Requires permission "
8213                    + android.Manifest.permission.SHUTDOWN);
8214        }
8215
8216        boolean timedout = false;
8217
8218        synchronized(this) {
8219            mShuttingDown = true;
8220            updateEventDispatchingLocked();
8221            timedout = mStackSupervisor.shutdownLocked(timeout);
8222        }
8223
8224        mAppOpsService.shutdown();
8225        mUsageStatsService.shutdown();
8226        mBatteryStatsService.shutdown();
8227        synchronized (this) {
8228            mProcessStats.shutdownLocked();
8229        }
8230
8231        return timedout;
8232    }
8233
8234    public final void activitySlept(IBinder token) {
8235        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8236
8237        final long origId = Binder.clearCallingIdentity();
8238
8239        synchronized (this) {
8240            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8241            if (r != null) {
8242                mStackSupervisor.activitySleptLocked(r);
8243            }
8244        }
8245
8246        Binder.restoreCallingIdentity(origId);
8247    }
8248
8249    void logLockScreen(String msg) {
8250        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8251                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8252                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8253                mStackSupervisor.mDismissKeyguardOnNextActivity);
8254    }
8255
8256    private void comeOutOfSleepIfNeededLocked() {
8257        if (!mWentToSleep && !mLockScreenShown) {
8258            if (mSleeping) {
8259                mSleeping = false;
8260                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8261            }
8262        }
8263    }
8264
8265    void wakingUp() {
8266        synchronized(this) {
8267            mWentToSleep = false;
8268            updateEventDispatchingLocked();
8269            comeOutOfSleepIfNeededLocked();
8270        }
8271    }
8272
8273    private void updateEventDispatchingLocked() {
8274        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8275    }
8276
8277    public void setLockScreenShown(boolean shown) {
8278        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8279                != PackageManager.PERMISSION_GRANTED) {
8280            throw new SecurityException("Requires permission "
8281                    + android.Manifest.permission.DEVICE_POWER);
8282        }
8283
8284        synchronized(this) {
8285            long ident = Binder.clearCallingIdentity();
8286            try {
8287                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8288                mLockScreenShown = shown;
8289                comeOutOfSleepIfNeededLocked();
8290            } finally {
8291                Binder.restoreCallingIdentity(ident);
8292            }
8293        }
8294    }
8295
8296    public void stopAppSwitches() {
8297        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8298                != PackageManager.PERMISSION_GRANTED) {
8299            throw new SecurityException("Requires permission "
8300                    + android.Manifest.permission.STOP_APP_SWITCHES);
8301        }
8302
8303        synchronized(this) {
8304            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8305                    + APP_SWITCH_DELAY_TIME;
8306            mDidAppSwitch = false;
8307            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8308            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8309            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8310        }
8311    }
8312
8313    public void resumeAppSwitches() {
8314        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8315                != PackageManager.PERMISSION_GRANTED) {
8316            throw new SecurityException("Requires permission "
8317                    + android.Manifest.permission.STOP_APP_SWITCHES);
8318        }
8319
8320        synchronized(this) {
8321            // Note that we don't execute any pending app switches... we will
8322            // let those wait until either the timeout, or the next start
8323            // activity request.
8324            mAppSwitchesAllowedTime = 0;
8325        }
8326    }
8327
8328    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8329            String name) {
8330        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8331            return true;
8332        }
8333
8334        final int perm = checkComponentPermission(
8335                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8336                callingUid, -1, true);
8337        if (perm == PackageManager.PERMISSION_GRANTED) {
8338            return true;
8339        }
8340
8341        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8342        return false;
8343    }
8344
8345    public void setDebugApp(String packageName, boolean waitForDebugger,
8346            boolean persistent) {
8347        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8348                "setDebugApp()");
8349
8350        long ident = Binder.clearCallingIdentity();
8351        try {
8352            // Note that this is not really thread safe if there are multiple
8353            // callers into it at the same time, but that's not a situation we
8354            // care about.
8355            if (persistent) {
8356                final ContentResolver resolver = mContext.getContentResolver();
8357                Settings.Global.putString(
8358                    resolver, Settings.Global.DEBUG_APP,
8359                    packageName);
8360                Settings.Global.putInt(
8361                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8362                    waitForDebugger ? 1 : 0);
8363            }
8364
8365            synchronized (this) {
8366                if (!persistent) {
8367                    mOrigDebugApp = mDebugApp;
8368                    mOrigWaitForDebugger = mWaitForDebugger;
8369                }
8370                mDebugApp = packageName;
8371                mWaitForDebugger = waitForDebugger;
8372                mDebugTransient = !persistent;
8373                if (packageName != null) {
8374                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8375                            UserHandle.USER_ALL, "set debug app");
8376                }
8377            }
8378        } finally {
8379            Binder.restoreCallingIdentity(ident);
8380        }
8381    }
8382
8383    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
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
8392            mOpenGlTraceApp = processName;
8393        }
8394    }
8395
8396    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8397            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8398        synchronized (this) {
8399            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8400            if (!isDebuggable) {
8401                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8402                    throw new SecurityException("Process not debuggable: " + app.packageName);
8403                }
8404            }
8405            mProfileApp = processName;
8406            mProfileFile = profileFile;
8407            if (mProfileFd != null) {
8408                try {
8409                    mProfileFd.close();
8410                } catch (IOException e) {
8411                }
8412                mProfileFd = null;
8413            }
8414            mProfileFd = profileFd;
8415            mProfileType = 0;
8416            mAutoStopProfiler = autoStopProfiler;
8417        }
8418    }
8419
8420    @Override
8421    public void setAlwaysFinish(boolean enabled) {
8422        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8423                "setAlwaysFinish()");
8424
8425        Settings.Global.putInt(
8426                mContext.getContentResolver(),
8427                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8428
8429        synchronized (this) {
8430            mAlwaysFinishActivities = enabled;
8431        }
8432    }
8433
8434    @Override
8435    public void setActivityController(IActivityController controller) {
8436        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8437                "setActivityController()");
8438        synchronized (this) {
8439            mController = controller;
8440            Watchdog.getInstance().setActivityController(controller);
8441        }
8442    }
8443
8444    @Override
8445    public void setUserIsMonkey(boolean userIsMonkey) {
8446        synchronized (this) {
8447            synchronized (mPidsSelfLocked) {
8448                final int callingPid = Binder.getCallingPid();
8449                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8450                if (precessRecord == null) {
8451                    throw new SecurityException("Unknown process: " + callingPid);
8452                }
8453                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8454                    throw new SecurityException("Only an instrumentation process "
8455                            + "with a UiAutomation can call setUserIsMonkey");
8456                }
8457            }
8458            mUserIsMonkey = userIsMonkey;
8459        }
8460    }
8461
8462    @Override
8463    public boolean isUserAMonkey() {
8464        synchronized (this) {
8465            // If there is a controller also implies the user is a monkey.
8466            return (mUserIsMonkey || mController != null);
8467        }
8468    }
8469
8470    public void requestBugReport() {
8471        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8472        SystemProperties.set("ctl.start", "bugreport");
8473    }
8474
8475    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8476        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8477    }
8478
8479    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8480        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8481            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8482        }
8483        return KEY_DISPATCHING_TIMEOUT;
8484    }
8485
8486    @Override
8487    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8488        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8489                != PackageManager.PERMISSION_GRANTED) {
8490            throw new SecurityException("Requires permission "
8491                    + android.Manifest.permission.FILTER_EVENTS);
8492        }
8493        ProcessRecord proc;
8494        long timeout;
8495        synchronized (this) {
8496            synchronized (mPidsSelfLocked) {
8497                proc = mPidsSelfLocked.get(pid);
8498            }
8499            timeout = getInputDispatchingTimeoutLocked(proc);
8500        }
8501
8502        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8503            return -1;
8504        }
8505
8506        return timeout;
8507    }
8508
8509    /**
8510     * Handle input dispatching timeouts.
8511     * Returns whether input dispatching should be aborted or not.
8512     */
8513    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8514            final ActivityRecord activity, final ActivityRecord parent,
8515            final boolean aboveSystem, String reason) {
8516        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8517                != PackageManager.PERMISSION_GRANTED) {
8518            throw new SecurityException("Requires permission "
8519                    + android.Manifest.permission.FILTER_EVENTS);
8520        }
8521
8522        final String annotation;
8523        if (reason == null) {
8524            annotation = "Input dispatching timed out";
8525        } else {
8526            annotation = "Input dispatching timed out (" + reason + ")";
8527        }
8528
8529        if (proc != null) {
8530            synchronized (this) {
8531                if (proc.debugging) {
8532                    return false;
8533                }
8534
8535                if (mDidDexOpt) {
8536                    // Give more time since we were dexopting.
8537                    mDidDexOpt = false;
8538                    return false;
8539                }
8540
8541                if (proc.instrumentationClass != null) {
8542                    Bundle info = new Bundle();
8543                    info.putString("shortMsg", "keyDispatchingTimedOut");
8544                    info.putString("longMsg", annotation);
8545                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8546                    return true;
8547                }
8548            }
8549            mHandler.post(new Runnable() {
8550                @Override
8551                public void run() {
8552                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8553                }
8554            });
8555        }
8556
8557        return true;
8558    }
8559
8560    public Bundle getAssistContextExtras(int requestType) {
8561        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8562                "getAssistContextExtras()");
8563        PendingAssistExtras pae;
8564        Bundle extras = new Bundle();
8565        synchronized (this) {
8566            ActivityRecord activity = getFocusedStack().mResumedActivity;
8567            if (activity == null) {
8568                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8569                return null;
8570            }
8571            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8572            if (activity.app == null || activity.app.thread == null) {
8573                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8574                return extras;
8575            }
8576            if (activity.app.pid == Binder.getCallingPid()) {
8577                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8578                return extras;
8579            }
8580            pae = new PendingAssistExtras(activity);
8581            try {
8582                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8583                        requestType);
8584                mPendingAssistExtras.add(pae);
8585                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8586            } catch (RemoteException e) {
8587                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8588                return extras;
8589            }
8590        }
8591        synchronized (pae) {
8592            while (!pae.haveResult) {
8593                try {
8594                    pae.wait();
8595                } catch (InterruptedException e) {
8596                }
8597            }
8598            if (pae.result != null) {
8599                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8600            }
8601        }
8602        synchronized (this) {
8603            mPendingAssistExtras.remove(pae);
8604            mHandler.removeCallbacks(pae);
8605        }
8606        return extras;
8607    }
8608
8609    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8610        PendingAssistExtras pae = (PendingAssistExtras)token;
8611        synchronized (pae) {
8612            pae.result = extras;
8613            pae.haveResult = true;
8614            pae.notifyAll();
8615        }
8616    }
8617
8618    public void registerProcessObserver(IProcessObserver observer) {
8619        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8620                "registerProcessObserver()");
8621        synchronized (this) {
8622            mProcessObservers.register(observer);
8623        }
8624    }
8625
8626    @Override
8627    public void unregisterProcessObserver(IProcessObserver observer) {
8628        synchronized (this) {
8629            mProcessObservers.unregister(observer);
8630        }
8631    }
8632
8633    @Override
8634    public boolean convertFromTranslucent(IBinder token) {
8635        final long origId = Binder.clearCallingIdentity();
8636        try {
8637            synchronized (this) {
8638                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8639                if (r == null) {
8640                    return false;
8641                }
8642                if (r.changeWindowTranslucency(true)) {
8643                    mWindowManager.setAppFullscreen(token, true);
8644                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8645                    return true;
8646                }
8647                return false;
8648            }
8649        } finally {
8650            Binder.restoreCallingIdentity(origId);
8651        }
8652    }
8653
8654    @Override
8655    public boolean convertToTranslucent(IBinder token) {
8656        final long origId = Binder.clearCallingIdentity();
8657        try {
8658            synchronized (this) {
8659                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8660                if (r == null) {
8661                    return false;
8662                }
8663                if (r.changeWindowTranslucency(false)) {
8664                    r.task.stack.convertToTranslucent(r);
8665                    mWindowManager.setAppFullscreen(token, false);
8666                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8667                    return true;
8668                }
8669                return false;
8670            }
8671        } finally {
8672            Binder.restoreCallingIdentity(origId);
8673        }
8674    }
8675
8676    @Override
8677    public void setImmersive(IBinder token, boolean immersive) {
8678        synchronized(this) {
8679            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8680            if (r == null) {
8681                throw new IllegalArgumentException();
8682            }
8683            r.immersive = immersive;
8684
8685            // update associated state if we're frontmost
8686            if (r == mFocusedActivity) {
8687                if (DEBUG_IMMERSIVE) {
8688                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8689                }
8690                applyUpdateLockStateLocked(r);
8691            }
8692        }
8693    }
8694
8695    @Override
8696    public boolean isImmersive(IBinder token) {
8697        synchronized (this) {
8698            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8699            if (r == null) {
8700                throw new IllegalArgumentException();
8701            }
8702            return r.immersive;
8703        }
8704    }
8705
8706    public boolean isTopActivityImmersive() {
8707        enforceNotIsolatedCaller("startActivity");
8708        synchronized (this) {
8709            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8710            return (r != null) ? r.immersive : false;
8711        }
8712    }
8713
8714    public final void enterSafeMode() {
8715        synchronized(this) {
8716            // It only makes sense to do this before the system is ready
8717            // and started launching other packages.
8718            if (!mSystemReady) {
8719                try {
8720                    AppGlobals.getPackageManager().enterSafeMode();
8721                } catch (RemoteException e) {
8722                }
8723            }
8724
8725            mSafeMode = true;
8726        }
8727    }
8728
8729    public final void showSafeModeOverlay() {
8730        View v = LayoutInflater.from(mContext).inflate(
8731                com.android.internal.R.layout.safe_mode, null);
8732        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8733        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8734        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8735        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8736        lp.gravity = Gravity.BOTTOM | Gravity.START;
8737        lp.format = v.getBackground().getOpacity();
8738        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8739                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8740        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8741        ((WindowManager)mContext.getSystemService(
8742                Context.WINDOW_SERVICE)).addView(v, lp);
8743    }
8744
8745    public void noteWakeupAlarm(IIntentSender sender) {
8746        if (!(sender instanceof PendingIntentRecord)) {
8747            return;
8748        }
8749        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8750        synchronized (stats) {
8751            if (mBatteryStatsService.isOnBattery()) {
8752                mBatteryStatsService.enforceCallingPermission();
8753                PendingIntentRecord rec = (PendingIntentRecord)sender;
8754                int MY_UID = Binder.getCallingUid();
8755                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8756                BatteryStatsImpl.Uid.Pkg pkg =
8757                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8758                pkg.incWakeupsLocked();
8759            }
8760        }
8761    }
8762
8763    public boolean killPids(int[] pids, String pReason, boolean secure) {
8764        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8765            throw new SecurityException("killPids only available to the system");
8766        }
8767        String reason = (pReason == null) ? "Unknown" : pReason;
8768        // XXX Note: don't acquire main activity lock here, because the window
8769        // manager calls in with its locks held.
8770
8771        boolean killed = false;
8772        synchronized (mPidsSelfLocked) {
8773            int[] types = new int[pids.length];
8774            int worstType = 0;
8775            for (int i=0; i<pids.length; i++) {
8776                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8777                if (proc != null) {
8778                    int type = proc.setAdj;
8779                    types[i] = type;
8780                    if (type > worstType) {
8781                        worstType = type;
8782                    }
8783                }
8784            }
8785
8786            // If the worst oom_adj is somewhere in the cached proc LRU range,
8787            // then constrain it so we will kill all cached procs.
8788            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8789                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8790                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8791            }
8792
8793            // If this is not a secure call, don't let it kill processes that
8794            // are important.
8795            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8796                worstType = ProcessList.SERVICE_ADJ;
8797            }
8798
8799            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8800            for (int i=0; i<pids.length; i++) {
8801                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8802                if (proc == null) {
8803                    continue;
8804                }
8805                int adj = proc.setAdj;
8806                if (adj >= worstType && !proc.killedByAm) {
8807                    killUnneededProcessLocked(proc, reason);
8808                    killed = true;
8809                }
8810            }
8811        }
8812        return killed;
8813    }
8814
8815    @Override
8816    public void killUid(int uid, String reason) {
8817        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8818            throw new SecurityException("killUid only available to the system");
8819        }
8820        synchronized (this) {
8821            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8822                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8823                    reason != null ? reason : "kill uid");
8824        }
8825    }
8826
8827    @Override
8828    public boolean killProcessesBelowForeground(String reason) {
8829        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8830            throw new SecurityException("killProcessesBelowForeground() only available to system");
8831        }
8832
8833        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8834    }
8835
8836    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8837        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8838            throw new SecurityException("killProcessesBelowAdj() only available to system");
8839        }
8840
8841        boolean killed = false;
8842        synchronized (mPidsSelfLocked) {
8843            final int size = mPidsSelfLocked.size();
8844            for (int i = 0; i < size; i++) {
8845                final int pid = mPidsSelfLocked.keyAt(i);
8846                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8847                if (proc == null) continue;
8848
8849                final int adj = proc.setAdj;
8850                if (adj > belowAdj && !proc.killedByAm) {
8851                    killUnneededProcessLocked(proc, reason);
8852                    killed = true;
8853                }
8854            }
8855        }
8856        return killed;
8857    }
8858
8859    @Override
8860    public void hang(final IBinder who, boolean allowRestart) {
8861        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8862                != PackageManager.PERMISSION_GRANTED) {
8863            throw new SecurityException("Requires permission "
8864                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8865        }
8866
8867        final IBinder.DeathRecipient death = new DeathRecipient() {
8868            @Override
8869            public void binderDied() {
8870                synchronized (this) {
8871                    notifyAll();
8872                }
8873            }
8874        };
8875
8876        try {
8877            who.linkToDeath(death, 0);
8878        } catch (RemoteException e) {
8879            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8880            return;
8881        }
8882
8883        synchronized (this) {
8884            Watchdog.getInstance().setAllowRestart(allowRestart);
8885            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8886            synchronized (death) {
8887                while (who.isBinderAlive()) {
8888                    try {
8889                        death.wait();
8890                    } catch (InterruptedException e) {
8891                    }
8892                }
8893            }
8894            Watchdog.getInstance().setAllowRestart(true);
8895        }
8896    }
8897
8898    @Override
8899    public void restart() {
8900        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8901                != PackageManager.PERMISSION_GRANTED) {
8902            throw new SecurityException("Requires permission "
8903                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8904        }
8905
8906        Log.i(TAG, "Sending shutdown broadcast...");
8907
8908        BroadcastReceiver br = new BroadcastReceiver() {
8909            @Override public void onReceive(Context context, Intent intent) {
8910                // Now the broadcast is done, finish up the low-level shutdown.
8911                Log.i(TAG, "Shutting down activity manager...");
8912                shutdown(10000);
8913                Log.i(TAG, "Shutdown complete, restarting!");
8914                Process.killProcess(Process.myPid());
8915                System.exit(10);
8916            }
8917        };
8918
8919        // First send the high-level shut down broadcast.
8920        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8921        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8922        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8923        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8924        mContext.sendOrderedBroadcastAsUser(intent,
8925                UserHandle.ALL, null, br, mHandler, 0, null, null);
8926        */
8927        br.onReceive(mContext, intent);
8928    }
8929
8930    private long getLowRamTimeSinceIdle(long now) {
8931        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8932    }
8933
8934    @Override
8935    public void performIdleMaintenance() {
8936        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8937                != PackageManager.PERMISSION_GRANTED) {
8938            throw new SecurityException("Requires permission "
8939                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8940        }
8941
8942        synchronized (this) {
8943            final long now = SystemClock.uptimeMillis();
8944            final long timeSinceLastIdle = now - mLastIdleTime;
8945            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8946            mLastIdleTime = now;
8947            mLowRamTimeSinceLastIdle = 0;
8948            if (mLowRamStartTime != 0) {
8949                mLowRamStartTime = now;
8950            }
8951
8952            StringBuilder sb = new StringBuilder(128);
8953            sb.append("Idle maintenance over ");
8954            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8955            sb.append(" low RAM for ");
8956            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8957            Slog.i(TAG, sb.toString());
8958
8959            // If at least 1/3 of our time since the last idle period has been spent
8960            // with RAM low, then we want to kill processes.
8961            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8962
8963            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8964                ProcessRecord proc = mLruProcesses.get(i);
8965                if (proc.notCachedSinceIdle) {
8966                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8967                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8968                        if (doKilling && proc.initialIdlePss != 0
8969                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8970                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8971                                    + " from " + proc.initialIdlePss + ")");
8972                        }
8973                    }
8974                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8975                    proc.notCachedSinceIdle = true;
8976                    proc.initialIdlePss = 0;
8977                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8978                            mSleeping, now);
8979                }
8980            }
8981
8982            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8983            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8984        }
8985    }
8986
8987    private void retrieveSettings() {
8988        final ContentResolver resolver = mContext.getContentResolver();
8989        String debugApp = Settings.Global.getString(
8990            resolver, Settings.Global.DEBUG_APP);
8991        boolean waitForDebugger = Settings.Global.getInt(
8992            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
8993        boolean alwaysFinishActivities = Settings.Global.getInt(
8994            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
8995        boolean forceRtl = Settings.Global.getInt(
8996                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
8997        // Transfer any global setting for forcing RTL layout, into a System Property
8998        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
8999
9000        Configuration configuration = new Configuration();
9001        Settings.System.getConfiguration(resolver, configuration);
9002        if (forceRtl) {
9003            // This will take care of setting the correct layout direction flags
9004            configuration.setLayoutDirection(configuration.locale);
9005        }
9006
9007        synchronized (this) {
9008            mDebugApp = mOrigDebugApp = debugApp;
9009            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9010            mAlwaysFinishActivities = alwaysFinishActivities;
9011            // This happens before any activities are started, so we can
9012            // change mConfiguration in-place.
9013            updateConfigurationLocked(configuration, null, false, true);
9014            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9015        }
9016    }
9017
9018    public boolean testIsSystemReady() {
9019        // no need to synchronize(this) just to read & return the value
9020        return mSystemReady;
9021    }
9022
9023    private static File getCalledPreBootReceiversFile() {
9024        File dataDir = Environment.getDataDirectory();
9025        File systemDir = new File(dataDir, "system");
9026        File fname = new File(systemDir, "called_pre_boots.dat");
9027        return fname;
9028    }
9029
9030    static final int LAST_DONE_VERSION = 10000;
9031
9032    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9033        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9034        File file = getCalledPreBootReceiversFile();
9035        FileInputStream fis = null;
9036        try {
9037            fis = new FileInputStream(file);
9038            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9039            int fvers = dis.readInt();
9040            if (fvers == LAST_DONE_VERSION) {
9041                String vers = dis.readUTF();
9042                String codename = dis.readUTF();
9043                String build = dis.readUTF();
9044                if (android.os.Build.VERSION.RELEASE.equals(vers)
9045                        && android.os.Build.VERSION.CODENAME.equals(codename)
9046                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9047                    int num = dis.readInt();
9048                    while (num > 0) {
9049                        num--;
9050                        String pkg = dis.readUTF();
9051                        String cls = dis.readUTF();
9052                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9053                    }
9054                }
9055            }
9056        } catch (FileNotFoundException e) {
9057        } catch (IOException e) {
9058            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9059        } finally {
9060            if (fis != null) {
9061                try {
9062                    fis.close();
9063                } catch (IOException e) {
9064                }
9065            }
9066        }
9067        return lastDoneReceivers;
9068    }
9069
9070    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9071        File file = getCalledPreBootReceiversFile();
9072        FileOutputStream fos = null;
9073        DataOutputStream dos = null;
9074        try {
9075            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9076            fos = new FileOutputStream(file);
9077            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9078            dos.writeInt(LAST_DONE_VERSION);
9079            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9080            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9081            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9082            dos.writeInt(list.size());
9083            for (int i=0; i<list.size(); i++) {
9084                dos.writeUTF(list.get(i).getPackageName());
9085                dos.writeUTF(list.get(i).getClassName());
9086            }
9087        } catch (IOException e) {
9088            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9089            file.delete();
9090        } finally {
9091            FileUtils.sync(fos);
9092            if (dos != null) {
9093                try {
9094                    dos.close();
9095                } catch (IOException e) {
9096                    // TODO Auto-generated catch block
9097                    e.printStackTrace();
9098                }
9099            }
9100        }
9101    }
9102
9103    public void systemReady(final Runnable goingCallback) {
9104        synchronized(this) {
9105            if (mSystemReady) {
9106                if (goingCallback != null) goingCallback.run();
9107                return;
9108            }
9109
9110            // Check to see if there are any update receivers to run.
9111            if (!mDidUpdate) {
9112                if (mWaitingUpdate) {
9113                    return;
9114                }
9115                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9116                List<ResolveInfo> ris = null;
9117                try {
9118                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9119                            intent, null, 0, 0);
9120                } catch (RemoteException e) {
9121                }
9122                if (ris != null) {
9123                    for (int i=ris.size()-1; i>=0; i--) {
9124                        if ((ris.get(i).activityInfo.applicationInfo.flags
9125                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9126                            ris.remove(i);
9127                        }
9128                    }
9129                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9130
9131                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9132
9133                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9134                    for (int i=0; i<ris.size(); i++) {
9135                        ActivityInfo ai = ris.get(i).activityInfo;
9136                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9137                        if (lastDoneReceivers.contains(comp)) {
9138                            // We already did the pre boot receiver for this app with the current
9139                            // platform version, so don't do it again...
9140                            ris.remove(i);
9141                            i--;
9142                            // ...however, do keep it as one that has been done, so we don't
9143                            // forget about it when rewriting the file of last done receivers.
9144                            doneReceivers.add(comp);
9145                        }
9146                    }
9147
9148                    final int[] users = getUsersLocked();
9149                    for (int i=0; i<ris.size(); i++) {
9150                        ActivityInfo ai = ris.get(i).activityInfo;
9151                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9152                        doneReceivers.add(comp);
9153                        intent.setComponent(comp);
9154                        for (int j=0; j<users.length; j++) {
9155                            IIntentReceiver finisher = null;
9156                            if (i == ris.size()-1 && j == users.length-1) {
9157                                finisher = new IIntentReceiver.Stub() {
9158                                    public void performReceive(Intent intent, int resultCode,
9159                                            String data, Bundle extras, boolean ordered,
9160                                            boolean sticky, int sendingUser) {
9161                                        // The raw IIntentReceiver interface is called
9162                                        // with the AM lock held, so redispatch to
9163                                        // execute our code without the lock.
9164                                        mHandler.post(new Runnable() {
9165                                            public void run() {
9166                                                synchronized (ActivityManagerService.this) {
9167                                                    mDidUpdate = true;
9168                                                }
9169                                                writeLastDonePreBootReceivers(doneReceivers);
9170                                                showBootMessage(mContext.getText(
9171                                                        R.string.android_upgrading_complete),
9172                                                        false);
9173                                                systemReady(goingCallback);
9174                                            }
9175                                        });
9176                                    }
9177                                };
9178                            }
9179                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9180                                    + " for user " + users[j]);
9181                            broadcastIntentLocked(null, null, intent, null, finisher,
9182                                    0, null, null, null, AppOpsManager.OP_NONE,
9183                                    true, false, MY_PID, Process.SYSTEM_UID,
9184                                    users[j]);
9185                            if (finisher != null) {
9186                                mWaitingUpdate = true;
9187                            }
9188                        }
9189                    }
9190                }
9191                if (mWaitingUpdate) {
9192                    return;
9193                }
9194                mDidUpdate = true;
9195            }
9196
9197            mAppOpsService.systemReady();
9198            mSystemReady = true;
9199        }
9200
9201        ArrayList<ProcessRecord> procsToKill = null;
9202        synchronized(mPidsSelfLocked) {
9203            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9204                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9205                if (!isAllowedWhileBooting(proc.info)){
9206                    if (procsToKill == null) {
9207                        procsToKill = new ArrayList<ProcessRecord>();
9208                    }
9209                    procsToKill.add(proc);
9210                }
9211            }
9212        }
9213
9214        synchronized(this) {
9215            if (procsToKill != null) {
9216                for (int i=procsToKill.size()-1; i>=0; i--) {
9217                    ProcessRecord proc = procsToKill.get(i);
9218                    Slog.i(TAG, "Removing system update proc: " + proc);
9219                    removeProcessLocked(proc, true, false, "system update done");
9220                }
9221            }
9222
9223            // Now that we have cleaned up any update processes, we
9224            // are ready to start launching real processes and know that
9225            // we won't trample on them any more.
9226            mProcessesReady = true;
9227        }
9228
9229        Slog.i(TAG, "System now ready");
9230        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9231            SystemClock.uptimeMillis());
9232
9233        synchronized(this) {
9234            // Make sure we have no pre-ready processes sitting around.
9235
9236            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9237                ResolveInfo ri = mContext.getPackageManager()
9238                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9239                                STOCK_PM_FLAGS);
9240                CharSequence errorMsg = null;
9241                if (ri != null) {
9242                    ActivityInfo ai = ri.activityInfo;
9243                    ApplicationInfo app = ai.applicationInfo;
9244                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9245                        mTopAction = Intent.ACTION_FACTORY_TEST;
9246                        mTopData = null;
9247                        mTopComponent = new ComponentName(app.packageName,
9248                                ai.name);
9249                    } else {
9250                        errorMsg = mContext.getResources().getText(
9251                                com.android.internal.R.string.factorytest_not_system);
9252                    }
9253                } else {
9254                    errorMsg = mContext.getResources().getText(
9255                            com.android.internal.R.string.factorytest_no_action);
9256                }
9257                if (errorMsg != null) {
9258                    mTopAction = null;
9259                    mTopData = null;
9260                    mTopComponent = null;
9261                    Message msg = Message.obtain();
9262                    msg.what = SHOW_FACTORY_ERROR_MSG;
9263                    msg.getData().putCharSequence("msg", errorMsg);
9264                    mHandler.sendMessage(msg);
9265                }
9266            }
9267        }
9268
9269        retrieveSettings();
9270
9271        synchronized (this) {
9272            readGrantedUriPermissionsLocked();
9273        }
9274
9275        if (goingCallback != null) goingCallback.run();
9276
9277        synchronized (this) {
9278            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9279                try {
9280                    List apps = AppGlobals.getPackageManager().
9281                        getPersistentApplications(STOCK_PM_FLAGS);
9282                    if (apps != null) {
9283                        int N = apps.size();
9284                        int i;
9285                        for (i=0; i<N; i++) {
9286                            ApplicationInfo info
9287                                = (ApplicationInfo)apps.get(i);
9288                            if (info != null &&
9289                                    !info.packageName.equals("android")) {
9290                                addAppLocked(info, false);
9291                            }
9292                        }
9293                    }
9294                } catch (RemoteException ex) {
9295                    // pm is in same process, this will never happen.
9296                }
9297            }
9298
9299            // Start up initial activity.
9300            mBooting = true;
9301
9302            try {
9303                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9304                    Message msg = Message.obtain();
9305                    msg.what = SHOW_UID_ERROR_MSG;
9306                    mHandler.sendMessage(msg);
9307                }
9308            } catch (RemoteException e) {
9309            }
9310
9311            long ident = Binder.clearCallingIdentity();
9312            try {
9313                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9314                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9315                        | Intent.FLAG_RECEIVER_FOREGROUND);
9316                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9317                broadcastIntentLocked(null, null, intent,
9318                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9319                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9320                intent = new Intent(Intent.ACTION_USER_STARTING);
9321                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9322                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9323                broadcastIntentLocked(null, null, intent,
9324                        null, new IIntentReceiver.Stub() {
9325                            @Override
9326                            public void performReceive(Intent intent, int resultCode, String data,
9327                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9328                                    throws RemoteException {
9329                            }
9330                        }, 0, null, null,
9331                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9332                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9333            } finally {
9334                Binder.restoreCallingIdentity(ident);
9335            }
9336            mStackSupervisor.resumeTopActivitiesLocked();
9337            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9338        }
9339    }
9340
9341    private boolean makeAppCrashingLocked(ProcessRecord app,
9342            String shortMsg, String longMsg, String stackTrace) {
9343        app.crashing = true;
9344        app.crashingReport = generateProcessError(app,
9345                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9346        startAppProblemLocked(app);
9347        app.stopFreezingAllLocked();
9348        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9349    }
9350
9351    private void makeAppNotRespondingLocked(ProcessRecord app,
9352            String activity, String shortMsg, String longMsg) {
9353        app.notResponding = true;
9354        app.notRespondingReport = generateProcessError(app,
9355                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9356                activity, shortMsg, longMsg, null);
9357        startAppProblemLocked(app);
9358        app.stopFreezingAllLocked();
9359    }
9360
9361    /**
9362     * Generate a process error record, suitable for attachment to a ProcessRecord.
9363     *
9364     * @param app The ProcessRecord in which the error occurred.
9365     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9366     *                      ActivityManager.AppErrorStateInfo
9367     * @param activity The activity associated with the crash, if known.
9368     * @param shortMsg Short message describing the crash.
9369     * @param longMsg Long message describing the crash.
9370     * @param stackTrace Full crash stack trace, may be null.
9371     *
9372     * @return Returns a fully-formed AppErrorStateInfo record.
9373     */
9374    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9375            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9376        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9377
9378        report.condition = condition;
9379        report.processName = app.processName;
9380        report.pid = app.pid;
9381        report.uid = app.info.uid;
9382        report.tag = activity;
9383        report.shortMsg = shortMsg;
9384        report.longMsg = longMsg;
9385        report.stackTrace = stackTrace;
9386
9387        return report;
9388    }
9389
9390    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9391        synchronized (this) {
9392            app.crashing = false;
9393            app.crashingReport = null;
9394            app.notResponding = false;
9395            app.notRespondingReport = null;
9396            if (app.anrDialog == fromDialog) {
9397                app.anrDialog = null;
9398            }
9399            if (app.waitDialog == fromDialog) {
9400                app.waitDialog = null;
9401            }
9402            if (app.pid > 0 && app.pid != MY_PID) {
9403                handleAppCrashLocked(app, null, null, null);
9404                killUnneededProcessLocked(app, "user request after error");
9405            }
9406        }
9407    }
9408
9409    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9410            String stackTrace) {
9411        long now = SystemClock.uptimeMillis();
9412
9413        Long crashTime;
9414        if (!app.isolated) {
9415            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9416        } else {
9417            crashTime = null;
9418        }
9419        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9420            // This process loses!
9421            Slog.w(TAG, "Process " + app.info.processName
9422                    + " has crashed too many times: killing!");
9423            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9424                    app.userId, app.info.processName, app.uid);
9425            mStackSupervisor.handleAppCrashLocked(app);
9426            if (!app.persistent) {
9427                // We don't want to start this process again until the user
9428                // explicitly does so...  but for persistent process, we really
9429                // need to keep it running.  If a persistent process is actually
9430                // repeatedly crashing, then badness for everyone.
9431                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9432                        app.info.processName);
9433                if (!app.isolated) {
9434                    // XXX We don't have a way to mark isolated processes
9435                    // as bad, since they don't have a peristent identity.
9436                    mBadProcesses.put(app.info.processName, app.uid,
9437                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9438                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9439                }
9440                app.bad = true;
9441                app.removed = true;
9442                // Don't let services in this process be restarted and potentially
9443                // annoy the user repeatedly.  Unless it is persistent, since those
9444                // processes run critical code.
9445                removeProcessLocked(app, false, false, "crash");
9446                mStackSupervisor.resumeTopActivitiesLocked();
9447                return false;
9448            }
9449            mStackSupervisor.resumeTopActivitiesLocked();
9450        } else {
9451            mStackSupervisor.finishTopRunningActivityLocked(app);
9452        }
9453
9454        // Bump up the crash count of any services currently running in the proc.
9455        for (int i=app.services.size()-1; i>=0; i--) {
9456            // Any services running in the application need to be placed
9457            // back in the pending list.
9458            ServiceRecord sr = app.services.valueAt(i);
9459            sr.crashCount++;
9460        }
9461
9462        // If the crashing process is what we consider to be the "home process" and it has been
9463        // replaced by a third-party app, clear the package preferred activities from packages
9464        // with a home activity running in the process to prevent a repeatedly crashing app
9465        // from blocking the user to manually clear the list.
9466        final ArrayList<ActivityRecord> activities = app.activities;
9467        if (app == mHomeProcess && activities.size() > 0
9468                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9469            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9470                final ActivityRecord r = activities.get(activityNdx);
9471                if (r.isHomeActivity()) {
9472                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9473                    try {
9474                        ActivityThread.getPackageManager()
9475                                .clearPackagePreferredActivities(r.packageName);
9476                    } catch (RemoteException c) {
9477                        // pm is in same process, this will never happen.
9478                    }
9479                }
9480            }
9481        }
9482
9483        if (!app.isolated) {
9484            // XXX Can't keep track of crash times for isolated processes,
9485            // because they don't have a perisistent identity.
9486            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9487        }
9488
9489        return true;
9490    }
9491
9492    void startAppProblemLocked(ProcessRecord app) {
9493        if (app.userId == mCurrentUserId) {
9494            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9495                    mContext, app.info.packageName, app.info.flags);
9496        } else {
9497            // If this app is not running under the current user, then we
9498            // can't give it a report button because that would require
9499            // launching the report UI under a different user.
9500            app.errorReportReceiver = null;
9501        }
9502        skipCurrentReceiverLocked(app);
9503    }
9504
9505    void skipCurrentReceiverLocked(ProcessRecord app) {
9506        for (BroadcastQueue queue : mBroadcastQueues) {
9507            queue.skipCurrentReceiverLocked(app);
9508        }
9509    }
9510
9511    /**
9512     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9513     * The application process will exit immediately after this call returns.
9514     * @param app object of the crashing app, null for the system server
9515     * @param crashInfo describing the exception
9516     */
9517    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9518        ProcessRecord r = findAppProcess(app, "Crash");
9519        final String processName = app == null ? "system_server"
9520                : (r == null ? "unknown" : r.processName);
9521
9522        handleApplicationCrashInner("crash", r, processName, crashInfo);
9523    }
9524
9525    /* Native crash reporting uses this inner version because it needs to be somewhat
9526     * decoupled from the AM-managed cleanup lifecycle
9527     */
9528    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9529            ApplicationErrorReport.CrashInfo crashInfo) {
9530        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9531                UserHandle.getUserId(Binder.getCallingUid()), processName,
9532                r == null ? -1 : r.info.flags,
9533                crashInfo.exceptionClassName,
9534                crashInfo.exceptionMessage,
9535                crashInfo.throwFileName,
9536                crashInfo.throwLineNumber);
9537
9538        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9539
9540        crashApplication(r, crashInfo);
9541    }
9542
9543    public void handleApplicationStrictModeViolation(
9544            IBinder app,
9545            int violationMask,
9546            StrictMode.ViolationInfo info) {
9547        ProcessRecord r = findAppProcess(app, "StrictMode");
9548        if (r == null) {
9549            return;
9550        }
9551
9552        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9553            Integer stackFingerprint = info.hashCode();
9554            boolean logIt = true;
9555            synchronized (mAlreadyLoggedViolatedStacks) {
9556                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9557                    logIt = false;
9558                    // TODO: sub-sample into EventLog for these, with
9559                    // the info.durationMillis?  Then we'd get
9560                    // the relative pain numbers, without logging all
9561                    // the stack traces repeatedly.  We'd want to do
9562                    // likewise in the client code, which also does
9563                    // dup suppression, before the Binder call.
9564                } else {
9565                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9566                        mAlreadyLoggedViolatedStacks.clear();
9567                    }
9568                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9569                }
9570            }
9571            if (logIt) {
9572                logStrictModeViolationToDropBox(r, info);
9573            }
9574        }
9575
9576        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9577            AppErrorResult result = new AppErrorResult();
9578            synchronized (this) {
9579                final long origId = Binder.clearCallingIdentity();
9580
9581                Message msg = Message.obtain();
9582                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9583                HashMap<String, Object> data = new HashMap<String, Object>();
9584                data.put("result", result);
9585                data.put("app", r);
9586                data.put("violationMask", violationMask);
9587                data.put("info", info);
9588                msg.obj = data;
9589                mHandler.sendMessage(msg);
9590
9591                Binder.restoreCallingIdentity(origId);
9592            }
9593            int res = result.get();
9594            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9595        }
9596    }
9597
9598    // Depending on the policy in effect, there could be a bunch of
9599    // these in quick succession so we try to batch these together to
9600    // minimize disk writes, number of dropbox entries, and maximize
9601    // compression, by having more fewer, larger records.
9602    private void logStrictModeViolationToDropBox(
9603            ProcessRecord process,
9604            StrictMode.ViolationInfo info) {
9605        if (info == null) {
9606            return;
9607        }
9608        final boolean isSystemApp = process == null ||
9609                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9610                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9611        final String processName = process == null ? "unknown" : process.processName;
9612        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9613        final DropBoxManager dbox = (DropBoxManager)
9614                mContext.getSystemService(Context.DROPBOX_SERVICE);
9615
9616        // Exit early if the dropbox isn't configured to accept this report type.
9617        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9618
9619        boolean bufferWasEmpty;
9620        boolean needsFlush;
9621        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9622        synchronized (sb) {
9623            bufferWasEmpty = sb.length() == 0;
9624            appendDropBoxProcessHeaders(process, processName, sb);
9625            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9626            sb.append("System-App: ").append(isSystemApp).append("\n");
9627            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9628            if (info.violationNumThisLoop != 0) {
9629                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9630            }
9631            if (info.numAnimationsRunning != 0) {
9632                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9633            }
9634            if (info.broadcastIntentAction != null) {
9635                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9636            }
9637            if (info.durationMillis != -1) {
9638                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9639            }
9640            if (info.numInstances != -1) {
9641                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9642            }
9643            if (info.tags != null) {
9644                for (String tag : info.tags) {
9645                    sb.append("Span-Tag: ").append(tag).append("\n");
9646                }
9647            }
9648            sb.append("\n");
9649            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9650                sb.append(info.crashInfo.stackTrace);
9651            }
9652            sb.append("\n");
9653
9654            // Only buffer up to ~64k.  Various logging bits truncate
9655            // things at 128k.
9656            needsFlush = (sb.length() > 64 * 1024);
9657        }
9658
9659        // Flush immediately if the buffer's grown too large, or this
9660        // is a non-system app.  Non-system apps are isolated with a
9661        // different tag & policy and not batched.
9662        //
9663        // Batching is useful during internal testing with
9664        // StrictMode settings turned up high.  Without batching,
9665        // thousands of separate files could be created on boot.
9666        if (!isSystemApp || needsFlush) {
9667            new Thread("Error dump: " + dropboxTag) {
9668                @Override
9669                public void run() {
9670                    String report;
9671                    synchronized (sb) {
9672                        report = sb.toString();
9673                        sb.delete(0, sb.length());
9674                        sb.trimToSize();
9675                    }
9676                    if (report.length() != 0) {
9677                        dbox.addText(dropboxTag, report);
9678                    }
9679                }
9680            }.start();
9681            return;
9682        }
9683
9684        // System app batching:
9685        if (!bufferWasEmpty) {
9686            // An existing dropbox-writing thread is outstanding, so
9687            // we don't need to start it up.  The existing thread will
9688            // catch the buffer appends we just did.
9689            return;
9690        }
9691
9692        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9693        // (After this point, we shouldn't access AMS internal data structures.)
9694        new Thread("Error dump: " + dropboxTag) {
9695            @Override
9696            public void run() {
9697                // 5 second sleep to let stacks arrive and be batched together
9698                try {
9699                    Thread.sleep(5000);  // 5 seconds
9700                } catch (InterruptedException e) {}
9701
9702                String errorReport;
9703                synchronized (mStrictModeBuffer) {
9704                    errorReport = mStrictModeBuffer.toString();
9705                    if (errorReport.length() == 0) {
9706                        return;
9707                    }
9708                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9709                    mStrictModeBuffer.trimToSize();
9710                }
9711                dbox.addText(dropboxTag, errorReport);
9712            }
9713        }.start();
9714    }
9715
9716    /**
9717     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9718     * @param app object of the crashing app, null for the system server
9719     * @param tag reported by the caller
9720     * @param crashInfo describing the context of the error
9721     * @return true if the process should exit immediately (WTF is fatal)
9722     */
9723    public boolean handleApplicationWtf(IBinder app, String tag,
9724            ApplicationErrorReport.CrashInfo crashInfo) {
9725        ProcessRecord r = findAppProcess(app, "WTF");
9726        final String processName = app == null ? "system_server"
9727                : (r == null ? "unknown" : r.processName);
9728
9729        EventLog.writeEvent(EventLogTags.AM_WTF,
9730                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9731                processName,
9732                r == null ? -1 : r.info.flags,
9733                tag, crashInfo.exceptionMessage);
9734
9735        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9736
9737        if (r != null && r.pid != Process.myPid() &&
9738                Settings.Global.getInt(mContext.getContentResolver(),
9739                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9740            crashApplication(r, crashInfo);
9741            return true;
9742        } else {
9743            return false;
9744        }
9745    }
9746
9747    /**
9748     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9749     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9750     */
9751    private ProcessRecord findAppProcess(IBinder app, String reason) {
9752        if (app == null) {
9753            return null;
9754        }
9755
9756        synchronized (this) {
9757            final int NP = mProcessNames.getMap().size();
9758            for (int ip=0; ip<NP; ip++) {
9759                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9760                final int NA = apps.size();
9761                for (int ia=0; ia<NA; ia++) {
9762                    ProcessRecord p = apps.valueAt(ia);
9763                    if (p.thread != null && p.thread.asBinder() == app) {
9764                        return p;
9765                    }
9766                }
9767            }
9768
9769            Slog.w(TAG, "Can't find mystery application for " + reason
9770                    + " from pid=" + Binder.getCallingPid()
9771                    + " uid=" + Binder.getCallingUid() + ": " + app);
9772            return null;
9773        }
9774    }
9775
9776    /**
9777     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9778     * to append various headers to the dropbox log text.
9779     */
9780    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9781            StringBuilder sb) {
9782        // Watchdog thread ends up invoking this function (with
9783        // a null ProcessRecord) to add the stack file to dropbox.
9784        // Do not acquire a lock on this (am) in such cases, as it
9785        // could cause a potential deadlock, if and when watchdog
9786        // is invoked due to unavailability of lock on am and it
9787        // would prevent watchdog from killing system_server.
9788        if (process == null) {
9789            sb.append("Process: ").append(processName).append("\n");
9790            return;
9791        }
9792        // Note: ProcessRecord 'process' is guarded by the service
9793        // instance.  (notably process.pkgList, which could otherwise change
9794        // concurrently during execution of this method)
9795        synchronized (this) {
9796            sb.append("Process: ").append(processName).append("\n");
9797            int flags = process.info.flags;
9798            IPackageManager pm = AppGlobals.getPackageManager();
9799            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9800            for (int ip=0; ip<process.pkgList.size(); ip++) {
9801                String pkg = process.pkgList.keyAt(ip);
9802                sb.append("Package: ").append(pkg);
9803                try {
9804                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9805                    if (pi != null) {
9806                        sb.append(" v").append(pi.versionCode);
9807                        if (pi.versionName != null) {
9808                            sb.append(" (").append(pi.versionName).append(")");
9809                        }
9810                    }
9811                } catch (RemoteException e) {
9812                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9813                }
9814                sb.append("\n");
9815            }
9816        }
9817    }
9818
9819    private static String processClass(ProcessRecord process) {
9820        if (process == null || process.pid == MY_PID) {
9821            return "system_server";
9822        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9823            return "system_app";
9824        } else {
9825            return "data_app";
9826        }
9827    }
9828
9829    /**
9830     * Write a description of an error (crash, WTF, ANR) to the drop box.
9831     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9832     * @param process which caused the error, null means the system server
9833     * @param activity which triggered the error, null if unknown
9834     * @param parent activity related to the error, null if unknown
9835     * @param subject line related to the error, null if absent
9836     * @param report in long form describing the error, null if absent
9837     * @param logFile to include in the report, null if none
9838     * @param crashInfo giving an application stack trace, null if absent
9839     */
9840    public void addErrorToDropBox(String eventType,
9841            ProcessRecord process, String processName, ActivityRecord activity,
9842            ActivityRecord parent, String subject,
9843            final String report, final File logFile,
9844            final ApplicationErrorReport.CrashInfo crashInfo) {
9845        // NOTE -- this must never acquire the ActivityManagerService lock,
9846        // otherwise the watchdog may be prevented from resetting the system.
9847
9848        final String dropboxTag = processClass(process) + "_" + eventType;
9849        final DropBoxManager dbox = (DropBoxManager)
9850                mContext.getSystemService(Context.DROPBOX_SERVICE);
9851
9852        // Exit early if the dropbox isn't configured to accept this report type.
9853        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9854
9855        final StringBuilder sb = new StringBuilder(1024);
9856        appendDropBoxProcessHeaders(process, processName, sb);
9857        if (activity != null) {
9858            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9859        }
9860        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9861            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9862        }
9863        if (parent != null && parent != activity) {
9864            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9865        }
9866        if (subject != null) {
9867            sb.append("Subject: ").append(subject).append("\n");
9868        }
9869        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9870        if (Debug.isDebuggerConnected()) {
9871            sb.append("Debugger: Connected\n");
9872        }
9873        sb.append("\n");
9874
9875        // Do the rest in a worker thread to avoid blocking the caller on I/O
9876        // (After this point, we shouldn't access AMS internal data structures.)
9877        Thread worker = new Thread("Error dump: " + dropboxTag) {
9878            @Override
9879            public void run() {
9880                if (report != null) {
9881                    sb.append(report);
9882                }
9883                if (logFile != null) {
9884                    try {
9885                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9886                                    "\n\n[[TRUNCATED]]"));
9887                    } catch (IOException e) {
9888                        Slog.e(TAG, "Error reading " + logFile, e);
9889                    }
9890                }
9891                if (crashInfo != null && crashInfo.stackTrace != null) {
9892                    sb.append(crashInfo.stackTrace);
9893                }
9894
9895                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9896                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9897                if (lines > 0) {
9898                    sb.append("\n");
9899
9900                    // Merge several logcat streams, and take the last N lines
9901                    InputStreamReader input = null;
9902                    try {
9903                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9904                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9905                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9906
9907                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9908                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9909                        input = new InputStreamReader(logcat.getInputStream());
9910
9911                        int num;
9912                        char[] buf = new char[8192];
9913                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9914                    } catch (IOException e) {
9915                        Slog.e(TAG, "Error running logcat", e);
9916                    } finally {
9917                        if (input != null) try { input.close(); } catch (IOException e) {}
9918                    }
9919                }
9920
9921                dbox.addText(dropboxTag, sb.toString());
9922            }
9923        };
9924
9925        if (process == null) {
9926            // If process is null, we are being called from some internal code
9927            // and may be about to die -- run this synchronously.
9928            worker.run();
9929        } else {
9930            worker.start();
9931        }
9932    }
9933
9934    /**
9935     * Bring up the "unexpected error" dialog box for a crashing app.
9936     * Deal with edge cases (intercepts from instrumented applications,
9937     * ActivityController, error intent receivers, that sort of thing).
9938     * @param r the application crashing
9939     * @param crashInfo describing the failure
9940     */
9941    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9942        long timeMillis = System.currentTimeMillis();
9943        String shortMsg = crashInfo.exceptionClassName;
9944        String longMsg = crashInfo.exceptionMessage;
9945        String stackTrace = crashInfo.stackTrace;
9946        if (shortMsg != null && longMsg != null) {
9947            longMsg = shortMsg + ": " + longMsg;
9948        } else if (shortMsg != null) {
9949            longMsg = shortMsg;
9950        }
9951
9952        AppErrorResult result = new AppErrorResult();
9953        synchronized (this) {
9954            if (mController != null) {
9955                try {
9956                    String name = r != null ? r.processName : null;
9957                    int pid = r != null ? r.pid : Binder.getCallingPid();
9958                    if (!mController.appCrashed(name, pid,
9959                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9960                        Slog.w(TAG, "Force-killing crashed app " + name
9961                                + " at watcher's request");
9962                        Process.killProcess(pid);
9963                        return;
9964                    }
9965                } catch (RemoteException e) {
9966                    mController = null;
9967                    Watchdog.getInstance().setActivityController(null);
9968                }
9969            }
9970
9971            final long origId = Binder.clearCallingIdentity();
9972
9973            // If this process is running instrumentation, finish it.
9974            if (r != null && r.instrumentationClass != null) {
9975                Slog.w(TAG, "Error in app " + r.processName
9976                      + " running instrumentation " + r.instrumentationClass + ":");
9977                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
9978                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
9979                Bundle info = new Bundle();
9980                info.putString("shortMsg", shortMsg);
9981                info.putString("longMsg", longMsg);
9982                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
9983                Binder.restoreCallingIdentity(origId);
9984                return;
9985            }
9986
9987            // If we can't identify the process or it's already exceeded its crash quota,
9988            // quit right away without showing a crash dialog.
9989            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
9990                Binder.restoreCallingIdentity(origId);
9991                return;
9992            }
9993
9994            Message msg = Message.obtain();
9995            msg.what = SHOW_ERROR_MSG;
9996            HashMap data = new HashMap();
9997            data.put("result", result);
9998            data.put("app", r);
9999            msg.obj = data;
10000            mHandler.sendMessage(msg);
10001
10002            Binder.restoreCallingIdentity(origId);
10003        }
10004
10005        int res = result.get();
10006
10007        Intent appErrorIntent = null;
10008        synchronized (this) {
10009            if (r != null && !r.isolated) {
10010                // XXX Can't keep track of crash time for isolated processes,
10011                // since they don't have a persistent identity.
10012                mProcessCrashTimes.put(r.info.processName, r.uid,
10013                        SystemClock.uptimeMillis());
10014            }
10015            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10016                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10017            }
10018        }
10019
10020        if (appErrorIntent != null) {
10021            try {
10022                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10023            } catch (ActivityNotFoundException e) {
10024                Slog.w(TAG, "bug report receiver dissappeared", e);
10025            }
10026        }
10027    }
10028
10029    Intent createAppErrorIntentLocked(ProcessRecord r,
10030            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10031        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10032        if (report == null) {
10033            return null;
10034        }
10035        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10036        result.setComponent(r.errorReportReceiver);
10037        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10038        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10039        return result;
10040    }
10041
10042    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10043            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10044        if (r.errorReportReceiver == null) {
10045            return null;
10046        }
10047
10048        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10049            return null;
10050        }
10051
10052        ApplicationErrorReport report = new ApplicationErrorReport();
10053        report.packageName = r.info.packageName;
10054        report.installerPackageName = r.errorReportReceiver.getPackageName();
10055        report.processName = r.processName;
10056        report.time = timeMillis;
10057        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10058
10059        if (r.crashing || r.forceCrashReport) {
10060            report.type = ApplicationErrorReport.TYPE_CRASH;
10061            report.crashInfo = crashInfo;
10062        } else if (r.notResponding) {
10063            report.type = ApplicationErrorReport.TYPE_ANR;
10064            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10065
10066            report.anrInfo.activity = r.notRespondingReport.tag;
10067            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10068            report.anrInfo.info = r.notRespondingReport.longMsg;
10069        }
10070
10071        return report;
10072    }
10073
10074    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10075        enforceNotIsolatedCaller("getProcessesInErrorState");
10076        // assume our apps are happy - lazy create the list
10077        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10078
10079        final boolean allUsers = ActivityManager.checkUidPermission(
10080                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10081                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10082        int userId = UserHandle.getUserId(Binder.getCallingUid());
10083
10084        synchronized (this) {
10085
10086            // iterate across all processes
10087            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10088                ProcessRecord app = mLruProcesses.get(i);
10089                if (!allUsers && app.userId != userId) {
10090                    continue;
10091                }
10092                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10093                    // This one's in trouble, so we'll generate a report for it
10094                    // crashes are higher priority (in case there's a crash *and* an anr)
10095                    ActivityManager.ProcessErrorStateInfo report = null;
10096                    if (app.crashing) {
10097                        report = app.crashingReport;
10098                    } else if (app.notResponding) {
10099                        report = app.notRespondingReport;
10100                    }
10101
10102                    if (report != null) {
10103                        if (errList == null) {
10104                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10105                        }
10106                        errList.add(report);
10107                    } else {
10108                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10109                                " crashing = " + app.crashing +
10110                                " notResponding = " + app.notResponding);
10111                    }
10112                }
10113            }
10114        }
10115
10116        return errList;
10117    }
10118
10119    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10120        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10121            if (currApp != null) {
10122                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10123            }
10124            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10125        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10126            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10127        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10128            if (currApp != null) {
10129                currApp.lru = 0;
10130            }
10131            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10132        } else if (adj >= ProcessList.SERVICE_ADJ) {
10133            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10134        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10135            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10136        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10137            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10138        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10139            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10140        } else {
10141            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10142        }
10143    }
10144
10145    private void fillInProcMemInfo(ProcessRecord app,
10146            ActivityManager.RunningAppProcessInfo outInfo) {
10147        outInfo.pid = app.pid;
10148        outInfo.uid = app.info.uid;
10149        if (mHeavyWeightProcess == app) {
10150            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10151        }
10152        if (app.persistent) {
10153            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10154        }
10155        if (app.activities.size() > 0) {
10156            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10157        }
10158        outInfo.lastTrimLevel = app.trimMemoryLevel;
10159        int adj = app.curAdj;
10160        outInfo.importance = oomAdjToImportance(adj, outInfo);
10161        outInfo.importanceReasonCode = app.adjTypeCode;
10162    }
10163
10164    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10165        enforceNotIsolatedCaller("getRunningAppProcesses");
10166        // Lazy instantiation of list
10167        List<ActivityManager.RunningAppProcessInfo> runList = null;
10168        final boolean allUsers = ActivityManager.checkUidPermission(
10169                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10170                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10171        int userId = UserHandle.getUserId(Binder.getCallingUid());
10172        synchronized (this) {
10173            // Iterate across all processes
10174            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10175                ProcessRecord app = mLruProcesses.get(i);
10176                if (!allUsers && app.userId != userId) {
10177                    continue;
10178                }
10179                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10180                    // Generate process state info for running application
10181                    ActivityManager.RunningAppProcessInfo currApp =
10182                        new ActivityManager.RunningAppProcessInfo(app.processName,
10183                                app.pid, app.getPackageList());
10184                    fillInProcMemInfo(app, currApp);
10185                    if (app.adjSource instanceof ProcessRecord) {
10186                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10187                        currApp.importanceReasonImportance = oomAdjToImportance(
10188                                app.adjSourceOom, null);
10189                    } else if (app.adjSource instanceof ActivityRecord) {
10190                        ActivityRecord r = (ActivityRecord)app.adjSource;
10191                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10192                    }
10193                    if (app.adjTarget instanceof ComponentName) {
10194                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10195                    }
10196                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10197                    //        + " lru=" + currApp.lru);
10198                    if (runList == null) {
10199                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10200                    }
10201                    runList.add(currApp);
10202                }
10203            }
10204        }
10205        return runList;
10206    }
10207
10208    public List<ApplicationInfo> getRunningExternalApplications() {
10209        enforceNotIsolatedCaller("getRunningExternalApplications");
10210        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10211        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10212        if (runningApps != null && runningApps.size() > 0) {
10213            Set<String> extList = new HashSet<String>();
10214            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10215                if (app.pkgList != null) {
10216                    for (String pkg : app.pkgList) {
10217                        extList.add(pkg);
10218                    }
10219                }
10220            }
10221            IPackageManager pm = AppGlobals.getPackageManager();
10222            for (String pkg : extList) {
10223                try {
10224                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10225                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10226                        retList.add(info);
10227                    }
10228                } catch (RemoteException e) {
10229                }
10230            }
10231        }
10232        return retList;
10233    }
10234
10235    @Override
10236    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10237        enforceNotIsolatedCaller("getMyMemoryState");
10238        synchronized (this) {
10239            ProcessRecord proc;
10240            synchronized (mPidsSelfLocked) {
10241                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10242            }
10243            fillInProcMemInfo(proc, outInfo);
10244        }
10245    }
10246
10247    @Override
10248    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10249        if (checkCallingPermission(android.Manifest.permission.DUMP)
10250                != PackageManager.PERMISSION_GRANTED) {
10251            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10252                    + Binder.getCallingPid()
10253                    + ", uid=" + Binder.getCallingUid()
10254                    + " without permission "
10255                    + android.Manifest.permission.DUMP);
10256            return;
10257        }
10258
10259        boolean dumpAll = false;
10260        boolean dumpClient = false;
10261        String dumpPackage = null;
10262
10263        int opti = 0;
10264        while (opti < args.length) {
10265            String opt = args[opti];
10266            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10267                break;
10268            }
10269            opti++;
10270            if ("-a".equals(opt)) {
10271                dumpAll = true;
10272            } else if ("-c".equals(opt)) {
10273                dumpClient = true;
10274            } else if ("-h".equals(opt)) {
10275                pw.println("Activity manager dump options:");
10276                pw.println("  [-a] [-c] [-h] [cmd] ...");
10277                pw.println("  cmd may be one of:");
10278                pw.println("    a[ctivities]: activity stack state");
10279                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10280                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10281                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10282                pw.println("    o[om]: out of memory management");
10283                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10284                pw.println("    provider [COMP_SPEC]: provider client-side state");
10285                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10286                pw.println("    service [COMP_SPEC]: service client-side state");
10287                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10288                pw.println("    all: dump all activities");
10289                pw.println("    top: dump the top activity");
10290                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10291                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10292                pw.println("    a partial substring in a component name, a");
10293                pw.println("    hex object identifier.");
10294                pw.println("  -a: include all available server state.");
10295                pw.println("  -c: include client state.");
10296                return;
10297            } else {
10298                pw.println("Unknown argument: " + opt + "; use -h for help");
10299            }
10300        }
10301
10302        long origId = Binder.clearCallingIdentity();
10303        boolean more = false;
10304        // Is the caller requesting to dump a particular piece of data?
10305        if (opti < args.length) {
10306            String cmd = args[opti];
10307            opti++;
10308            if ("activities".equals(cmd) || "a".equals(cmd)) {
10309                synchronized (this) {
10310                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10311                }
10312            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10313                String[] newArgs;
10314                String name;
10315                if (opti >= args.length) {
10316                    name = null;
10317                    newArgs = EMPTY_STRING_ARRAY;
10318                } else {
10319                    name = args[opti];
10320                    opti++;
10321                    newArgs = new String[args.length - opti];
10322                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10323                            args.length - opti);
10324                }
10325                synchronized (this) {
10326                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10327                }
10328            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10329                String[] newArgs;
10330                String name;
10331                if (opti >= args.length) {
10332                    name = null;
10333                    newArgs = EMPTY_STRING_ARRAY;
10334                } else {
10335                    name = args[opti];
10336                    opti++;
10337                    newArgs = new String[args.length - opti];
10338                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10339                            args.length - opti);
10340                }
10341                synchronized (this) {
10342                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10343                }
10344            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10345                String[] newArgs;
10346                String name;
10347                if (opti >= args.length) {
10348                    name = null;
10349                    newArgs = EMPTY_STRING_ARRAY;
10350                } else {
10351                    name = args[opti];
10352                    opti++;
10353                    newArgs = new String[args.length - opti];
10354                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10355                            args.length - opti);
10356                }
10357                synchronized (this) {
10358                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10359                }
10360            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10361                synchronized (this) {
10362                    dumpOomLocked(fd, pw, args, opti, true);
10363                }
10364            } else if ("provider".equals(cmd)) {
10365                String[] newArgs;
10366                String name;
10367                if (opti >= args.length) {
10368                    name = null;
10369                    newArgs = EMPTY_STRING_ARRAY;
10370                } else {
10371                    name = args[opti];
10372                    opti++;
10373                    newArgs = new String[args.length - opti];
10374                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10375                }
10376                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10377                    pw.println("No providers match: " + name);
10378                    pw.println("Use -h for help.");
10379                }
10380            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10381                synchronized (this) {
10382                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10383                }
10384            } else if ("service".equals(cmd)) {
10385                String[] newArgs;
10386                String name;
10387                if (opti >= args.length) {
10388                    name = null;
10389                    newArgs = EMPTY_STRING_ARRAY;
10390                } else {
10391                    name = args[opti];
10392                    opti++;
10393                    newArgs = new String[args.length - opti];
10394                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10395                            args.length - opti);
10396                }
10397                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10398                    pw.println("No services match: " + name);
10399                    pw.println("Use -h for help.");
10400                }
10401            } else if ("package".equals(cmd)) {
10402                String[] newArgs;
10403                if (opti >= args.length) {
10404                    pw.println("package: no package name specified");
10405                    pw.println("Use -h for help.");
10406                } else {
10407                    dumpPackage = args[opti];
10408                    opti++;
10409                    newArgs = new String[args.length - opti];
10410                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10411                            args.length - opti);
10412                    args = newArgs;
10413                    opti = 0;
10414                    more = true;
10415                }
10416            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10417                synchronized (this) {
10418                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10419                }
10420            } else {
10421                // Dumping a single activity?
10422                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10423                    pw.println("Bad activity command, or no activities match: " + cmd);
10424                    pw.println("Use -h for help.");
10425                }
10426            }
10427            if (!more) {
10428                Binder.restoreCallingIdentity(origId);
10429                return;
10430            }
10431        }
10432
10433        // No piece of data specified, dump everything.
10434        synchronized (this) {
10435            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10436            pw.println();
10437            if (dumpAll) {
10438                pw.println("-------------------------------------------------------------------------------");
10439            }
10440            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10441            pw.println();
10442            if (dumpAll) {
10443                pw.println("-------------------------------------------------------------------------------");
10444            }
10445            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10446            pw.println();
10447            if (dumpAll) {
10448                pw.println("-------------------------------------------------------------------------------");
10449            }
10450            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10451            pw.println();
10452            if (dumpAll) {
10453                pw.println("-------------------------------------------------------------------------------");
10454            }
10455            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10456            pw.println();
10457            if (dumpAll) {
10458                pw.println("-------------------------------------------------------------------------------");
10459            }
10460            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10461        }
10462        Binder.restoreCallingIdentity(origId);
10463    }
10464
10465    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10466            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10467        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10468
10469        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10470                dumpPackage);
10471        boolean needSep = printedAnything;
10472
10473        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10474                dumpPackage, needSep, "  mFocusedActivity: ");
10475        if (printed) {
10476            printedAnything = true;
10477            needSep = false;
10478        }
10479
10480        if (dumpPackage == null) {
10481            if (needSep) {
10482                pw.println();
10483            }
10484            needSep = true;
10485            printedAnything = true;
10486            mStackSupervisor.dump(pw, "  ");
10487        }
10488
10489        if (mRecentTasks.size() > 0) {
10490            boolean printedHeader = false;
10491
10492            final int N = mRecentTasks.size();
10493            for (int i=0; i<N; i++) {
10494                TaskRecord tr = mRecentTasks.get(i);
10495                if (dumpPackage != null) {
10496                    if (tr.realActivity == null ||
10497                            !dumpPackage.equals(tr.realActivity)) {
10498                        continue;
10499                    }
10500                }
10501                if (!printedHeader) {
10502                    if (needSep) {
10503                        pw.println();
10504                    }
10505                    pw.println("  Recent tasks:");
10506                    printedHeader = true;
10507                    printedAnything = true;
10508                }
10509                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10510                        pw.println(tr);
10511                if (dumpAll) {
10512                    mRecentTasks.get(i).dump(pw, "    ");
10513                }
10514            }
10515        }
10516
10517        if (!printedAnything) {
10518            pw.println("  (nothing)");
10519        }
10520    }
10521
10522    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10523            int opti, boolean dumpAll, String dumpPackage) {
10524        boolean needSep = false;
10525        boolean printedAnything = false;
10526        int numPers = 0;
10527
10528        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10529
10530        if (dumpAll) {
10531            final int NP = mProcessNames.getMap().size();
10532            for (int ip=0; ip<NP; ip++) {
10533                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10534                final int NA = procs.size();
10535                for (int ia=0; ia<NA; ia++) {
10536                    ProcessRecord r = procs.valueAt(ia);
10537                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10538                        continue;
10539                    }
10540                    if (!needSep) {
10541                        pw.println("  All known processes:");
10542                        needSep = true;
10543                        printedAnything = true;
10544                    }
10545                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10546                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10547                        pw.print(" "); pw.println(r);
10548                    r.dump(pw, "    ");
10549                    if (r.persistent) {
10550                        numPers++;
10551                    }
10552                }
10553            }
10554        }
10555
10556        if (mIsolatedProcesses.size() > 0) {
10557            boolean printed = false;
10558            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10559                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10560                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10561                    continue;
10562                }
10563                if (!printed) {
10564                    if (needSep) {
10565                        pw.println();
10566                    }
10567                    pw.println("  Isolated process list (sorted by uid):");
10568                    printedAnything = true;
10569                    printed = true;
10570                    needSep = true;
10571                }
10572                pw.println(String.format("%sIsolated #%2d: %s",
10573                        "    ", i, r.toString()));
10574            }
10575        }
10576
10577        if (mLruProcesses.size() > 0) {
10578            if (needSep) {
10579                pw.println();
10580            }
10581            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10582                    pw.print(" total, non-act at ");
10583                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10584                    pw.print(", non-svc at ");
10585                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10586                    pw.println("):");
10587            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10588            needSep = true;
10589            printedAnything = true;
10590        }
10591
10592        if (dumpAll || dumpPackage != null) {
10593            synchronized (mPidsSelfLocked) {
10594                boolean printed = false;
10595                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10596                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10597                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10598                        continue;
10599                    }
10600                    if (!printed) {
10601                        if (needSep) pw.println();
10602                        needSep = true;
10603                        pw.println("  PID mappings:");
10604                        printed = true;
10605                        printedAnything = true;
10606                    }
10607                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10608                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10609                }
10610            }
10611        }
10612
10613        if (mForegroundProcesses.size() > 0) {
10614            synchronized (mPidsSelfLocked) {
10615                boolean printed = false;
10616                for (int i=0; i<mForegroundProcesses.size(); i++) {
10617                    ProcessRecord r = mPidsSelfLocked.get(
10618                            mForegroundProcesses.valueAt(i).pid);
10619                    if (dumpPackage != null && (r == null
10620                            || !r.pkgList.containsKey(dumpPackage))) {
10621                        continue;
10622                    }
10623                    if (!printed) {
10624                        if (needSep) pw.println();
10625                        needSep = true;
10626                        pw.println("  Foreground Processes:");
10627                        printed = true;
10628                        printedAnything = true;
10629                    }
10630                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10631                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10632                }
10633            }
10634        }
10635
10636        if (mPersistentStartingProcesses.size() > 0) {
10637            if (needSep) pw.println();
10638            needSep = true;
10639            printedAnything = true;
10640            pw.println("  Persisent processes that are starting:");
10641            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10642                    "Starting Norm", "Restarting PERS", dumpPackage);
10643        }
10644
10645        if (mRemovedProcesses.size() > 0) {
10646            if (needSep) pw.println();
10647            needSep = true;
10648            printedAnything = true;
10649            pw.println("  Processes that are being removed:");
10650            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10651                    "Removed Norm", "Removed PERS", dumpPackage);
10652        }
10653
10654        if (mProcessesOnHold.size() > 0) {
10655            if (needSep) pw.println();
10656            needSep = true;
10657            printedAnything = true;
10658            pw.println("  Processes that are on old until the system is ready:");
10659            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10660                    "OnHold Norm", "OnHold PERS", dumpPackage);
10661        }
10662
10663        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10664
10665        if (mProcessCrashTimes.getMap().size() > 0) {
10666            boolean printed = false;
10667            long now = SystemClock.uptimeMillis();
10668            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10669            final int NP = pmap.size();
10670            for (int ip=0; ip<NP; ip++) {
10671                String pname = pmap.keyAt(ip);
10672                SparseArray<Long> uids = pmap.valueAt(ip);
10673                final int N = uids.size();
10674                for (int i=0; i<N; i++) {
10675                    int puid = uids.keyAt(i);
10676                    ProcessRecord r = mProcessNames.get(pname, puid);
10677                    if (dumpPackage != null && (r == null
10678                            || !r.pkgList.containsKey(dumpPackage))) {
10679                        continue;
10680                    }
10681                    if (!printed) {
10682                        if (needSep) pw.println();
10683                        needSep = true;
10684                        pw.println("  Time since processes crashed:");
10685                        printed = true;
10686                        printedAnything = true;
10687                    }
10688                    pw.print("    Process "); pw.print(pname);
10689                            pw.print(" uid "); pw.print(puid);
10690                            pw.print(": last crashed ");
10691                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10692                            pw.println(" ago");
10693                }
10694            }
10695        }
10696
10697        if (mBadProcesses.getMap().size() > 0) {
10698            boolean printed = false;
10699            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10700            final int NP = pmap.size();
10701            for (int ip=0; ip<NP; ip++) {
10702                String pname = pmap.keyAt(ip);
10703                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10704                final int N = uids.size();
10705                for (int i=0; i<N; i++) {
10706                    int puid = uids.keyAt(i);
10707                    ProcessRecord r = mProcessNames.get(pname, puid);
10708                    if (dumpPackage != null && (r == null
10709                            || !r.pkgList.containsKey(dumpPackage))) {
10710                        continue;
10711                    }
10712                    if (!printed) {
10713                        if (needSep) pw.println();
10714                        needSep = true;
10715                        pw.println("  Bad processes:");
10716                        printedAnything = true;
10717                    }
10718                    BadProcessInfo info = uids.valueAt(i);
10719                    pw.print("    Bad process "); pw.print(pname);
10720                            pw.print(" uid "); pw.print(puid);
10721                            pw.print(": crashed at time "); pw.println(info.time);
10722                    if (info.shortMsg != null) {
10723                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10724                    }
10725                    if (info.longMsg != null) {
10726                        pw.print("      Long msg: "); pw.println(info.longMsg);
10727                    }
10728                    if (info.stack != null) {
10729                        pw.println("      Stack:");
10730                        int lastPos = 0;
10731                        for (int pos=0; pos<info.stack.length(); pos++) {
10732                            if (info.stack.charAt(pos) == '\n') {
10733                                pw.print("        ");
10734                                pw.write(info.stack, lastPos, pos-lastPos);
10735                                pw.println();
10736                                lastPos = pos+1;
10737                            }
10738                        }
10739                        if (lastPos < info.stack.length()) {
10740                            pw.print("        ");
10741                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10742                            pw.println();
10743                        }
10744                    }
10745                }
10746            }
10747        }
10748
10749        if (dumpPackage == null) {
10750            pw.println();
10751            needSep = false;
10752            pw.println("  mStartedUsers:");
10753            for (int i=0; i<mStartedUsers.size(); i++) {
10754                UserStartedState uss = mStartedUsers.valueAt(i);
10755                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10756                        pw.print(": "); uss.dump("", pw);
10757            }
10758            pw.print("  mStartedUserArray: [");
10759            for (int i=0; i<mStartedUserArray.length; i++) {
10760                if (i > 0) pw.print(", ");
10761                pw.print(mStartedUserArray[i]);
10762            }
10763            pw.println("]");
10764            pw.print("  mUserLru: [");
10765            for (int i=0; i<mUserLru.size(); i++) {
10766                if (i > 0) pw.print(", ");
10767                pw.print(mUserLru.get(i));
10768            }
10769            pw.println("]");
10770            if (dumpAll) {
10771                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10772            }
10773        }
10774        if (mHomeProcess != null && (dumpPackage == null
10775                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10776            if (needSep) {
10777                pw.println();
10778                needSep = false;
10779            }
10780            pw.println("  mHomeProcess: " + mHomeProcess);
10781        }
10782        if (mPreviousProcess != null && (dumpPackage == null
10783                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10784            if (needSep) {
10785                pw.println();
10786                needSep = false;
10787            }
10788            pw.println("  mPreviousProcess: " + mPreviousProcess);
10789        }
10790        if (dumpAll) {
10791            StringBuilder sb = new StringBuilder(128);
10792            sb.append("  mPreviousProcessVisibleTime: ");
10793            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10794            pw.println(sb);
10795        }
10796        if (mHeavyWeightProcess != null && (dumpPackage == null
10797                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10798            if (needSep) {
10799                pw.println();
10800                needSep = false;
10801            }
10802            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10803        }
10804        if (dumpPackage == null) {
10805            pw.println("  mConfiguration: " + mConfiguration);
10806        }
10807        if (dumpAll) {
10808            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10809            if (mCompatModePackages.getPackages().size() > 0) {
10810                boolean printed = false;
10811                for (Map.Entry<String, Integer> entry
10812                        : mCompatModePackages.getPackages().entrySet()) {
10813                    String pkg = entry.getKey();
10814                    int mode = entry.getValue();
10815                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10816                        continue;
10817                    }
10818                    if (!printed) {
10819                        pw.println("  mScreenCompatPackages:");
10820                        printed = true;
10821                    }
10822                    pw.print("    "); pw.print(pkg); pw.print(": ");
10823                            pw.print(mode); pw.println();
10824                }
10825            }
10826        }
10827        if (dumpPackage == null) {
10828            if (mSleeping || mWentToSleep || mLockScreenShown) {
10829                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10830                        + " mLockScreenShown " + mLockScreenShown);
10831            }
10832            if (mShuttingDown) {
10833                pw.println("  mShuttingDown=" + mShuttingDown);
10834            }
10835        }
10836        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10837                || mOrigWaitForDebugger) {
10838            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10839                    || dumpPackage.equals(mOrigDebugApp)) {
10840                if (needSep) {
10841                    pw.println();
10842                    needSep = false;
10843                }
10844                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10845                        + " mDebugTransient=" + mDebugTransient
10846                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10847            }
10848        }
10849        if (mOpenGlTraceApp != null) {
10850            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10851                if (needSep) {
10852                    pw.println();
10853                    needSep = false;
10854                }
10855                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10856            }
10857        }
10858        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10859                || mProfileFd != null) {
10860            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10861                if (needSep) {
10862                    pw.println();
10863                    needSep = false;
10864                }
10865                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10866                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10867                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10868                        + mAutoStopProfiler);
10869            }
10870        }
10871        if (dumpPackage == null) {
10872            if (mAlwaysFinishActivities || mController != null) {
10873                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10874                        + " mController=" + mController);
10875            }
10876            if (dumpAll) {
10877                pw.println("  Total persistent processes: " + numPers);
10878                pw.println("  mProcessesReady=" + mProcessesReady
10879                        + " mSystemReady=" + mSystemReady);
10880                pw.println("  mBooting=" + mBooting
10881                        + " mBooted=" + mBooted
10882                        + " mFactoryTest=" + mFactoryTest);
10883                pw.print("  mLastPowerCheckRealtime=");
10884                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10885                        pw.println("");
10886                pw.print("  mLastPowerCheckUptime=");
10887                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10888                        pw.println("");
10889                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10890                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10891                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10892                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10893                        + " (" + mLruProcesses.size() + " total)"
10894                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10895                        + " mNumServiceProcs=" + mNumServiceProcs
10896                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10897                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10898                        + " mLastMemoryLevel" + mLastMemoryLevel
10899                        + " mLastNumProcesses" + mLastNumProcesses);
10900                long now = SystemClock.uptimeMillis();
10901                pw.print("  mLastIdleTime=");
10902                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10903                        pw.print(" mLowRamSinceLastIdle=");
10904                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10905                        pw.println();
10906            }
10907        }
10908
10909        if (!printedAnything) {
10910            pw.println("  (nothing)");
10911        }
10912    }
10913
10914    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10915            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10916        if (mProcessesToGc.size() > 0) {
10917            boolean printed = false;
10918            long now = SystemClock.uptimeMillis();
10919            for (int i=0; i<mProcessesToGc.size(); i++) {
10920                ProcessRecord proc = mProcessesToGc.get(i);
10921                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10922                    continue;
10923                }
10924                if (!printed) {
10925                    if (needSep) pw.println();
10926                    needSep = true;
10927                    pw.println("  Processes that are waiting to GC:");
10928                    printed = true;
10929                }
10930                pw.print("    Process "); pw.println(proc);
10931                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10932                        pw.print(", last gced=");
10933                        pw.print(now-proc.lastRequestedGc);
10934                        pw.print(" ms ago, last lowMem=");
10935                        pw.print(now-proc.lastLowMemory);
10936                        pw.println(" ms ago");
10937
10938            }
10939        }
10940        return needSep;
10941    }
10942
10943    void printOomLevel(PrintWriter pw, String name, int adj) {
10944        pw.print("    ");
10945        if (adj >= 0) {
10946            pw.print(' ');
10947            if (adj < 10) pw.print(' ');
10948        } else {
10949            if (adj > -10) pw.print(' ');
10950        }
10951        pw.print(adj);
10952        pw.print(": ");
10953        pw.print(name);
10954        pw.print(" (");
10955        pw.print(mProcessList.getMemLevel(adj)/1024);
10956        pw.println(" kB)");
10957    }
10958
10959    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10960            int opti, boolean dumpAll) {
10961        boolean needSep = false;
10962
10963        if (mLruProcesses.size() > 0) {
10964            if (needSep) pw.println();
10965            needSep = true;
10966            pw.println("  OOM levels:");
10967            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10968            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10969            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10970            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10971            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10972            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10973            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10974            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10975            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
10976            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
10977            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
10978            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
10979            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
10980
10981            if (needSep) pw.println();
10982            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
10983                    pw.print(" total, non-act at ");
10984                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10985                    pw.print(", non-svc at ");
10986                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10987                    pw.println("):");
10988            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
10989            needSep = true;
10990        }
10991
10992        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
10993
10994        pw.println();
10995        pw.println("  mHomeProcess: " + mHomeProcess);
10996        pw.println("  mPreviousProcess: " + mPreviousProcess);
10997        if (mHeavyWeightProcess != null) {
10998            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10999        }
11000
11001        return true;
11002    }
11003
11004    /**
11005     * There are three ways to call this:
11006     *  - no provider specified: dump all the providers
11007     *  - a flattened component name that matched an existing provider was specified as the
11008     *    first arg: dump that one provider
11009     *  - the first arg isn't the flattened component name of an existing provider:
11010     *    dump all providers whose component contains the first arg as a substring
11011     */
11012    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11013            int opti, boolean dumpAll) {
11014        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11015    }
11016
11017    static class ItemMatcher {
11018        ArrayList<ComponentName> components;
11019        ArrayList<String> strings;
11020        ArrayList<Integer> objects;
11021        boolean all;
11022
11023        ItemMatcher() {
11024            all = true;
11025        }
11026
11027        void build(String name) {
11028            ComponentName componentName = ComponentName.unflattenFromString(name);
11029            if (componentName != null) {
11030                if (components == null) {
11031                    components = new ArrayList<ComponentName>();
11032                }
11033                components.add(componentName);
11034                all = false;
11035            } else {
11036                int objectId = 0;
11037                // Not a '/' separated full component name; maybe an object ID?
11038                try {
11039                    objectId = Integer.parseInt(name, 16);
11040                    if (objects == null) {
11041                        objects = new ArrayList<Integer>();
11042                    }
11043                    objects.add(objectId);
11044                    all = false;
11045                } catch (RuntimeException e) {
11046                    // Not an integer; just do string match.
11047                    if (strings == null) {
11048                        strings = new ArrayList<String>();
11049                    }
11050                    strings.add(name);
11051                    all = false;
11052                }
11053            }
11054        }
11055
11056        int build(String[] args, int opti) {
11057            for (; opti<args.length; opti++) {
11058                String name = args[opti];
11059                if ("--".equals(name)) {
11060                    return opti+1;
11061                }
11062                build(name);
11063            }
11064            return opti;
11065        }
11066
11067        boolean match(Object object, ComponentName comp) {
11068            if (all) {
11069                return true;
11070            }
11071            if (components != null) {
11072                for (int i=0; i<components.size(); i++) {
11073                    if (components.get(i).equals(comp)) {
11074                        return true;
11075                    }
11076                }
11077            }
11078            if (objects != null) {
11079                for (int i=0; i<objects.size(); i++) {
11080                    if (System.identityHashCode(object) == objects.get(i)) {
11081                        return true;
11082                    }
11083                }
11084            }
11085            if (strings != null) {
11086                String flat = comp.flattenToString();
11087                for (int i=0; i<strings.size(); i++) {
11088                    if (flat.contains(strings.get(i))) {
11089                        return true;
11090                    }
11091                }
11092            }
11093            return false;
11094        }
11095    }
11096
11097    /**
11098     * There are three things that cmd can be:
11099     *  - a flattened component name that matches an existing activity
11100     *  - the cmd arg isn't the flattened component name of an existing activity:
11101     *    dump all activity whose component contains the cmd as a substring
11102     *  - A hex number of the ActivityRecord object instance.
11103     */
11104    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11105            int opti, boolean dumpAll) {
11106        ArrayList<ActivityRecord> activities;
11107
11108        synchronized (this) {
11109            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11110        }
11111
11112        if (activities.size() <= 0) {
11113            return false;
11114        }
11115
11116        String[] newArgs = new String[args.length - opti];
11117        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11118
11119        TaskRecord lastTask = null;
11120        boolean needSep = false;
11121        for (int i=activities.size()-1; i>=0; i--) {
11122            ActivityRecord r = activities.get(i);
11123            if (needSep) {
11124                pw.println();
11125            }
11126            needSep = true;
11127            synchronized (this) {
11128                if (lastTask != r.task) {
11129                    lastTask = r.task;
11130                    pw.print("TASK "); pw.print(lastTask.affinity);
11131                            pw.print(" id="); pw.println(lastTask.taskId);
11132                    if (dumpAll) {
11133                        lastTask.dump(pw, "  ");
11134                    }
11135                }
11136            }
11137            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11138        }
11139        return true;
11140    }
11141
11142    /**
11143     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11144     * there is a thread associated with the activity.
11145     */
11146    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11147            final ActivityRecord r, String[] args, boolean dumpAll) {
11148        String innerPrefix = prefix + "  ";
11149        synchronized (this) {
11150            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11151                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11152                    pw.print(" pid=");
11153                    if (r.app != null) pw.println(r.app.pid);
11154                    else pw.println("(not running)");
11155            if (dumpAll) {
11156                r.dump(pw, innerPrefix);
11157            }
11158        }
11159        if (r.app != null && r.app.thread != null) {
11160            // flush anything that is already in the PrintWriter since the thread is going
11161            // to write to the file descriptor directly
11162            pw.flush();
11163            try {
11164                TransferPipe tp = new TransferPipe();
11165                try {
11166                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11167                            r.appToken, innerPrefix, args);
11168                    tp.go(fd);
11169                } finally {
11170                    tp.kill();
11171                }
11172            } catch (IOException e) {
11173                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11174            } catch (RemoteException e) {
11175                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11176            }
11177        }
11178    }
11179
11180    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11181            int opti, boolean dumpAll, String dumpPackage) {
11182        boolean needSep = false;
11183        boolean onlyHistory = false;
11184        boolean printedAnything = false;
11185
11186        if ("history".equals(dumpPackage)) {
11187            if (opti < args.length && "-s".equals(args[opti])) {
11188                dumpAll = false;
11189            }
11190            onlyHistory = true;
11191            dumpPackage = null;
11192        }
11193
11194        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11195        if (!onlyHistory && dumpAll) {
11196            if (mRegisteredReceivers.size() > 0) {
11197                boolean printed = false;
11198                Iterator it = mRegisteredReceivers.values().iterator();
11199                while (it.hasNext()) {
11200                    ReceiverList r = (ReceiverList)it.next();
11201                    if (dumpPackage != null && (r.app == null ||
11202                            !dumpPackage.equals(r.app.info.packageName))) {
11203                        continue;
11204                    }
11205                    if (!printed) {
11206                        pw.println("  Registered Receivers:");
11207                        needSep = true;
11208                        printed = true;
11209                        printedAnything = true;
11210                    }
11211                    pw.print("  * "); pw.println(r);
11212                    r.dump(pw, "    ");
11213                }
11214            }
11215
11216            if (mReceiverResolver.dump(pw, needSep ?
11217                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11218                    "    ", dumpPackage, false)) {
11219                needSep = true;
11220                printedAnything = true;
11221            }
11222        }
11223
11224        for (BroadcastQueue q : mBroadcastQueues) {
11225            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11226            printedAnything |= needSep;
11227        }
11228
11229        needSep = true;
11230
11231        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11232            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11233                if (needSep) {
11234                    pw.println();
11235                }
11236                needSep = true;
11237                printedAnything = true;
11238                pw.print("  Sticky broadcasts for user ");
11239                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11240                StringBuilder sb = new StringBuilder(128);
11241                for (Map.Entry<String, ArrayList<Intent>> ent
11242                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11243                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11244                    if (dumpAll) {
11245                        pw.println(":");
11246                        ArrayList<Intent> intents = ent.getValue();
11247                        final int N = intents.size();
11248                        for (int i=0; i<N; i++) {
11249                            sb.setLength(0);
11250                            sb.append("    Intent: ");
11251                            intents.get(i).toShortString(sb, false, true, false, false);
11252                            pw.println(sb.toString());
11253                            Bundle bundle = intents.get(i).getExtras();
11254                            if (bundle != null) {
11255                                pw.print("      ");
11256                                pw.println(bundle.toString());
11257                            }
11258                        }
11259                    } else {
11260                        pw.println("");
11261                    }
11262                }
11263            }
11264        }
11265
11266        if (!onlyHistory && dumpAll) {
11267            pw.println();
11268            for (BroadcastQueue queue : mBroadcastQueues) {
11269                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11270                        + queue.mBroadcastsScheduled);
11271            }
11272            pw.println("  mHandler:");
11273            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11274            needSep = true;
11275            printedAnything = true;
11276        }
11277
11278        if (!printedAnything) {
11279            pw.println("  (nothing)");
11280        }
11281    }
11282
11283    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11284            int opti, boolean dumpAll, String dumpPackage) {
11285        boolean needSep;
11286        boolean printedAnything = false;
11287
11288        ItemMatcher matcher = new ItemMatcher();
11289        matcher.build(args, opti);
11290
11291        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11292
11293        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11294        printedAnything |= needSep;
11295
11296        if (mLaunchingProviders.size() > 0) {
11297            boolean printed = false;
11298            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11299                ContentProviderRecord r = mLaunchingProviders.get(i);
11300                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11301                    continue;
11302                }
11303                if (!printed) {
11304                    if (needSep) pw.println();
11305                    needSep = true;
11306                    pw.println("  Launching content providers:");
11307                    printed = true;
11308                    printedAnything = true;
11309                }
11310                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11311                        pw.println(r);
11312            }
11313        }
11314
11315        if (mGrantedUriPermissions.size() > 0) {
11316            boolean printed = false;
11317            int dumpUid = -2;
11318            if (dumpPackage != null) {
11319                try {
11320                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11321                } catch (NameNotFoundException e) {
11322                    dumpUid = -1;
11323                }
11324            }
11325            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11326                int uid = mGrantedUriPermissions.keyAt(i);
11327                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11328                    continue;
11329                }
11330                ArrayMap<Uri, UriPermission> perms
11331                        = mGrantedUriPermissions.valueAt(i);
11332                if (!printed) {
11333                    if (needSep) pw.println();
11334                    needSep = true;
11335                    pw.println("  Granted Uri Permissions:");
11336                    printed = true;
11337                    printedAnything = true;
11338                }
11339                pw.print("  * UID "); pw.print(uid);
11340                        pw.println(" holds:");
11341                for (UriPermission perm : perms.values()) {
11342                    pw.print("    "); pw.println(perm);
11343                    if (dumpAll) {
11344                        perm.dump(pw, "      ");
11345                    }
11346                }
11347            }
11348        }
11349
11350        if (!printedAnything) {
11351            pw.println("  (nothing)");
11352        }
11353    }
11354
11355    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11356            int opti, boolean dumpAll, String dumpPackage) {
11357        boolean printed = false;
11358
11359        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11360
11361        if (mIntentSenderRecords.size() > 0) {
11362            Iterator<WeakReference<PendingIntentRecord>> it
11363                    = mIntentSenderRecords.values().iterator();
11364            while (it.hasNext()) {
11365                WeakReference<PendingIntentRecord> ref = it.next();
11366                PendingIntentRecord rec = ref != null ? ref.get(): null;
11367                if (dumpPackage != null && (rec == null
11368                        || !dumpPackage.equals(rec.key.packageName))) {
11369                    continue;
11370                }
11371                printed = true;
11372                if (rec != null) {
11373                    pw.print("  * "); pw.println(rec);
11374                    if (dumpAll) {
11375                        rec.dump(pw, "    ");
11376                    }
11377                } else {
11378                    pw.print("  * "); pw.println(ref);
11379                }
11380            }
11381        }
11382
11383        if (!printed) {
11384            pw.println("  (nothing)");
11385        }
11386    }
11387
11388    private static final int dumpProcessList(PrintWriter pw,
11389            ActivityManagerService service, List list,
11390            String prefix, String normalLabel, String persistentLabel,
11391            String dumpPackage) {
11392        int numPers = 0;
11393        final int N = list.size()-1;
11394        for (int i=N; i>=0; i--) {
11395            ProcessRecord r = (ProcessRecord)list.get(i);
11396            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11397                continue;
11398            }
11399            pw.println(String.format("%s%s #%2d: %s",
11400                    prefix, (r.persistent ? persistentLabel : normalLabel),
11401                    i, r.toString()));
11402            if (r.persistent) {
11403                numPers++;
11404            }
11405        }
11406        return numPers;
11407    }
11408
11409    private static final boolean dumpProcessOomList(PrintWriter pw,
11410            ActivityManagerService service, List<ProcessRecord> origList,
11411            String prefix, String normalLabel, String persistentLabel,
11412            boolean inclDetails, String dumpPackage) {
11413
11414        ArrayList<Pair<ProcessRecord, Integer>> list
11415                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11416        for (int i=0; i<origList.size(); i++) {
11417            ProcessRecord r = origList.get(i);
11418            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11419                continue;
11420            }
11421            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11422        }
11423
11424        if (list.size() <= 0) {
11425            return false;
11426        }
11427
11428        Comparator<Pair<ProcessRecord, Integer>> comparator
11429                = new Comparator<Pair<ProcessRecord, Integer>>() {
11430            @Override
11431            public int compare(Pair<ProcessRecord, Integer> object1,
11432                    Pair<ProcessRecord, Integer> object2) {
11433                if (object1.first.setAdj != object2.first.setAdj) {
11434                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11435                }
11436                if (object1.second.intValue() != object2.second.intValue()) {
11437                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11438                }
11439                return 0;
11440            }
11441        };
11442
11443        Collections.sort(list, comparator);
11444
11445        final long curRealtime = SystemClock.elapsedRealtime();
11446        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11447        final long curUptime = SystemClock.uptimeMillis();
11448        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11449
11450        for (int i=list.size()-1; i>=0; i--) {
11451            ProcessRecord r = list.get(i).first;
11452            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11453            char schedGroup;
11454            switch (r.setSchedGroup) {
11455                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11456                    schedGroup = 'B';
11457                    break;
11458                case Process.THREAD_GROUP_DEFAULT:
11459                    schedGroup = 'F';
11460                    break;
11461                default:
11462                    schedGroup = '?';
11463                    break;
11464            }
11465            char foreground;
11466            if (r.foregroundActivities) {
11467                foreground = 'A';
11468            } else if (r.foregroundServices) {
11469                foreground = 'S';
11470            } else {
11471                foreground = ' ';
11472            }
11473            String procState = ProcessList.makeProcStateString(r.curProcState);
11474            pw.print(prefix);
11475            pw.print(r.persistent ? persistentLabel : normalLabel);
11476            pw.print(" #");
11477            int num = (origList.size()-1)-list.get(i).second;
11478            if (num < 10) pw.print(' ');
11479            pw.print(num);
11480            pw.print(": ");
11481            pw.print(oomAdj);
11482            pw.print(' ');
11483            pw.print(schedGroup);
11484            pw.print('/');
11485            pw.print(foreground);
11486            pw.print('/');
11487            pw.print(procState);
11488            pw.print(" trm:");
11489            if (r.trimMemoryLevel < 10) pw.print(' ');
11490            pw.print(r.trimMemoryLevel);
11491            pw.print(' ');
11492            pw.print(r.toShortString());
11493            pw.print(" (");
11494            pw.print(r.adjType);
11495            pw.println(')');
11496            if (r.adjSource != null || r.adjTarget != null) {
11497                pw.print(prefix);
11498                pw.print("    ");
11499                if (r.adjTarget instanceof ComponentName) {
11500                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11501                } else if (r.adjTarget != null) {
11502                    pw.print(r.adjTarget.toString());
11503                } else {
11504                    pw.print("{null}");
11505                }
11506                pw.print("<=");
11507                if (r.adjSource instanceof ProcessRecord) {
11508                    pw.print("Proc{");
11509                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11510                    pw.println("}");
11511                } else if (r.adjSource != null) {
11512                    pw.println(r.adjSource.toString());
11513                } else {
11514                    pw.println("{null}");
11515                }
11516            }
11517            if (inclDetails) {
11518                pw.print(prefix);
11519                pw.print("    ");
11520                pw.print("oom: max="); pw.print(r.maxAdj);
11521                pw.print(" curRaw="); pw.print(r.curRawAdj);
11522                pw.print(" setRaw="); pw.print(r.setRawAdj);
11523                pw.print(" cur="); pw.print(r.curAdj);
11524                pw.print(" set="); pw.println(r.setAdj);
11525                pw.print(prefix);
11526                pw.print("    ");
11527                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11528                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11529                pw.print(" lastPss="); pw.print(r.lastPss);
11530                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11531                pw.print(prefix);
11532                pw.print("    ");
11533                pw.print("keeping="); pw.print(r.keeping);
11534                pw.print(" cached="); pw.print(r.cached);
11535                pw.print(" empty="); pw.print(r.empty);
11536                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11537
11538                if (!r.keeping) {
11539                    if (r.lastWakeTime != 0) {
11540                        long wtime;
11541                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11542                        synchronized (stats) {
11543                            wtime = stats.getProcessWakeTime(r.info.uid,
11544                                    r.pid, curRealtime);
11545                        }
11546                        long timeUsed = wtime - r.lastWakeTime;
11547                        pw.print(prefix);
11548                        pw.print("    ");
11549                        pw.print("keep awake over ");
11550                        TimeUtils.formatDuration(realtimeSince, pw);
11551                        pw.print(" used ");
11552                        TimeUtils.formatDuration(timeUsed, pw);
11553                        pw.print(" (");
11554                        pw.print((timeUsed*100)/realtimeSince);
11555                        pw.println("%)");
11556                    }
11557                    if (r.lastCpuTime != 0) {
11558                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11559                        pw.print(prefix);
11560                        pw.print("    ");
11561                        pw.print("run cpu over ");
11562                        TimeUtils.formatDuration(uptimeSince, pw);
11563                        pw.print(" used ");
11564                        TimeUtils.formatDuration(timeUsed, pw);
11565                        pw.print(" (");
11566                        pw.print((timeUsed*100)/uptimeSince);
11567                        pw.println("%)");
11568                    }
11569                }
11570            }
11571        }
11572        return true;
11573    }
11574
11575    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11576        ArrayList<ProcessRecord> procs;
11577        synchronized (this) {
11578            if (args != null && args.length > start
11579                    && args[start].charAt(0) != '-') {
11580                procs = new ArrayList<ProcessRecord>();
11581                int pid = -1;
11582                try {
11583                    pid = Integer.parseInt(args[start]);
11584                } catch (NumberFormatException e) {
11585                }
11586                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11587                    ProcessRecord proc = mLruProcesses.get(i);
11588                    if (proc.pid == pid) {
11589                        procs.add(proc);
11590                    } else if (proc.processName.equals(args[start])) {
11591                        procs.add(proc);
11592                    }
11593                }
11594                if (procs.size() <= 0) {
11595                    return null;
11596                }
11597            } else {
11598                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11599            }
11600        }
11601        return procs;
11602    }
11603
11604    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11605            PrintWriter pw, String[] args) {
11606        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11607        if (procs == null) {
11608            pw.println("No process found for: " + args[0]);
11609            return;
11610        }
11611
11612        long uptime = SystemClock.uptimeMillis();
11613        long realtime = SystemClock.elapsedRealtime();
11614        pw.println("Applications Graphics Acceleration Info:");
11615        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11616
11617        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11618            ProcessRecord r = procs.get(i);
11619            if (r.thread != null) {
11620                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11621                pw.flush();
11622                try {
11623                    TransferPipe tp = new TransferPipe();
11624                    try {
11625                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11626                        tp.go(fd);
11627                    } finally {
11628                        tp.kill();
11629                    }
11630                } catch (IOException e) {
11631                    pw.println("Failure while dumping the app: " + r);
11632                    pw.flush();
11633                } catch (RemoteException e) {
11634                    pw.println("Got a RemoteException while dumping the app " + r);
11635                    pw.flush();
11636                }
11637            }
11638        }
11639    }
11640
11641    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11642        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11643        if (procs == null) {
11644            pw.println("No process found for: " + args[0]);
11645            return;
11646        }
11647
11648        pw.println("Applications Database Info:");
11649
11650        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11651            ProcessRecord r = procs.get(i);
11652            if (r.thread != null) {
11653                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11654                pw.flush();
11655                try {
11656                    TransferPipe tp = new TransferPipe();
11657                    try {
11658                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11659                        tp.go(fd);
11660                    } finally {
11661                        tp.kill();
11662                    }
11663                } catch (IOException e) {
11664                    pw.println("Failure while dumping the app: " + r);
11665                    pw.flush();
11666                } catch (RemoteException e) {
11667                    pw.println("Got a RemoteException while dumping the app " + r);
11668                    pw.flush();
11669                }
11670            }
11671        }
11672    }
11673
11674    final static class MemItem {
11675        final boolean isProc;
11676        final String label;
11677        final String shortLabel;
11678        final long pss;
11679        final int id;
11680        final boolean hasActivities;
11681        ArrayList<MemItem> subitems;
11682
11683        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11684                boolean _hasActivities) {
11685            isProc = true;
11686            label = _label;
11687            shortLabel = _shortLabel;
11688            pss = _pss;
11689            id = _id;
11690            hasActivities = _hasActivities;
11691        }
11692
11693        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11694            isProc = false;
11695            label = _label;
11696            shortLabel = _shortLabel;
11697            pss = _pss;
11698            id = _id;
11699            hasActivities = false;
11700        }
11701    }
11702
11703    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11704            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11705        if (sort && !isCompact) {
11706            Collections.sort(items, new Comparator<MemItem>() {
11707                @Override
11708                public int compare(MemItem lhs, MemItem rhs) {
11709                    if (lhs.pss < rhs.pss) {
11710                        return 1;
11711                    } else if (lhs.pss > rhs.pss) {
11712                        return -1;
11713                    }
11714                    return 0;
11715                }
11716            });
11717        }
11718
11719        for (int i=0; i<items.size(); i++) {
11720            MemItem mi = items.get(i);
11721            if (!isCompact) {
11722                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11723            } else if (mi.isProc) {
11724                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11725                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11726                pw.println(mi.hasActivities ? ",a" : ",e");
11727            } else {
11728                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11729                pw.println(mi.pss);
11730            }
11731            if (mi.subitems != null) {
11732                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11733                        true, isCompact);
11734            }
11735        }
11736    }
11737
11738    // These are in KB.
11739    static final long[] DUMP_MEM_BUCKETS = new long[] {
11740        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11741        120*1024, 160*1024, 200*1024,
11742        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11743        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11744    };
11745
11746    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11747            boolean stackLike) {
11748        int start = label.lastIndexOf('.');
11749        if (start >= 0) start++;
11750        else start = 0;
11751        int end = label.length();
11752        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11753            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11754                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11755                out.append(bucket);
11756                out.append(stackLike ? "MB." : "MB ");
11757                out.append(label, start, end);
11758                return;
11759            }
11760        }
11761        out.append(memKB/1024);
11762        out.append(stackLike ? "MB." : "MB ");
11763        out.append(label, start, end);
11764    }
11765
11766    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11767            ProcessList.NATIVE_ADJ,
11768            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11769            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11770            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11771            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11772            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11773    };
11774    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11775            "Native",
11776            "System", "Persistent", "Foreground",
11777            "Visible", "Perceptible",
11778            "Heavy Weight", "Backup",
11779            "A Services", "Home",
11780            "Previous", "B Services", "Cached"
11781    };
11782    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11783            "native",
11784            "sys", "pers", "fore",
11785            "vis", "percept",
11786            "heavy", "backup",
11787            "servicea", "home",
11788            "prev", "serviceb", "cached"
11789    };
11790
11791    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11792            long realtime, boolean isCheckinRequest, boolean isCompact) {
11793        if (isCheckinRequest || isCompact) {
11794            // short checkin version
11795            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11796        } else {
11797            pw.println("Applications Memory Usage (kB):");
11798            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11799        }
11800    }
11801
11802    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11803            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11804        boolean dumpDetails = false;
11805        boolean dumpFullDetails = false;
11806        boolean dumpDalvik = false;
11807        boolean oomOnly = false;
11808        boolean isCompact = false;
11809        boolean localOnly = false;
11810
11811        int opti = 0;
11812        while (opti < args.length) {
11813            String opt = args[opti];
11814            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11815                break;
11816            }
11817            opti++;
11818            if ("-a".equals(opt)) {
11819                dumpDetails = true;
11820                dumpFullDetails = true;
11821                dumpDalvik = true;
11822            } else if ("-d".equals(opt)) {
11823                dumpDalvik = true;
11824            } else if ("-c".equals(opt)) {
11825                isCompact = true;
11826            } else if ("--oom".equals(opt)) {
11827                oomOnly = true;
11828            } else if ("--local".equals(opt)) {
11829                localOnly = true;
11830            } else if ("-h".equals(opt)) {
11831                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11832                pw.println("  -a: include all available information for each process.");
11833                pw.println("  -d: include dalvik details when dumping process details.");
11834                pw.println("  -c: dump in a compact machine-parseable representation.");
11835                pw.println("  --oom: only show processes organized by oom adj.");
11836                pw.println("  --local: only collect details locally, don't call process.");
11837                pw.println("If [process] is specified it can be the name or ");
11838                pw.println("pid of a specific process to dump.");
11839                return;
11840            } else {
11841                pw.println("Unknown argument: " + opt + "; use -h for help");
11842            }
11843        }
11844
11845        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11846        long uptime = SystemClock.uptimeMillis();
11847        long realtime = SystemClock.elapsedRealtime();
11848        final long[] tmpLong = new long[1];
11849
11850        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11851        if (procs == null) {
11852            // No Java processes.  Maybe they want to print a native process.
11853            if (args != null && args.length > opti
11854                    && args[opti].charAt(0) != '-') {
11855                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11856                        = new ArrayList<ProcessCpuTracker.Stats>();
11857                updateCpuStatsNow();
11858                int findPid = -1;
11859                try {
11860                    findPid = Integer.parseInt(args[opti]);
11861                } catch (NumberFormatException e) {
11862                }
11863                synchronized (mProcessCpuThread) {
11864                    final int N = mProcessCpuTracker.countStats();
11865                    for (int i=0; i<N; i++) {
11866                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11867                        if (st.pid == findPid || (st.baseName != null
11868                                && st.baseName.equals(args[opti]))) {
11869                            nativeProcs.add(st);
11870                        }
11871                    }
11872                }
11873                if (nativeProcs.size() > 0) {
11874                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11875                            isCompact);
11876                    Debug.MemoryInfo mi = null;
11877                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11878                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11879                        final int pid = r.pid;
11880                        if (!isCheckinRequest && dumpDetails) {
11881                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11882                        }
11883                        if (mi == null) {
11884                            mi = new Debug.MemoryInfo();
11885                        }
11886                        if (dumpDetails || (!brief && !oomOnly)) {
11887                            Debug.getMemoryInfo(pid, mi);
11888                        } else {
11889                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11890                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11891                        }
11892                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11893                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11894                        if (isCheckinRequest) {
11895                            pw.println();
11896                        }
11897                    }
11898                    return;
11899                }
11900            }
11901            pw.println("No process found for: " + args[opti]);
11902            return;
11903        }
11904
11905        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11906            dumpDetails = true;
11907        }
11908
11909        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11910
11911        String[] innerArgs = new String[args.length-opti];
11912        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11913
11914        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11915        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11916        long nativePss=0, dalvikPss=0, otherPss=0;
11917        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11918
11919        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11920        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11921                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11922
11923        long totalPss = 0;
11924        long cachedPss = 0;
11925
11926        Debug.MemoryInfo mi = null;
11927        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11928            final ProcessRecord r = procs.get(i);
11929            final IApplicationThread thread;
11930            final int pid;
11931            final int oomAdj;
11932            final boolean hasActivities;
11933            synchronized (this) {
11934                thread = r.thread;
11935                pid = r.pid;
11936                oomAdj = r.getSetAdjWithServices();
11937                hasActivities = r.activities.size() > 0;
11938            }
11939            if (thread != null) {
11940                if (!isCheckinRequest && dumpDetails) {
11941                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11942                }
11943                if (mi == null) {
11944                    mi = new Debug.MemoryInfo();
11945                }
11946                if (dumpDetails || (!brief && !oomOnly)) {
11947                    Debug.getMemoryInfo(pid, mi);
11948                } else {
11949                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11950                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11951                }
11952                if (dumpDetails) {
11953                    if (localOnly) {
11954                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11955                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11956                        if (isCheckinRequest) {
11957                            pw.println();
11958                        }
11959                    } else {
11960                        try {
11961                            pw.flush();
11962                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11963                                    dumpDalvik, innerArgs);
11964                        } catch (RemoteException e) {
11965                            if (!isCheckinRequest) {
11966                                pw.println("Got RemoteException!");
11967                                pw.flush();
11968                            }
11969                        }
11970                    }
11971                }
11972
11973                final long myTotalPss = mi.getTotalPss();
11974                final long myTotalUss = mi.getTotalUss();
11975
11976                synchronized (this) {
11977                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
11978                        // Record this for posterity if the process has been stable.
11979                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
11980                    }
11981                }
11982
11983                if (!isCheckinRequest && mi != null) {
11984                    totalPss += myTotalPss;
11985                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
11986                            (hasActivities ? " / activities)" : ")"),
11987                            r.processName, myTotalPss, pid, hasActivities);
11988                    procMems.add(pssItem);
11989                    procMemsMap.put(pid, pssItem);
11990
11991                    nativePss += mi.nativePss;
11992                    dalvikPss += mi.dalvikPss;
11993                    otherPss += mi.otherPss;
11994                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
11995                        long mem = mi.getOtherPss(j);
11996                        miscPss[j] += mem;
11997                        otherPss -= mem;
11998                    }
11999
12000                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12001                        cachedPss += myTotalPss;
12002                    }
12003
12004                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12005                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12006                                || oomIndex == (oomPss.length-1)) {
12007                            oomPss[oomIndex] += myTotalPss;
12008                            if (oomProcs[oomIndex] == null) {
12009                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12010                            }
12011                            oomProcs[oomIndex].add(pssItem);
12012                            break;
12013                        }
12014                    }
12015                }
12016            }
12017        }
12018
12019        if (!isCheckinRequest && procs.size() > 1) {
12020            // If we are showing aggregations, also look for native processes to
12021            // include so that our aggregations are more accurate.
12022            updateCpuStatsNow();
12023            synchronized (mProcessCpuThread) {
12024                final int N = mProcessCpuTracker.countStats();
12025                for (int i=0; i<N; i++) {
12026                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12027                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12028                        if (mi == null) {
12029                            mi = new Debug.MemoryInfo();
12030                        }
12031                        if (!brief && !oomOnly) {
12032                            Debug.getMemoryInfo(st.pid, mi);
12033                        } else {
12034                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12035                            mi.nativePrivateDirty = (int)tmpLong[0];
12036                        }
12037
12038                        final long myTotalPss = mi.getTotalPss();
12039                        totalPss += myTotalPss;
12040
12041                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12042                                st.name, myTotalPss, st.pid, false);
12043                        procMems.add(pssItem);
12044
12045                        nativePss += mi.nativePss;
12046                        dalvikPss += mi.dalvikPss;
12047                        otherPss += mi.otherPss;
12048                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12049                            long mem = mi.getOtherPss(j);
12050                            miscPss[j] += mem;
12051                            otherPss -= mem;
12052                        }
12053                        oomPss[0] += myTotalPss;
12054                        if (oomProcs[0] == null) {
12055                            oomProcs[0] = new ArrayList<MemItem>();
12056                        }
12057                        oomProcs[0].add(pssItem);
12058                    }
12059                }
12060            }
12061
12062            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12063
12064            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12065            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12066            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12067            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12068                String label = Debug.MemoryInfo.getOtherLabel(j);
12069                catMems.add(new MemItem(label, label, miscPss[j], j));
12070            }
12071
12072            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12073            for (int j=0; j<oomPss.length; j++) {
12074                if (oomPss[j] != 0) {
12075                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12076                            : DUMP_MEM_OOM_LABEL[j];
12077                    MemItem item = new MemItem(label, label, oomPss[j],
12078                            DUMP_MEM_OOM_ADJ[j]);
12079                    item.subitems = oomProcs[j];
12080                    oomMems.add(item);
12081                }
12082            }
12083
12084            if (!brief && !oomOnly && !isCompact) {
12085                pw.println();
12086                pw.println("Total PSS by process:");
12087                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12088                pw.println();
12089            }
12090            if (!isCompact) {
12091                pw.println("Total PSS by OOM adjustment:");
12092            }
12093            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12094            if (!brief && !oomOnly) {
12095                PrintWriter out = categoryPw != null ? categoryPw : pw;
12096                if (!isCompact) {
12097                    out.println();
12098                    out.println("Total PSS by category:");
12099                }
12100                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12101            }
12102            if (!isCompact) {
12103                pw.println();
12104            }
12105            MemInfoReader memInfo = new MemInfoReader();
12106            memInfo.readMemInfo();
12107            if (!brief) {
12108                if (!isCompact) {
12109                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12110                    pw.println(" kB");
12111                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12112                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12113                            pw.print(cachedPss); pw.print(" cached pss + ");
12114                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12115                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12116                } else {
12117                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12118                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12119                            + memInfo.getFreeSizeKb()); pw.print(",");
12120                    pw.println(totalPss - cachedPss);
12121                }
12122            }
12123            if (!isCompact) {
12124                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12125                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12126                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12127                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12128                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12129                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12130                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12131                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12132                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12133                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12134                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12135            }
12136            if (!brief) {
12137                if (memInfo.getZramTotalSizeKb() != 0) {
12138                    if (!isCompact) {
12139                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12140                                pw.print(" kB physical used for ");
12141                                pw.print(memInfo.getSwapTotalSizeKb()
12142                                        - memInfo.getSwapFreeSizeKb());
12143                                pw.print(" kB in swap (");
12144                                pw.print(memInfo.getSwapTotalSizeKb());
12145                                pw.println(" kB total swap)");
12146                    } else {
12147                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12148                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12149                                pw.println(memInfo.getSwapFreeSizeKb());
12150                    }
12151                }
12152                final int[] SINGLE_LONG_FORMAT = new int[] {
12153                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12154                };
12155                long[] longOut = new long[1];
12156                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12157                        SINGLE_LONG_FORMAT, null, longOut, null);
12158                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12159                longOut[0] = 0;
12160                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12161                        SINGLE_LONG_FORMAT, null, longOut, null);
12162                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12163                longOut[0] = 0;
12164                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12165                        SINGLE_LONG_FORMAT, null, longOut, null);
12166                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12167                longOut[0] = 0;
12168                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12169                        SINGLE_LONG_FORMAT, null, longOut, null);
12170                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12171                if (!isCompact) {
12172                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12173                        pw.print("      KSM: "); pw.print(sharing);
12174                                pw.print(" kB saved from shared ");
12175                                pw.print(shared); pw.println(" kB");
12176                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12177                                pw.print(voltile); pw.println(" kB volatile");
12178                    }
12179                    pw.print("   Tuning: ");
12180                    pw.print(ActivityManager.staticGetMemoryClass());
12181                    pw.print(" (large ");
12182                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12183                    pw.print("), oom ");
12184                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12185                    pw.print(" kB");
12186                    pw.print(", restore limit ");
12187                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12188                    pw.print(" kB");
12189                    if (ActivityManager.isLowRamDeviceStatic()) {
12190                        pw.print(" (low-ram)");
12191                    }
12192                    if (ActivityManager.isHighEndGfx()) {
12193                        pw.print(" (high-end-gfx)");
12194                    }
12195                    pw.println();
12196                } else {
12197                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12198                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12199                    pw.println(voltile);
12200                    pw.print("tuning,");
12201                    pw.print(ActivityManager.staticGetMemoryClass());
12202                    pw.print(',');
12203                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12204                    pw.print(',');
12205                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12206                    if (ActivityManager.isLowRamDeviceStatic()) {
12207                        pw.print(",low-ram");
12208                    }
12209                    if (ActivityManager.isHighEndGfx()) {
12210                        pw.print(",high-end-gfx");
12211                    }
12212                    pw.println();
12213                }
12214            }
12215        }
12216    }
12217
12218    /**
12219     * Searches array of arguments for the specified string
12220     * @param args array of argument strings
12221     * @param value value to search for
12222     * @return true if the value is contained in the array
12223     */
12224    private static boolean scanArgs(String[] args, String value) {
12225        if (args != null) {
12226            for (String arg : args) {
12227                if (value.equals(arg)) {
12228                    return true;
12229                }
12230            }
12231        }
12232        return false;
12233    }
12234
12235    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12236            ContentProviderRecord cpr, boolean always) {
12237        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12238
12239        if (!inLaunching || always) {
12240            synchronized (cpr) {
12241                cpr.launchingApp = null;
12242                cpr.notifyAll();
12243            }
12244            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12245            String names[] = cpr.info.authority.split(";");
12246            for (int j = 0; j < names.length; j++) {
12247                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12248            }
12249        }
12250
12251        for (int i=0; i<cpr.connections.size(); i++) {
12252            ContentProviderConnection conn = cpr.connections.get(i);
12253            if (conn.waiting) {
12254                // If this connection is waiting for the provider, then we don't
12255                // need to mess with its process unless we are always removing
12256                // or for some reason the provider is not currently launching.
12257                if (inLaunching && !always) {
12258                    continue;
12259                }
12260            }
12261            ProcessRecord capp = conn.client;
12262            conn.dead = true;
12263            if (conn.stableCount > 0) {
12264                if (!capp.persistent && capp.thread != null
12265                        && capp.pid != 0
12266                        && capp.pid != MY_PID) {
12267                    killUnneededProcessLocked(capp, "depends on provider "
12268                            + cpr.name.flattenToShortString()
12269                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12270                }
12271            } else if (capp.thread != null && conn.provider.provider != null) {
12272                try {
12273                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12274                } catch (RemoteException e) {
12275                }
12276                // In the protocol here, we don't expect the client to correctly
12277                // clean up this connection, we'll just remove it.
12278                cpr.connections.remove(i);
12279                conn.client.conProviders.remove(conn);
12280            }
12281        }
12282
12283        if (inLaunching && always) {
12284            mLaunchingProviders.remove(cpr);
12285        }
12286        return inLaunching;
12287    }
12288
12289    /**
12290     * Main code for cleaning up a process when it has gone away.  This is
12291     * called both as a result of the process dying, or directly when stopping
12292     * a process when running in single process mode.
12293     */
12294    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12295            boolean restarting, boolean allowRestart, int index) {
12296        if (index >= 0) {
12297            removeLruProcessLocked(app);
12298            ProcessList.remove(app.pid);
12299        }
12300
12301        mProcessesToGc.remove(app);
12302        mPendingPssProcesses.remove(app);
12303
12304        // Dismiss any open dialogs.
12305        if (app.crashDialog != null && !app.forceCrashReport) {
12306            app.crashDialog.dismiss();
12307            app.crashDialog = null;
12308        }
12309        if (app.anrDialog != null) {
12310            app.anrDialog.dismiss();
12311            app.anrDialog = null;
12312        }
12313        if (app.waitDialog != null) {
12314            app.waitDialog.dismiss();
12315            app.waitDialog = null;
12316        }
12317
12318        app.crashing = false;
12319        app.notResponding = false;
12320
12321        app.resetPackageList(mProcessStats);
12322        app.unlinkDeathRecipient();
12323        app.makeInactive(mProcessStats);
12324        app.forcingToForeground = null;
12325        app.foregroundServices = false;
12326        app.foregroundActivities = false;
12327        app.hasShownUi = false;
12328        app.hasAboveClient = false;
12329        app.hasClientActivities = false;
12330
12331        mServices.killServicesLocked(app, allowRestart);
12332
12333        boolean restart = false;
12334
12335        // Remove published content providers.
12336        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12337            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12338            final boolean always = app.bad || !allowRestart;
12339            if (removeDyingProviderLocked(app, cpr, always) || always) {
12340                // We left the provider in the launching list, need to
12341                // restart it.
12342                restart = true;
12343            }
12344
12345            cpr.provider = null;
12346            cpr.proc = null;
12347        }
12348        app.pubProviders.clear();
12349
12350        // Take care of any launching providers waiting for this process.
12351        if (checkAppInLaunchingProvidersLocked(app, false)) {
12352            restart = true;
12353        }
12354
12355        // Unregister from connected content providers.
12356        if (!app.conProviders.isEmpty()) {
12357            for (int i=0; i<app.conProviders.size(); i++) {
12358                ContentProviderConnection conn = app.conProviders.get(i);
12359                conn.provider.connections.remove(conn);
12360            }
12361            app.conProviders.clear();
12362        }
12363
12364        // At this point there may be remaining entries in mLaunchingProviders
12365        // where we were the only one waiting, so they are no longer of use.
12366        // Look for these and clean up if found.
12367        // XXX Commented out for now.  Trying to figure out a way to reproduce
12368        // the actual situation to identify what is actually going on.
12369        if (false) {
12370            for (int i=0; i<mLaunchingProviders.size(); i++) {
12371                ContentProviderRecord cpr = (ContentProviderRecord)
12372                        mLaunchingProviders.get(i);
12373                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12374                    synchronized (cpr) {
12375                        cpr.launchingApp = null;
12376                        cpr.notifyAll();
12377                    }
12378                }
12379            }
12380        }
12381
12382        skipCurrentReceiverLocked(app);
12383
12384        // Unregister any receivers.
12385        for (int i=app.receivers.size()-1; i>=0; i--) {
12386            removeReceiverLocked(app.receivers.valueAt(i));
12387        }
12388        app.receivers.clear();
12389
12390        // If the app is undergoing backup, tell the backup manager about it
12391        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12392            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12393                    + mBackupTarget.appInfo + " died during backup");
12394            try {
12395                IBackupManager bm = IBackupManager.Stub.asInterface(
12396                        ServiceManager.getService(Context.BACKUP_SERVICE));
12397                bm.agentDisconnected(app.info.packageName);
12398            } catch (RemoteException e) {
12399                // can't happen; backup manager is local
12400            }
12401        }
12402
12403        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12404            ProcessChangeItem item = mPendingProcessChanges.get(i);
12405            if (item.pid == app.pid) {
12406                mPendingProcessChanges.remove(i);
12407                mAvailProcessChanges.add(item);
12408            }
12409        }
12410        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12411
12412        // If the caller is restarting this app, then leave it in its
12413        // current lists and let the caller take care of it.
12414        if (restarting) {
12415            return;
12416        }
12417
12418        if (!app.persistent || app.isolated) {
12419            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12420                    "Removing non-persistent process during cleanup: " + app);
12421            mProcessNames.remove(app.processName, app.uid);
12422            mIsolatedProcesses.remove(app.uid);
12423            if (mHeavyWeightProcess == app) {
12424                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12425                        mHeavyWeightProcess.userId, 0));
12426                mHeavyWeightProcess = null;
12427            }
12428        } else if (!app.removed) {
12429            // This app is persistent, so we need to keep its record around.
12430            // If it is not already on the pending app list, add it there
12431            // and start a new process for it.
12432            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12433                mPersistentStartingProcesses.add(app);
12434                restart = true;
12435            }
12436        }
12437        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12438                "Clean-up removing on hold: " + app);
12439        mProcessesOnHold.remove(app);
12440
12441        if (app == mHomeProcess) {
12442            mHomeProcess = null;
12443        }
12444        if (app == mPreviousProcess) {
12445            mPreviousProcess = null;
12446        }
12447
12448        if (restart && !app.isolated) {
12449            // We have components that still need to be running in the
12450            // process, so re-launch it.
12451            mProcessNames.put(app.processName, app.uid, app);
12452            startProcessLocked(app, "restart", app.processName);
12453        } else if (app.pid > 0 && app.pid != MY_PID) {
12454            // Goodbye!
12455            synchronized (mPidsSelfLocked) {
12456                mPidsSelfLocked.remove(app.pid);
12457                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12458            }
12459            app.setPid(0);
12460        }
12461    }
12462
12463    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12464        // Look through the content providers we are waiting to have launched,
12465        // and if any run in this process then either schedule a restart of
12466        // the process or kill the client waiting for it if this process has
12467        // gone bad.
12468        int NL = mLaunchingProviders.size();
12469        boolean restart = false;
12470        for (int i=0; i<NL; i++) {
12471            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12472            if (cpr.launchingApp == app) {
12473                if (!alwaysBad && !app.bad) {
12474                    restart = true;
12475                } else {
12476                    removeDyingProviderLocked(app, cpr, true);
12477                    // cpr should have been removed from mLaunchingProviders
12478                    NL = mLaunchingProviders.size();
12479                    i--;
12480                }
12481            }
12482        }
12483        return restart;
12484    }
12485
12486    // =========================================================
12487    // SERVICES
12488    // =========================================================
12489
12490    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12491            int flags) {
12492        enforceNotIsolatedCaller("getServices");
12493        synchronized (this) {
12494            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12495        }
12496    }
12497
12498    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12499        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12500        synchronized (this) {
12501            return mServices.getRunningServiceControlPanelLocked(name);
12502        }
12503    }
12504
12505    public ComponentName startService(IApplicationThread caller, Intent service,
12506            String resolvedType, int userId) {
12507        enforceNotIsolatedCaller("startService");
12508        // Refuse possible leaked file descriptors
12509        if (service != null && service.hasFileDescriptors() == true) {
12510            throw new IllegalArgumentException("File descriptors passed in Intent");
12511        }
12512
12513        if (DEBUG_SERVICE)
12514            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12515        synchronized(this) {
12516            final int callingPid = Binder.getCallingPid();
12517            final int callingUid = Binder.getCallingUid();
12518            final long origId = Binder.clearCallingIdentity();
12519            ComponentName res = mServices.startServiceLocked(caller, service,
12520                    resolvedType, callingPid, callingUid, userId);
12521            Binder.restoreCallingIdentity(origId);
12522            return res;
12523        }
12524    }
12525
12526    ComponentName startServiceInPackage(int uid,
12527            Intent service, String resolvedType, int userId) {
12528        synchronized(this) {
12529            if (DEBUG_SERVICE)
12530                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12531            final long origId = Binder.clearCallingIdentity();
12532            ComponentName res = mServices.startServiceLocked(null, service,
12533                    resolvedType, -1, uid, userId);
12534            Binder.restoreCallingIdentity(origId);
12535            return res;
12536        }
12537    }
12538
12539    public int stopService(IApplicationThread caller, Intent service,
12540            String resolvedType, int userId) {
12541        enforceNotIsolatedCaller("stopService");
12542        // Refuse possible leaked file descriptors
12543        if (service != null && service.hasFileDescriptors() == true) {
12544            throw new IllegalArgumentException("File descriptors passed in Intent");
12545        }
12546
12547        synchronized(this) {
12548            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12549        }
12550    }
12551
12552    public IBinder peekService(Intent service, String resolvedType) {
12553        enforceNotIsolatedCaller("peekService");
12554        // Refuse possible leaked file descriptors
12555        if (service != null && service.hasFileDescriptors() == true) {
12556            throw new IllegalArgumentException("File descriptors passed in Intent");
12557        }
12558        synchronized(this) {
12559            return mServices.peekServiceLocked(service, resolvedType);
12560        }
12561    }
12562
12563    public boolean stopServiceToken(ComponentName className, IBinder token,
12564            int startId) {
12565        synchronized(this) {
12566            return mServices.stopServiceTokenLocked(className, token, startId);
12567        }
12568    }
12569
12570    public void setServiceForeground(ComponentName className, IBinder token,
12571            int id, Notification notification, boolean removeNotification) {
12572        synchronized(this) {
12573            mServices.setServiceForegroundLocked(className, token, id, notification,
12574                    removeNotification);
12575        }
12576    }
12577
12578    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12579            boolean requireFull, String name, String callerPackage) {
12580        final int callingUserId = UserHandle.getUserId(callingUid);
12581        if (callingUserId != userId) {
12582            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12583                if ((requireFull || checkComponentPermission(
12584                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12585                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12586                        && checkComponentPermission(
12587                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12588                                callingPid, callingUid, -1, true)
12589                                != PackageManager.PERMISSION_GRANTED) {
12590                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12591                        // In this case, they would like to just execute as their
12592                        // owner user instead of failing.
12593                        userId = callingUserId;
12594                    } else {
12595                        StringBuilder builder = new StringBuilder(128);
12596                        builder.append("Permission Denial: ");
12597                        builder.append(name);
12598                        if (callerPackage != null) {
12599                            builder.append(" from ");
12600                            builder.append(callerPackage);
12601                        }
12602                        builder.append(" asks to run as user ");
12603                        builder.append(userId);
12604                        builder.append(" but is calling from user ");
12605                        builder.append(UserHandle.getUserId(callingUid));
12606                        builder.append("; this requires ");
12607                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12608                        if (!requireFull) {
12609                            builder.append(" or ");
12610                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12611                        }
12612                        String msg = builder.toString();
12613                        Slog.w(TAG, msg);
12614                        throw new SecurityException(msg);
12615                    }
12616                }
12617            }
12618            if (userId == UserHandle.USER_CURRENT
12619                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12620                // Note that we may be accessing this outside of a lock...
12621                // shouldn't be a big deal, if this is being called outside
12622                // of a locked context there is intrinsically a race with
12623                // the value the caller will receive and someone else changing it.
12624                userId = mCurrentUserId;
12625            }
12626            if (!allowAll && userId < 0) {
12627                throw new IllegalArgumentException(
12628                        "Call does not support special user #" + userId);
12629            }
12630        }
12631        return userId;
12632    }
12633
12634    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12635            String className, int flags) {
12636        boolean result = false;
12637        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12638            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12639                if (ActivityManager.checkUidPermission(
12640                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12641                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12642                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12643                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12644                            + " requests FLAG_SINGLE_USER, but app does not hold "
12645                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12646                    Slog.w(TAG, msg);
12647                    throw new SecurityException(msg);
12648                }
12649                result = true;
12650            }
12651        } else if (componentProcessName == aInfo.packageName) {
12652            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12653        } else if ("system".equals(componentProcessName)) {
12654            result = true;
12655        }
12656        if (DEBUG_MU) {
12657            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12658                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12659        }
12660        return result;
12661    }
12662
12663    public int bindService(IApplicationThread caller, IBinder token,
12664            Intent service, String resolvedType,
12665            IServiceConnection connection, int flags, int userId) {
12666        enforceNotIsolatedCaller("bindService");
12667        // Refuse possible leaked file descriptors
12668        if (service != null && service.hasFileDescriptors() == true) {
12669            throw new IllegalArgumentException("File descriptors passed in Intent");
12670        }
12671
12672        synchronized(this) {
12673            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12674                    connection, flags, userId);
12675        }
12676    }
12677
12678    public boolean unbindService(IServiceConnection connection) {
12679        synchronized (this) {
12680            return mServices.unbindServiceLocked(connection);
12681        }
12682    }
12683
12684    public void publishService(IBinder token, Intent intent, IBinder service) {
12685        // Refuse possible leaked file descriptors
12686        if (intent != null && intent.hasFileDescriptors() == true) {
12687            throw new IllegalArgumentException("File descriptors passed in Intent");
12688        }
12689
12690        synchronized(this) {
12691            if (!(token instanceof ServiceRecord)) {
12692                throw new IllegalArgumentException("Invalid service token");
12693            }
12694            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12695        }
12696    }
12697
12698    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12699        // Refuse possible leaked file descriptors
12700        if (intent != null && intent.hasFileDescriptors() == true) {
12701            throw new IllegalArgumentException("File descriptors passed in Intent");
12702        }
12703
12704        synchronized(this) {
12705            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12706        }
12707    }
12708
12709    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12710        synchronized(this) {
12711            if (!(token instanceof ServiceRecord)) {
12712                throw new IllegalArgumentException("Invalid service token");
12713            }
12714            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12715        }
12716    }
12717
12718    // =========================================================
12719    // BACKUP AND RESTORE
12720    // =========================================================
12721
12722    // Cause the target app to be launched if necessary and its backup agent
12723    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12724    // activity manager to announce its creation.
12725    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12726        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12727        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12728
12729        synchronized(this) {
12730            // !!! TODO: currently no check here that we're already bound
12731            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12732            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12733            synchronized (stats) {
12734                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12735            }
12736
12737            // Backup agent is now in use, its package can't be stopped.
12738            try {
12739                AppGlobals.getPackageManager().setPackageStoppedState(
12740                        app.packageName, false, UserHandle.getUserId(app.uid));
12741            } catch (RemoteException e) {
12742            } catch (IllegalArgumentException e) {
12743                Slog.w(TAG, "Failed trying to unstop package "
12744                        + app.packageName + ": " + e);
12745            }
12746
12747            BackupRecord r = new BackupRecord(ss, app, backupMode);
12748            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12749                    ? new ComponentName(app.packageName, app.backupAgentName)
12750                    : new ComponentName("android", "FullBackupAgent");
12751            // startProcessLocked() returns existing proc's record if it's already running
12752            ProcessRecord proc = startProcessLocked(app.processName, app,
12753                    false, 0, "backup", hostingName, false, false, false);
12754            if (proc == null) {
12755                Slog.e(TAG, "Unable to start backup agent process " + r);
12756                return false;
12757            }
12758
12759            r.app = proc;
12760            mBackupTarget = r;
12761            mBackupAppName = app.packageName;
12762
12763            // Try not to kill the process during backup
12764            updateOomAdjLocked(proc);
12765
12766            // If the process is already attached, schedule the creation of the backup agent now.
12767            // If it is not yet live, this will be done when it attaches to the framework.
12768            if (proc.thread != null) {
12769                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12770                try {
12771                    proc.thread.scheduleCreateBackupAgent(app,
12772                            compatibilityInfoForPackageLocked(app), backupMode);
12773                } catch (RemoteException e) {
12774                    // Will time out on the backup manager side
12775                }
12776            } else {
12777                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12778            }
12779            // Invariants: at this point, the target app process exists and the application
12780            // is either already running or in the process of coming up.  mBackupTarget and
12781            // mBackupAppName describe the app, so that when it binds back to the AM we
12782            // know that it's scheduled for a backup-agent operation.
12783        }
12784
12785        return true;
12786    }
12787
12788    @Override
12789    public void clearPendingBackup() {
12790        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12791        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12792
12793        synchronized (this) {
12794            mBackupTarget = null;
12795            mBackupAppName = null;
12796        }
12797    }
12798
12799    // A backup agent has just come up
12800    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12801        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12802                + " = " + agent);
12803
12804        synchronized(this) {
12805            if (!agentPackageName.equals(mBackupAppName)) {
12806                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12807                return;
12808            }
12809        }
12810
12811        long oldIdent = Binder.clearCallingIdentity();
12812        try {
12813            IBackupManager bm = IBackupManager.Stub.asInterface(
12814                    ServiceManager.getService(Context.BACKUP_SERVICE));
12815            bm.agentConnected(agentPackageName, agent);
12816        } catch (RemoteException e) {
12817            // can't happen; the backup manager service is local
12818        } catch (Exception e) {
12819            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12820            e.printStackTrace();
12821        } finally {
12822            Binder.restoreCallingIdentity(oldIdent);
12823        }
12824    }
12825
12826    // done with this agent
12827    public void unbindBackupAgent(ApplicationInfo appInfo) {
12828        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12829        if (appInfo == null) {
12830            Slog.w(TAG, "unbind backup agent for null app");
12831            return;
12832        }
12833
12834        synchronized(this) {
12835            try {
12836                if (mBackupAppName == null) {
12837                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12838                    return;
12839                }
12840
12841                if (!mBackupAppName.equals(appInfo.packageName)) {
12842                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12843                    return;
12844                }
12845
12846                // Not backing this app up any more; reset its OOM adjustment
12847                final ProcessRecord proc = mBackupTarget.app;
12848                updateOomAdjLocked(proc);
12849
12850                // If the app crashed during backup, 'thread' will be null here
12851                if (proc.thread != null) {
12852                    try {
12853                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12854                                compatibilityInfoForPackageLocked(appInfo));
12855                    } catch (Exception e) {
12856                        Slog.e(TAG, "Exception when unbinding backup agent:");
12857                        e.printStackTrace();
12858                    }
12859                }
12860            } finally {
12861                mBackupTarget = null;
12862                mBackupAppName = null;
12863            }
12864        }
12865    }
12866    // =========================================================
12867    // BROADCASTS
12868    // =========================================================
12869
12870    private final List getStickiesLocked(String action, IntentFilter filter,
12871            List cur, int userId) {
12872        final ContentResolver resolver = mContext.getContentResolver();
12873        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12874        if (stickies == null) {
12875            return cur;
12876        }
12877        final ArrayList<Intent> list = stickies.get(action);
12878        if (list == null) {
12879            return cur;
12880        }
12881        int N = list.size();
12882        for (int i=0; i<N; i++) {
12883            Intent intent = list.get(i);
12884            if (filter.match(resolver, intent, true, TAG) >= 0) {
12885                if (cur == null) {
12886                    cur = new ArrayList<Intent>();
12887                }
12888                cur.add(intent);
12889            }
12890        }
12891        return cur;
12892    }
12893
12894    boolean isPendingBroadcastProcessLocked(int pid) {
12895        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12896                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12897    }
12898
12899    void skipPendingBroadcastLocked(int pid) {
12900            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12901            for (BroadcastQueue queue : mBroadcastQueues) {
12902                queue.skipPendingBroadcastLocked(pid);
12903            }
12904    }
12905
12906    // The app just attached; send any pending broadcasts that it should receive
12907    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12908        boolean didSomething = false;
12909        for (BroadcastQueue queue : mBroadcastQueues) {
12910            didSomething |= queue.sendPendingBroadcastsLocked(app);
12911        }
12912        return didSomething;
12913    }
12914
12915    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12916            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12917        enforceNotIsolatedCaller("registerReceiver");
12918        int callingUid;
12919        int callingPid;
12920        synchronized(this) {
12921            ProcessRecord callerApp = null;
12922            if (caller != null) {
12923                callerApp = getRecordForAppLocked(caller);
12924                if (callerApp == null) {
12925                    throw new SecurityException(
12926                            "Unable to find app for caller " + caller
12927                            + " (pid=" + Binder.getCallingPid()
12928                            + ") when registering receiver " + receiver);
12929                }
12930                if (callerApp.info.uid != Process.SYSTEM_UID &&
12931                        !callerApp.pkgList.containsKey(callerPackage) &&
12932                        !"android".equals(callerPackage)) {
12933                    throw new SecurityException("Given caller package " + callerPackage
12934                            + " is not running in process " + callerApp);
12935                }
12936                callingUid = callerApp.info.uid;
12937                callingPid = callerApp.pid;
12938            } else {
12939                callerPackage = null;
12940                callingUid = Binder.getCallingUid();
12941                callingPid = Binder.getCallingPid();
12942            }
12943
12944            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12945                    true, true, "registerReceiver", callerPackage);
12946
12947            List allSticky = null;
12948
12949            // Look for any matching sticky broadcasts...
12950            Iterator actions = filter.actionsIterator();
12951            if (actions != null) {
12952                while (actions.hasNext()) {
12953                    String action = (String)actions.next();
12954                    allSticky = getStickiesLocked(action, filter, allSticky,
12955                            UserHandle.USER_ALL);
12956                    allSticky = getStickiesLocked(action, filter, allSticky,
12957                            UserHandle.getUserId(callingUid));
12958                }
12959            } else {
12960                allSticky = getStickiesLocked(null, filter, allSticky,
12961                        UserHandle.USER_ALL);
12962                allSticky = getStickiesLocked(null, filter, allSticky,
12963                        UserHandle.getUserId(callingUid));
12964            }
12965
12966            // The first sticky in the list is returned directly back to
12967            // the client.
12968            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12969
12970            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12971                    + ": " + sticky);
12972
12973            if (receiver == null) {
12974                return sticky;
12975            }
12976
12977            ReceiverList rl
12978                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12979            if (rl == null) {
12980                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
12981                        userId, receiver);
12982                if (rl.app != null) {
12983                    rl.app.receivers.add(rl);
12984                } else {
12985                    try {
12986                        receiver.asBinder().linkToDeath(rl, 0);
12987                    } catch (RemoteException e) {
12988                        return sticky;
12989                    }
12990                    rl.linkedToDeath = true;
12991                }
12992                mRegisteredReceivers.put(receiver.asBinder(), rl);
12993            } else if (rl.uid != callingUid) {
12994                throw new IllegalArgumentException(
12995                        "Receiver requested to register for uid " + callingUid
12996                        + " was previously registered for uid " + rl.uid);
12997            } else if (rl.pid != callingPid) {
12998                throw new IllegalArgumentException(
12999                        "Receiver requested to register for pid " + callingPid
13000                        + " was previously registered for pid " + rl.pid);
13001            } else if (rl.userId != userId) {
13002                throw new IllegalArgumentException(
13003                        "Receiver requested to register for user " + userId
13004                        + " was previously registered for user " + rl.userId);
13005            }
13006            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13007                    permission, callingUid, userId);
13008            rl.add(bf);
13009            if (!bf.debugCheck()) {
13010                Slog.w(TAG, "==> For Dynamic broadast");
13011            }
13012            mReceiverResolver.addFilter(bf);
13013
13014            // Enqueue broadcasts for all existing stickies that match
13015            // this filter.
13016            if (allSticky != null) {
13017                ArrayList receivers = new ArrayList();
13018                receivers.add(bf);
13019
13020                int N = allSticky.size();
13021                for (int i=0; i<N; i++) {
13022                    Intent intent = (Intent)allSticky.get(i);
13023                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13024                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13025                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13026                            null, null, false, true, true, -1);
13027                    queue.enqueueParallelBroadcastLocked(r);
13028                    queue.scheduleBroadcastsLocked();
13029                }
13030            }
13031
13032            return sticky;
13033        }
13034    }
13035
13036    public void unregisterReceiver(IIntentReceiver receiver) {
13037        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13038
13039        final long origId = Binder.clearCallingIdentity();
13040        try {
13041            boolean doTrim = false;
13042
13043            synchronized(this) {
13044                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13045                if (rl != null) {
13046                    if (rl.curBroadcast != null) {
13047                        BroadcastRecord r = rl.curBroadcast;
13048                        final boolean doNext = finishReceiverLocked(
13049                                receiver.asBinder(), r.resultCode, r.resultData,
13050                                r.resultExtras, r.resultAbort);
13051                        if (doNext) {
13052                            doTrim = true;
13053                            r.queue.processNextBroadcast(false);
13054                        }
13055                    }
13056
13057                    if (rl.app != null) {
13058                        rl.app.receivers.remove(rl);
13059                    }
13060                    removeReceiverLocked(rl);
13061                    if (rl.linkedToDeath) {
13062                        rl.linkedToDeath = false;
13063                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13064                    }
13065                }
13066            }
13067
13068            // If we actually concluded any broadcasts, we might now be able
13069            // to trim the recipients' apps from our working set
13070            if (doTrim) {
13071                trimApplications();
13072                return;
13073            }
13074
13075        } finally {
13076            Binder.restoreCallingIdentity(origId);
13077        }
13078    }
13079
13080    void removeReceiverLocked(ReceiverList rl) {
13081        mRegisteredReceivers.remove(rl.receiver.asBinder());
13082        int N = rl.size();
13083        for (int i=0; i<N; i++) {
13084            mReceiverResolver.removeFilter(rl.get(i));
13085        }
13086    }
13087
13088    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13089        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13090            ProcessRecord r = mLruProcesses.get(i);
13091            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13092                try {
13093                    r.thread.dispatchPackageBroadcast(cmd, packages);
13094                } catch (RemoteException ex) {
13095                }
13096            }
13097        }
13098    }
13099
13100    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13101            int[] users) {
13102        List<ResolveInfo> receivers = null;
13103        try {
13104            HashSet<ComponentName> singleUserReceivers = null;
13105            boolean scannedFirstReceivers = false;
13106            for (int user : users) {
13107                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13108                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13109                if (user != 0 && newReceivers != null) {
13110                    // If this is not the primary user, we need to check for
13111                    // any receivers that should be filtered out.
13112                    for (int i=0; i<newReceivers.size(); i++) {
13113                        ResolveInfo ri = newReceivers.get(i);
13114                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13115                            newReceivers.remove(i);
13116                            i--;
13117                        }
13118                    }
13119                }
13120                if (newReceivers != null && newReceivers.size() == 0) {
13121                    newReceivers = null;
13122                }
13123                if (receivers == null) {
13124                    receivers = newReceivers;
13125                } else if (newReceivers != null) {
13126                    // We need to concatenate the additional receivers
13127                    // found with what we have do far.  This would be easy,
13128                    // but we also need to de-dup any receivers that are
13129                    // singleUser.
13130                    if (!scannedFirstReceivers) {
13131                        // Collect any single user receivers we had already retrieved.
13132                        scannedFirstReceivers = true;
13133                        for (int i=0; i<receivers.size(); i++) {
13134                            ResolveInfo ri = receivers.get(i);
13135                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13136                                ComponentName cn = new ComponentName(
13137                                        ri.activityInfo.packageName, ri.activityInfo.name);
13138                                if (singleUserReceivers == null) {
13139                                    singleUserReceivers = new HashSet<ComponentName>();
13140                                }
13141                                singleUserReceivers.add(cn);
13142                            }
13143                        }
13144                    }
13145                    // Add the new results to the existing results, tracking
13146                    // and de-dupping single user receivers.
13147                    for (int i=0; i<newReceivers.size(); i++) {
13148                        ResolveInfo ri = newReceivers.get(i);
13149                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13150                            ComponentName cn = new ComponentName(
13151                                    ri.activityInfo.packageName, ri.activityInfo.name);
13152                            if (singleUserReceivers == null) {
13153                                singleUserReceivers = new HashSet<ComponentName>();
13154                            }
13155                            if (!singleUserReceivers.contains(cn)) {
13156                                singleUserReceivers.add(cn);
13157                                receivers.add(ri);
13158                            }
13159                        } else {
13160                            receivers.add(ri);
13161                        }
13162                    }
13163                }
13164            }
13165        } catch (RemoteException ex) {
13166            // pm is in same process, this will never happen.
13167        }
13168        return receivers;
13169    }
13170
13171    private final int broadcastIntentLocked(ProcessRecord callerApp,
13172            String callerPackage, Intent intent, String resolvedType,
13173            IIntentReceiver resultTo, int resultCode, String resultData,
13174            Bundle map, String requiredPermission, int appOp,
13175            boolean ordered, boolean sticky, int callingPid, int callingUid,
13176            int userId) {
13177        intent = new Intent(intent);
13178
13179        // By default broadcasts do not go to stopped apps.
13180        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13181
13182        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13183            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13184            + " ordered=" + ordered + " userid=" + userId);
13185        if ((resultTo != null) && !ordered) {
13186            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13187        }
13188
13189        userId = handleIncomingUser(callingPid, callingUid, userId,
13190                true, false, "broadcast", callerPackage);
13191
13192        // Make sure that the user who is receiving this broadcast is started.
13193        // If not, we will just skip it.
13194        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13195            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13196                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13197                Slog.w(TAG, "Skipping broadcast of " + intent
13198                        + ": user " + userId + " is stopped");
13199                return ActivityManager.BROADCAST_SUCCESS;
13200            }
13201        }
13202
13203        /*
13204         * Prevent non-system code (defined here to be non-persistent
13205         * processes) from sending protected broadcasts.
13206         */
13207        int callingAppId = UserHandle.getAppId(callingUid);
13208        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13209            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13210            callingUid == 0) {
13211            // Always okay.
13212        } else if (callerApp == null || !callerApp.persistent) {
13213            try {
13214                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13215                        intent.getAction())) {
13216                    String msg = "Permission Denial: not allowed to send broadcast "
13217                            + intent.getAction() + " from pid="
13218                            + callingPid + ", uid=" + callingUid;
13219                    Slog.w(TAG, msg);
13220                    throw new SecurityException(msg);
13221                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13222                    // Special case for compatibility: we don't want apps to send this,
13223                    // but historically it has not been protected and apps may be using it
13224                    // to poke their own app widget.  So, instead of making it protected,
13225                    // just limit it to the caller.
13226                    if (callerApp == null) {
13227                        String msg = "Permission Denial: not allowed to send broadcast "
13228                                + intent.getAction() + " from unknown caller.";
13229                        Slog.w(TAG, msg);
13230                        throw new SecurityException(msg);
13231                    } else if (intent.getComponent() != null) {
13232                        // They are good enough to send to an explicit component...  verify
13233                        // it is being sent to the calling app.
13234                        if (!intent.getComponent().getPackageName().equals(
13235                                callerApp.info.packageName)) {
13236                            String msg = "Permission Denial: not allowed to send broadcast "
13237                                    + intent.getAction() + " to "
13238                                    + intent.getComponent().getPackageName() + " from "
13239                                    + callerApp.info.packageName;
13240                            Slog.w(TAG, msg);
13241                            throw new SecurityException(msg);
13242                        }
13243                    } else {
13244                        // Limit broadcast to their own package.
13245                        intent.setPackage(callerApp.info.packageName);
13246                    }
13247                }
13248            } catch (RemoteException e) {
13249                Slog.w(TAG, "Remote exception", e);
13250                return ActivityManager.BROADCAST_SUCCESS;
13251            }
13252        }
13253
13254        // Handle special intents: if this broadcast is from the package
13255        // manager about a package being removed, we need to remove all of
13256        // its activities from the history stack.
13257        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13258                intent.getAction());
13259        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13260                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13261                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13262                || uidRemoved) {
13263            if (checkComponentPermission(
13264                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13265                    callingPid, callingUid, -1, true)
13266                    == PackageManager.PERMISSION_GRANTED) {
13267                if (uidRemoved) {
13268                    final Bundle intentExtras = intent.getExtras();
13269                    final int uid = intentExtras != null
13270                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13271                    if (uid >= 0) {
13272                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13273                        synchronized (bs) {
13274                            bs.removeUidStatsLocked(uid);
13275                        }
13276                        mAppOpsService.uidRemoved(uid);
13277                    }
13278                } else {
13279                    // If resources are unavailable just force stop all
13280                    // those packages and flush the attribute cache as well.
13281                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13282                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13283                        if (list != null && (list.length > 0)) {
13284                            for (String pkg : list) {
13285                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
13286                                        "storage unmount");
13287                            }
13288                            sendPackageBroadcastLocked(
13289                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13290                        }
13291                    } else {
13292                        Uri data = intent.getData();
13293                        String ssp;
13294                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13295                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13296                                    intent.getAction());
13297                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13298                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13299                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13300                                        false, userId, removed ? "pkg removed" : "pkg changed");
13301                            }
13302                            if (removed) {
13303                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13304                                        new String[] {ssp}, userId);
13305                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13306                                    mAppOpsService.packageRemoved(
13307                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13308
13309                                    // Remove all permissions granted from/to this package
13310                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13311                                }
13312                            }
13313                        }
13314                    }
13315                }
13316            } else {
13317                String msg = "Permission Denial: " + intent.getAction()
13318                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13319                        + ", uid=" + callingUid + ")"
13320                        + " requires "
13321                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13322                Slog.w(TAG, msg);
13323                throw new SecurityException(msg);
13324            }
13325
13326        // Special case for adding a package: by default turn on compatibility
13327        // mode.
13328        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13329            Uri data = intent.getData();
13330            String ssp;
13331            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13332                mCompatModePackages.handlePackageAddedLocked(ssp,
13333                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13334            }
13335        }
13336
13337        /*
13338         * If this is the time zone changed action, queue up a message that will reset the timezone
13339         * of all currently running processes. This message will get queued up before the broadcast
13340         * happens.
13341         */
13342        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13343            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13344        }
13345
13346        /*
13347         * If the user set the time, let all running processes know.
13348         */
13349        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13350            final int is24Hour = intent.getBooleanExtra(
13351                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13352            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13353        }
13354
13355        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13356            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13357        }
13358
13359        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13360            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13361            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13362        }
13363
13364        // Add to the sticky list if requested.
13365        if (sticky) {
13366            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13367                    callingPid, callingUid)
13368                    != PackageManager.PERMISSION_GRANTED) {
13369                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13370                        + callingPid + ", uid=" + callingUid
13371                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13372                Slog.w(TAG, msg);
13373                throw new SecurityException(msg);
13374            }
13375            if (requiredPermission != null) {
13376                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13377                        + " and enforce permission " + requiredPermission);
13378                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13379            }
13380            if (intent.getComponent() != null) {
13381                throw new SecurityException(
13382                        "Sticky broadcasts can't target a specific component");
13383            }
13384            // We use userId directly here, since the "all" target is maintained
13385            // as a separate set of sticky broadcasts.
13386            if (userId != UserHandle.USER_ALL) {
13387                // But first, if this is not a broadcast to all users, then
13388                // make sure it doesn't conflict with an existing broadcast to
13389                // all users.
13390                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13391                        UserHandle.USER_ALL);
13392                if (stickies != null) {
13393                    ArrayList<Intent> list = stickies.get(intent.getAction());
13394                    if (list != null) {
13395                        int N = list.size();
13396                        int i;
13397                        for (i=0; i<N; i++) {
13398                            if (intent.filterEquals(list.get(i))) {
13399                                throw new IllegalArgumentException(
13400                                        "Sticky broadcast " + intent + " for user "
13401                                        + userId + " conflicts with existing global broadcast");
13402                            }
13403                        }
13404                    }
13405                }
13406            }
13407            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13408            if (stickies == null) {
13409                stickies = new ArrayMap<String, ArrayList<Intent>>();
13410                mStickyBroadcasts.put(userId, stickies);
13411            }
13412            ArrayList<Intent> list = stickies.get(intent.getAction());
13413            if (list == null) {
13414                list = new ArrayList<Intent>();
13415                stickies.put(intent.getAction(), list);
13416            }
13417            int N = list.size();
13418            int i;
13419            for (i=0; i<N; i++) {
13420                if (intent.filterEquals(list.get(i))) {
13421                    // This sticky already exists, replace it.
13422                    list.set(i, new Intent(intent));
13423                    break;
13424                }
13425            }
13426            if (i >= N) {
13427                list.add(new Intent(intent));
13428            }
13429        }
13430
13431        int[] users;
13432        if (userId == UserHandle.USER_ALL) {
13433            // Caller wants broadcast to go to all started users.
13434            users = mStartedUserArray;
13435        } else {
13436            // Caller wants broadcast to go to one specific user.
13437            users = new int[] {userId};
13438        }
13439
13440        // Figure out who all will receive this broadcast.
13441        List receivers = null;
13442        List<BroadcastFilter> registeredReceivers = null;
13443        // Need to resolve the intent to interested receivers...
13444        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13445                 == 0) {
13446            receivers = collectReceiverComponents(intent, resolvedType, users);
13447        }
13448        if (intent.getComponent() == null) {
13449            registeredReceivers = mReceiverResolver.queryIntent(intent,
13450                    resolvedType, false, userId);
13451        }
13452
13453        final boolean replacePending =
13454                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13455
13456        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13457                + " replacePending=" + replacePending);
13458
13459        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13460        if (!ordered && NR > 0) {
13461            // If we are not serializing this broadcast, then send the
13462            // registered receivers separately so they don't wait for the
13463            // components to be launched.
13464            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13465            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13466                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13467                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13468                    ordered, sticky, false, userId);
13469            if (DEBUG_BROADCAST) Slog.v(
13470                    TAG, "Enqueueing parallel broadcast " + r);
13471            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13472            if (!replaced) {
13473                queue.enqueueParallelBroadcastLocked(r);
13474                queue.scheduleBroadcastsLocked();
13475            }
13476            registeredReceivers = null;
13477            NR = 0;
13478        }
13479
13480        // Merge into one list.
13481        int ir = 0;
13482        if (receivers != null) {
13483            // A special case for PACKAGE_ADDED: do not allow the package
13484            // being added to see this broadcast.  This prevents them from
13485            // using this as a back door to get run as soon as they are
13486            // installed.  Maybe in the future we want to have a special install
13487            // broadcast or such for apps, but we'd like to deliberately make
13488            // this decision.
13489            String skipPackages[] = null;
13490            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13491                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13492                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13493                Uri data = intent.getData();
13494                if (data != null) {
13495                    String pkgName = data.getSchemeSpecificPart();
13496                    if (pkgName != null) {
13497                        skipPackages = new String[] { pkgName };
13498                    }
13499                }
13500            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13501                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13502            }
13503            if (skipPackages != null && (skipPackages.length > 0)) {
13504                for (String skipPackage : skipPackages) {
13505                    if (skipPackage != null) {
13506                        int NT = receivers.size();
13507                        for (int it=0; it<NT; it++) {
13508                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13509                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13510                                receivers.remove(it);
13511                                it--;
13512                                NT--;
13513                            }
13514                        }
13515                    }
13516                }
13517            }
13518
13519            int NT = receivers != null ? receivers.size() : 0;
13520            int it = 0;
13521            ResolveInfo curt = null;
13522            BroadcastFilter curr = null;
13523            while (it < NT && ir < NR) {
13524                if (curt == null) {
13525                    curt = (ResolveInfo)receivers.get(it);
13526                }
13527                if (curr == null) {
13528                    curr = registeredReceivers.get(ir);
13529                }
13530                if (curr.getPriority() >= curt.priority) {
13531                    // Insert this broadcast record into the final list.
13532                    receivers.add(it, curr);
13533                    ir++;
13534                    curr = null;
13535                    it++;
13536                    NT++;
13537                } else {
13538                    // Skip to the next ResolveInfo in the final list.
13539                    it++;
13540                    curt = null;
13541                }
13542            }
13543        }
13544        while (ir < NR) {
13545            if (receivers == null) {
13546                receivers = new ArrayList();
13547            }
13548            receivers.add(registeredReceivers.get(ir));
13549            ir++;
13550        }
13551
13552        if ((receivers != null && receivers.size() > 0)
13553                || resultTo != null) {
13554            BroadcastQueue queue = broadcastQueueForIntent(intent);
13555            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13556                    callerPackage, callingPid, callingUid, resolvedType,
13557                    requiredPermission, appOp, receivers, resultTo, resultCode,
13558                    resultData, map, ordered, sticky, false, userId);
13559            if (DEBUG_BROADCAST) Slog.v(
13560                    TAG, "Enqueueing ordered broadcast " + r
13561                    + ": prev had " + queue.mOrderedBroadcasts.size());
13562            if (DEBUG_BROADCAST) {
13563                int seq = r.intent.getIntExtra("seq", -1);
13564                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13565            }
13566            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13567            if (!replaced) {
13568                queue.enqueueOrderedBroadcastLocked(r);
13569                queue.scheduleBroadcastsLocked();
13570            }
13571        }
13572
13573        return ActivityManager.BROADCAST_SUCCESS;
13574    }
13575
13576    final Intent verifyBroadcastLocked(Intent intent) {
13577        // Refuse possible leaked file descriptors
13578        if (intent != null && intent.hasFileDescriptors() == true) {
13579            throw new IllegalArgumentException("File descriptors passed in Intent");
13580        }
13581
13582        int flags = intent.getFlags();
13583
13584        if (!mProcessesReady) {
13585            // if the caller really truly claims to know what they're doing, go
13586            // ahead and allow the broadcast without launching any receivers
13587            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13588                intent = new Intent(intent);
13589                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13590            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13591                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13592                        + " before boot completion");
13593                throw new IllegalStateException("Cannot broadcast before boot completed");
13594            }
13595        }
13596
13597        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13598            throw new IllegalArgumentException(
13599                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13600        }
13601
13602        return intent;
13603    }
13604
13605    public final int broadcastIntent(IApplicationThread caller,
13606            Intent intent, String resolvedType, IIntentReceiver resultTo,
13607            int resultCode, String resultData, Bundle map,
13608            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13609        enforceNotIsolatedCaller("broadcastIntent");
13610        synchronized(this) {
13611            intent = verifyBroadcastLocked(intent);
13612
13613            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13614            final int callingPid = Binder.getCallingPid();
13615            final int callingUid = Binder.getCallingUid();
13616            final long origId = Binder.clearCallingIdentity();
13617            int res = broadcastIntentLocked(callerApp,
13618                    callerApp != null ? callerApp.info.packageName : null,
13619                    intent, resolvedType, resultTo,
13620                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13621                    callingPid, callingUid, userId);
13622            Binder.restoreCallingIdentity(origId);
13623            return res;
13624        }
13625    }
13626
13627    int broadcastIntentInPackage(String packageName, int uid,
13628            Intent intent, String resolvedType, IIntentReceiver resultTo,
13629            int resultCode, String resultData, Bundle map,
13630            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13631        synchronized(this) {
13632            intent = verifyBroadcastLocked(intent);
13633
13634            final long origId = Binder.clearCallingIdentity();
13635            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13636                    resultTo, resultCode, resultData, map, requiredPermission,
13637                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13638            Binder.restoreCallingIdentity(origId);
13639            return res;
13640        }
13641    }
13642
13643    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13644        // Refuse possible leaked file descriptors
13645        if (intent != null && intent.hasFileDescriptors() == true) {
13646            throw new IllegalArgumentException("File descriptors passed in Intent");
13647        }
13648
13649        userId = handleIncomingUser(Binder.getCallingPid(),
13650                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13651
13652        synchronized(this) {
13653            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13654                    != PackageManager.PERMISSION_GRANTED) {
13655                String msg = "Permission Denial: unbroadcastIntent() from pid="
13656                        + Binder.getCallingPid()
13657                        + ", uid=" + Binder.getCallingUid()
13658                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13659                Slog.w(TAG, msg);
13660                throw new SecurityException(msg);
13661            }
13662            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13663            if (stickies != null) {
13664                ArrayList<Intent> list = stickies.get(intent.getAction());
13665                if (list != null) {
13666                    int N = list.size();
13667                    int i;
13668                    for (i=0; i<N; i++) {
13669                        if (intent.filterEquals(list.get(i))) {
13670                            list.remove(i);
13671                            break;
13672                        }
13673                    }
13674                    if (list.size() <= 0) {
13675                        stickies.remove(intent.getAction());
13676                    }
13677                }
13678                if (stickies.size() <= 0) {
13679                    mStickyBroadcasts.remove(userId);
13680                }
13681            }
13682        }
13683    }
13684
13685    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13686            String resultData, Bundle resultExtras, boolean resultAbort) {
13687        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13688        if (r == null) {
13689            Slog.w(TAG, "finishReceiver called but not found on queue");
13690            return false;
13691        }
13692
13693        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13694    }
13695
13696    void backgroundServicesFinishedLocked(int userId) {
13697        for (BroadcastQueue queue : mBroadcastQueues) {
13698            queue.backgroundServicesFinishedLocked(userId);
13699        }
13700    }
13701
13702    public void finishReceiver(IBinder who, int resultCode, String resultData,
13703            Bundle resultExtras, boolean resultAbort) {
13704        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13705
13706        // Refuse possible leaked file descriptors
13707        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13708            throw new IllegalArgumentException("File descriptors passed in Bundle");
13709        }
13710
13711        final long origId = Binder.clearCallingIdentity();
13712        try {
13713            boolean doNext = false;
13714            BroadcastRecord r;
13715
13716            synchronized(this) {
13717                r = broadcastRecordForReceiverLocked(who);
13718                if (r != null) {
13719                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13720                        resultData, resultExtras, resultAbort, true);
13721                }
13722            }
13723
13724            if (doNext) {
13725                r.queue.processNextBroadcast(false);
13726            }
13727            trimApplications();
13728        } finally {
13729            Binder.restoreCallingIdentity(origId);
13730        }
13731    }
13732
13733    // =========================================================
13734    // INSTRUMENTATION
13735    // =========================================================
13736
13737    public boolean startInstrumentation(ComponentName className,
13738            String profileFile, int flags, Bundle arguments,
13739            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13740            int userId) {
13741        enforceNotIsolatedCaller("startInstrumentation");
13742        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13743                userId, false, true, "startInstrumentation", null);
13744        // Refuse possible leaked file descriptors
13745        if (arguments != null && arguments.hasFileDescriptors()) {
13746            throw new IllegalArgumentException("File descriptors passed in Bundle");
13747        }
13748
13749        synchronized(this) {
13750            InstrumentationInfo ii = null;
13751            ApplicationInfo ai = null;
13752            try {
13753                ii = mContext.getPackageManager().getInstrumentationInfo(
13754                    className, STOCK_PM_FLAGS);
13755                ai = AppGlobals.getPackageManager().getApplicationInfo(
13756                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13757            } catch (PackageManager.NameNotFoundException e) {
13758            } catch (RemoteException e) {
13759            }
13760            if (ii == null) {
13761                reportStartInstrumentationFailure(watcher, className,
13762                        "Unable to find instrumentation info for: " + className);
13763                return false;
13764            }
13765            if (ai == null) {
13766                reportStartInstrumentationFailure(watcher, className,
13767                        "Unable to find instrumentation target package: " + ii.targetPackage);
13768                return false;
13769            }
13770
13771            int match = mContext.getPackageManager().checkSignatures(
13772                    ii.targetPackage, ii.packageName);
13773            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13774                String msg = "Permission Denial: starting instrumentation "
13775                        + className + " from pid="
13776                        + Binder.getCallingPid()
13777                        + ", uid=" + Binder.getCallingPid()
13778                        + " not allowed because package " + ii.packageName
13779                        + " does not have a signature matching the target "
13780                        + ii.targetPackage;
13781                reportStartInstrumentationFailure(watcher, className, msg);
13782                throw new SecurityException(msg);
13783            }
13784
13785            final long origId = Binder.clearCallingIdentity();
13786            // Instrumentation can kill and relaunch even persistent processes
13787            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
13788                    "start instr");
13789            ProcessRecord app = addAppLocked(ai, false);
13790            app.instrumentationClass = className;
13791            app.instrumentationInfo = ai;
13792            app.instrumentationProfileFile = profileFile;
13793            app.instrumentationArguments = arguments;
13794            app.instrumentationWatcher = watcher;
13795            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13796            app.instrumentationResultClass = className;
13797            Binder.restoreCallingIdentity(origId);
13798        }
13799
13800        return true;
13801    }
13802
13803    /**
13804     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13805     * error to the logs, but if somebody is watching, send the report there too.  This enables
13806     * the "am" command to report errors with more information.
13807     *
13808     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13809     * @param cn The component name of the instrumentation.
13810     * @param report The error report.
13811     */
13812    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13813            ComponentName cn, String report) {
13814        Slog.w(TAG, report);
13815        try {
13816            if (watcher != null) {
13817                Bundle results = new Bundle();
13818                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13819                results.putString("Error", report);
13820                watcher.instrumentationStatus(cn, -1, results);
13821            }
13822        } catch (RemoteException e) {
13823            Slog.w(TAG, e);
13824        }
13825    }
13826
13827    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13828        if (app.instrumentationWatcher != null) {
13829            try {
13830                // NOTE:  IInstrumentationWatcher *must* be oneway here
13831                app.instrumentationWatcher.instrumentationFinished(
13832                    app.instrumentationClass,
13833                    resultCode,
13834                    results);
13835            } catch (RemoteException e) {
13836            }
13837        }
13838        if (app.instrumentationUiAutomationConnection != null) {
13839            try {
13840                app.instrumentationUiAutomationConnection.shutdown();
13841            } catch (RemoteException re) {
13842                /* ignore */
13843            }
13844            // Only a UiAutomation can set this flag and now that
13845            // it is finished we make sure it is reset to its default.
13846            mUserIsMonkey = false;
13847        }
13848        app.instrumentationWatcher = null;
13849        app.instrumentationUiAutomationConnection = null;
13850        app.instrumentationClass = null;
13851        app.instrumentationInfo = null;
13852        app.instrumentationProfileFile = null;
13853        app.instrumentationArguments = null;
13854
13855        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
13856                "finished inst");
13857    }
13858
13859    public void finishInstrumentation(IApplicationThread target,
13860            int resultCode, Bundle results) {
13861        int userId = UserHandle.getCallingUserId();
13862        // Refuse possible leaked file descriptors
13863        if (results != null && results.hasFileDescriptors()) {
13864            throw new IllegalArgumentException("File descriptors passed in Intent");
13865        }
13866
13867        synchronized(this) {
13868            ProcessRecord app = getRecordForAppLocked(target);
13869            if (app == null) {
13870                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13871                return;
13872            }
13873            final long origId = Binder.clearCallingIdentity();
13874            finishInstrumentationLocked(app, resultCode, results);
13875            Binder.restoreCallingIdentity(origId);
13876        }
13877    }
13878
13879    // =========================================================
13880    // CONFIGURATION
13881    // =========================================================
13882
13883    public ConfigurationInfo getDeviceConfigurationInfo() {
13884        ConfigurationInfo config = new ConfigurationInfo();
13885        synchronized (this) {
13886            config.reqTouchScreen = mConfiguration.touchscreen;
13887            config.reqKeyboardType = mConfiguration.keyboard;
13888            config.reqNavigation = mConfiguration.navigation;
13889            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13890                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13891                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13892            }
13893            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13894                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13895                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13896            }
13897            config.reqGlEsVersion = GL_ES_VERSION;
13898        }
13899        return config;
13900    }
13901
13902    ActivityStack getFocusedStack() {
13903        return mStackSupervisor.getFocusedStack();
13904    }
13905
13906    public Configuration getConfiguration() {
13907        Configuration ci;
13908        synchronized(this) {
13909            ci = new Configuration(mConfiguration);
13910        }
13911        return ci;
13912    }
13913
13914    public void updatePersistentConfiguration(Configuration values) {
13915        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13916                "updateConfiguration()");
13917        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13918                "updateConfiguration()");
13919        if (values == null) {
13920            throw new NullPointerException("Configuration must not be null");
13921        }
13922
13923        synchronized(this) {
13924            final long origId = Binder.clearCallingIdentity();
13925            updateConfigurationLocked(values, null, true, false);
13926            Binder.restoreCallingIdentity(origId);
13927        }
13928    }
13929
13930    public void updateConfiguration(Configuration values) {
13931        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13932                "updateConfiguration()");
13933
13934        synchronized(this) {
13935            if (values == null && mWindowManager != null) {
13936                // sentinel: fetch the current configuration from the window manager
13937                values = mWindowManager.computeNewConfiguration();
13938            }
13939
13940            if (mWindowManager != null) {
13941                mProcessList.applyDisplaySize(mWindowManager);
13942            }
13943
13944            final long origId = Binder.clearCallingIdentity();
13945            if (values != null) {
13946                Settings.System.clearConfiguration(values);
13947            }
13948            updateConfigurationLocked(values, null, false, false);
13949            Binder.restoreCallingIdentity(origId);
13950        }
13951    }
13952
13953    /**
13954     * Do either or both things: (1) change the current configuration, and (2)
13955     * make sure the given activity is running with the (now) current
13956     * configuration.  Returns true if the activity has been left running, or
13957     * false if <var>starting</var> is being destroyed to match the new
13958     * configuration.
13959     * @param persistent TODO
13960     */
13961    boolean updateConfigurationLocked(Configuration values,
13962            ActivityRecord starting, boolean persistent, boolean initLocale) {
13963        int changes = 0;
13964
13965        if (values != null) {
13966            Configuration newConfig = new Configuration(mConfiguration);
13967            changes = newConfig.updateFrom(values);
13968            if (changes != 0) {
13969                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13970                    Slog.i(TAG, "Updating configuration to: " + values);
13971                }
13972
13973                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13974
13975                if (values.locale != null && !initLocale) {
13976                    saveLocaleLocked(values.locale,
13977                                     !values.locale.equals(mConfiguration.locale),
13978                                     values.userSetLocale);
13979                }
13980
13981                mConfigurationSeq++;
13982                if (mConfigurationSeq <= 0) {
13983                    mConfigurationSeq = 1;
13984                }
13985                newConfig.seq = mConfigurationSeq;
13986                mConfiguration = newConfig;
13987                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
13988
13989                final Configuration configCopy = new Configuration(mConfiguration);
13990
13991                // TODO: If our config changes, should we auto dismiss any currently
13992                // showing dialogs?
13993                mShowDialogs = shouldShowDialogs(newConfig);
13994
13995                AttributeCache ac = AttributeCache.instance();
13996                if (ac != null) {
13997                    ac.updateConfiguration(configCopy);
13998                }
13999
14000                // Make sure all resources in our process are updated
14001                // right now, so that anyone who is going to retrieve
14002                // resource values after we return will be sure to get
14003                // the new ones.  This is especially important during
14004                // boot, where the first config change needs to guarantee
14005                // all resources have that config before following boot
14006                // code is executed.
14007                mSystemThread.applyConfigurationToResources(configCopy);
14008
14009                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14010                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14011                    msg.obj = new Configuration(configCopy);
14012                    mHandler.sendMessage(msg);
14013                }
14014
14015                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14016                    ProcessRecord app = mLruProcesses.get(i);
14017                    try {
14018                        if (app.thread != null) {
14019                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14020                                    + app.processName + " new config " + mConfiguration);
14021                            app.thread.scheduleConfigurationChanged(configCopy);
14022                        }
14023                    } catch (Exception e) {
14024                    }
14025                }
14026                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14027                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14028                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14029                        | Intent.FLAG_RECEIVER_FOREGROUND);
14030                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14031                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14032                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14033                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14034                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14035                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14036                    broadcastIntentLocked(null, null, intent,
14037                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14038                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14039                }
14040            }
14041        }
14042
14043        boolean kept = true;
14044        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14045        // mainStack is null during startup.
14046        if (mainStack != null) {
14047            if (changes != 0 && starting == null) {
14048                // If the configuration changed, and the caller is not already
14049                // in the process of starting an activity, then find the top
14050                // activity to check if its configuration needs to change.
14051                starting = mainStack.topRunningActivityLocked(null);
14052            }
14053
14054            if (starting != null) {
14055                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14056                // And we need to make sure at this point that all other activities
14057                // are made visible with the correct configuration.
14058                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14059            }
14060        }
14061
14062        if (values != null && mWindowManager != null) {
14063            mWindowManager.setNewConfiguration(mConfiguration);
14064        }
14065
14066        return kept;
14067    }
14068
14069    /**
14070     * Decide based on the configuration whether we should shouw the ANR,
14071     * crash, etc dialogs.  The idea is that if there is no affordnace to
14072     * press the on-screen buttons, we shouldn't show the dialog.
14073     *
14074     * A thought: SystemUI might also want to get told about this, the Power
14075     * dialog / global actions also might want different behaviors.
14076     */
14077    private static final boolean shouldShowDialogs(Configuration config) {
14078        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14079                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14080    }
14081
14082    /**
14083     * Save the locale.  You must be inside a synchronized (this) block.
14084     */
14085    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14086        if(isDiff) {
14087            SystemProperties.set("user.language", l.getLanguage());
14088            SystemProperties.set("user.region", l.getCountry());
14089        }
14090
14091        if(isPersist) {
14092            SystemProperties.set("persist.sys.language", l.getLanguage());
14093            SystemProperties.set("persist.sys.country", l.getCountry());
14094            SystemProperties.set("persist.sys.localevar", l.getVariant());
14095        }
14096    }
14097
14098    @Override
14099    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14100        ActivityRecord srec = ActivityRecord.forToken(token);
14101        return srec != null && srec.task.affinity != null &&
14102                srec.task.affinity.equals(destAffinity);
14103    }
14104
14105    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14106            Intent resultData) {
14107
14108        synchronized (this) {
14109            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14110            if (stack != null) {
14111                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14112            }
14113            return false;
14114        }
14115    }
14116
14117    public int getLaunchedFromUid(IBinder activityToken) {
14118        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14119        if (srec == null) {
14120            return -1;
14121        }
14122        return srec.launchedFromUid;
14123    }
14124
14125    public String getLaunchedFromPackage(IBinder activityToken) {
14126        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14127        if (srec == null) {
14128            return null;
14129        }
14130        return srec.launchedFromPackage;
14131    }
14132
14133    // =========================================================
14134    // LIFETIME MANAGEMENT
14135    // =========================================================
14136
14137    // Returns which broadcast queue the app is the current [or imminent] receiver
14138    // on, or 'null' if the app is not an active broadcast recipient.
14139    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14140        BroadcastRecord r = app.curReceiver;
14141        if (r != null) {
14142            return r.queue;
14143        }
14144
14145        // It's not the current receiver, but it might be starting up to become one
14146        synchronized (this) {
14147            for (BroadcastQueue queue : mBroadcastQueues) {
14148                r = queue.mPendingBroadcast;
14149                if (r != null && r.curApp == app) {
14150                    // found it; report which queue it's in
14151                    return queue;
14152                }
14153            }
14154        }
14155
14156        return null;
14157    }
14158
14159    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14160            boolean doingAll, long now) {
14161        if (mAdjSeq == app.adjSeq) {
14162            // This adjustment has already been computed.
14163            return app.curRawAdj;
14164        }
14165
14166        if (app.thread == null) {
14167            app.adjSeq = mAdjSeq;
14168            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14169            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14170            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14171        }
14172
14173        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14174        app.adjSource = null;
14175        app.adjTarget = null;
14176        app.empty = false;
14177        app.cached = false;
14178
14179        final int activitiesSize = app.activities.size();
14180
14181        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14182            // The max adjustment doesn't allow this app to be anything
14183            // below foreground, so it is not worth doing work for it.
14184            app.adjType = "fixed";
14185            app.adjSeq = mAdjSeq;
14186            app.curRawAdj = app.maxAdj;
14187            app.foregroundActivities = false;
14188            app.keeping = true;
14189            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14190            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14191            // System process can do UI, and when they do we want to have
14192            // them trim their memory after the user leaves the UI.  To
14193            // facilitate this, here we need to determine whether or not it
14194            // is currently showing UI.
14195            app.systemNoUi = true;
14196            if (app == TOP_APP) {
14197                app.systemNoUi = false;
14198            } else if (activitiesSize > 0) {
14199                for (int j = 0; j < activitiesSize; j++) {
14200                    final ActivityRecord r = app.activities.get(j);
14201                    if (r.visible) {
14202                        app.systemNoUi = false;
14203                    }
14204                }
14205            }
14206            if (!app.systemNoUi) {
14207                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14208            }
14209            return (app.curAdj=app.maxAdj);
14210        }
14211
14212        app.keeping = false;
14213        app.systemNoUi = false;
14214
14215        // Determine the importance of the process, starting with most
14216        // important to least, and assign an appropriate OOM adjustment.
14217        int adj;
14218        int schedGroup;
14219        int procState;
14220        boolean foregroundActivities = false;
14221        boolean interesting = false;
14222        BroadcastQueue queue;
14223        if (app == TOP_APP) {
14224            // The last app on the list is the foreground app.
14225            adj = ProcessList.FOREGROUND_APP_ADJ;
14226            schedGroup = Process.THREAD_GROUP_DEFAULT;
14227            app.adjType = "top-activity";
14228            foregroundActivities = true;
14229            interesting = true;
14230            procState = ActivityManager.PROCESS_STATE_TOP;
14231        } else if (app.instrumentationClass != null) {
14232            // Don't want to kill running instrumentation.
14233            adj = ProcessList.FOREGROUND_APP_ADJ;
14234            schedGroup = Process.THREAD_GROUP_DEFAULT;
14235            app.adjType = "instrumentation";
14236            interesting = true;
14237            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14238        } else if ((queue = isReceivingBroadcast(app)) != null) {
14239            // An app that is currently receiving a broadcast also
14240            // counts as being in the foreground for OOM killer purposes.
14241            // It's placed in a sched group based on the nature of the
14242            // broadcast as reflected by which queue it's active in.
14243            adj = ProcessList.FOREGROUND_APP_ADJ;
14244            schedGroup = (queue == mFgBroadcastQueue)
14245                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14246            app.adjType = "broadcast";
14247            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14248        } else if (app.executingServices.size() > 0) {
14249            // An app that is currently executing a service callback also
14250            // counts as being in the foreground.
14251            adj = ProcessList.FOREGROUND_APP_ADJ;
14252            schedGroup = app.execServicesFg ?
14253                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14254            app.adjType = "exec-service";
14255            procState = ActivityManager.PROCESS_STATE_SERVICE;
14256            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14257        } else {
14258            // As far as we know the process is empty.  We may change our mind later.
14259            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14260            // At this point we don't actually know the adjustment.  Use the cached adj
14261            // value that the caller wants us to.
14262            adj = cachedAdj;
14263            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14264            app.cached = true;
14265            app.empty = true;
14266            app.adjType = "cch-empty";
14267        }
14268
14269        // Examine all activities if not already foreground.
14270        if (!foregroundActivities && activitiesSize > 0) {
14271            for (int j = 0; j < activitiesSize; j++) {
14272                final ActivityRecord r = app.activities.get(j);
14273                if (r.app != app) {
14274                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14275                            + app + "?!?");
14276                    continue;
14277                }
14278                if (r.visible) {
14279                    // App has a visible activity; only upgrade adjustment.
14280                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14281                        adj = ProcessList.VISIBLE_APP_ADJ;
14282                        app.adjType = "visible";
14283                    }
14284                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14285                        procState = ActivityManager.PROCESS_STATE_TOP;
14286                    }
14287                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14288                    app.cached = false;
14289                    app.empty = false;
14290                    foregroundActivities = true;
14291                    break;
14292                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14293                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14294                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14295                        app.adjType = "pausing";
14296                    }
14297                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14298                        procState = ActivityManager.PROCESS_STATE_TOP;
14299                    }
14300                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14301                    app.cached = false;
14302                    app.empty = false;
14303                    foregroundActivities = true;
14304                } else if (r.state == ActivityState.STOPPING) {
14305                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14306                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14307                        app.adjType = "stopping";
14308                    }
14309                    // For the process state, we will at this point consider the
14310                    // process to be cached.  It will be cached either as an activity
14311                    // or empty depending on whether the activity is finishing.  We do
14312                    // this so that we can treat the process as cached for purposes of
14313                    // memory trimming (determing current memory level, trim command to
14314                    // send to process) since there can be an arbitrary number of stopping
14315                    // processes and they should soon all go into the cached state.
14316                    if (!r.finishing) {
14317                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14318                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14319                        }
14320                    }
14321                    app.cached = false;
14322                    app.empty = false;
14323                    foregroundActivities = true;
14324                } else {
14325                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14326                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14327                        app.adjType = "cch-act";
14328                    }
14329                }
14330            }
14331        }
14332
14333        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14334            if (app.foregroundServices) {
14335                // The user is aware of this app, so make it visible.
14336                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14337                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14338                app.cached = false;
14339                app.adjType = "fg-service";
14340                schedGroup = Process.THREAD_GROUP_DEFAULT;
14341            } else if (app.forcingToForeground != null) {
14342                // The user is aware of this app, so make it visible.
14343                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14344                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14345                app.cached = false;
14346                app.adjType = "force-fg";
14347                app.adjSource = app.forcingToForeground;
14348                schedGroup = Process.THREAD_GROUP_DEFAULT;
14349            }
14350        }
14351
14352        if (app.foregroundServices) {
14353            interesting = true;
14354        }
14355
14356        if (app == mHeavyWeightProcess) {
14357            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14358                // We don't want to kill the current heavy-weight process.
14359                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14360                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14361                app.cached = false;
14362                app.adjType = "heavy";
14363            }
14364            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14365                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14366            }
14367        }
14368
14369        if (app == mHomeProcess) {
14370            if (adj > ProcessList.HOME_APP_ADJ) {
14371                // This process is hosting what we currently consider to be the
14372                // home app, so we don't want to let it go into the background.
14373                adj = ProcessList.HOME_APP_ADJ;
14374                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14375                app.cached = false;
14376                app.adjType = "home";
14377            }
14378            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14379                procState = ActivityManager.PROCESS_STATE_HOME;
14380            }
14381        }
14382
14383        if (app == mPreviousProcess && app.activities.size() > 0) {
14384            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14385                // This was the previous process that showed UI to the user.
14386                // We want to try to keep it around more aggressively, to give
14387                // a good experience around switching between two apps.
14388                adj = ProcessList.PREVIOUS_APP_ADJ;
14389                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14390                app.cached = false;
14391                app.adjType = "previous";
14392            }
14393            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14394                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14395            }
14396        }
14397
14398        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14399                + " reason=" + app.adjType);
14400
14401        // By default, we use the computed adjustment.  It may be changed if
14402        // there are applications dependent on our services or providers, but
14403        // this gives us a baseline and makes sure we don't get into an
14404        // infinite recursion.
14405        app.adjSeq = mAdjSeq;
14406        app.curRawAdj = adj;
14407        app.hasStartedServices = false;
14408
14409        if (mBackupTarget != null && app == mBackupTarget.app) {
14410            // If possible we want to avoid killing apps while they're being backed up
14411            if (adj > ProcessList.BACKUP_APP_ADJ) {
14412                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14413                adj = ProcessList.BACKUP_APP_ADJ;
14414                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14415                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14416                }
14417                app.adjType = "backup";
14418                app.cached = false;
14419            }
14420            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14421                procState = ActivityManager.PROCESS_STATE_BACKUP;
14422            }
14423        }
14424
14425        boolean mayBeTop = false;
14426
14427        for (int is = app.services.size()-1;
14428                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14429                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14430                        || procState > ActivityManager.PROCESS_STATE_TOP);
14431                is--) {
14432            ServiceRecord s = app.services.valueAt(is);
14433            if (s.startRequested) {
14434                app.hasStartedServices = true;
14435                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14436                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14437                }
14438                if (app.hasShownUi && app != mHomeProcess) {
14439                    // If this process has shown some UI, let it immediately
14440                    // go to the LRU list because it may be pretty heavy with
14441                    // UI stuff.  We'll tag it with a label just to help
14442                    // debug and understand what is going on.
14443                    if (adj > ProcessList.SERVICE_ADJ) {
14444                        app.adjType = "cch-started-ui-services";
14445                    }
14446                } else {
14447                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14448                        // This service has seen some activity within
14449                        // recent memory, so we will keep its process ahead
14450                        // of the background processes.
14451                        if (adj > ProcessList.SERVICE_ADJ) {
14452                            adj = ProcessList.SERVICE_ADJ;
14453                            app.adjType = "started-services";
14454                            app.cached = false;
14455                        }
14456                    }
14457                    // If we have let the service slide into the background
14458                    // state, still have some text describing what it is doing
14459                    // even though the service no longer has an impact.
14460                    if (adj > ProcessList.SERVICE_ADJ) {
14461                        app.adjType = "cch-started-services";
14462                    }
14463                }
14464                // Don't kill this process because it is doing work; it
14465                // has said it is doing work.
14466                app.keeping = true;
14467            }
14468            for (int conni = s.connections.size()-1;
14469                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14470                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14471                            || procState > ActivityManager.PROCESS_STATE_TOP);
14472                    conni--) {
14473                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14474                for (int i = 0;
14475                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14476                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14477                                || procState > ActivityManager.PROCESS_STATE_TOP);
14478                        i++) {
14479                    // XXX should compute this based on the max of
14480                    // all connected clients.
14481                    ConnectionRecord cr = clist.get(i);
14482                    if (cr.binding.client == app) {
14483                        // Binding to ourself is not interesting.
14484                        continue;
14485                    }
14486                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14487                        ProcessRecord client = cr.binding.client;
14488                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14489                                TOP_APP, doingAll, now);
14490                        int clientProcState = client.curProcState;
14491                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14492                            // If the other app is cached for any reason, for purposes here
14493                            // we are going to consider it empty.  The specific cached state
14494                            // doesn't propagate except under certain conditions.
14495                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14496                        }
14497                        String adjType = null;
14498                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14499                            // Not doing bind OOM management, so treat
14500                            // this guy more like a started service.
14501                            if (app.hasShownUi && app != mHomeProcess) {
14502                                // If this process has shown some UI, let it immediately
14503                                // go to the LRU list because it may be pretty heavy with
14504                                // UI stuff.  We'll tag it with a label just to help
14505                                // debug and understand what is going on.
14506                                if (adj > clientAdj) {
14507                                    adjType = "cch-bound-ui-services";
14508                                }
14509                                app.cached = false;
14510                                clientAdj = adj;
14511                                clientProcState = procState;
14512                            } else {
14513                                if (now >= (s.lastActivity
14514                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14515                                    // This service has not seen activity within
14516                                    // recent memory, so allow it to drop to the
14517                                    // LRU list if there is no other reason to keep
14518                                    // it around.  We'll also tag it with a label just
14519                                    // to help debug and undertand what is going on.
14520                                    if (adj > clientAdj) {
14521                                        adjType = "cch-bound-services";
14522                                    }
14523                                    clientAdj = adj;
14524                                }
14525                            }
14526                        }
14527                        if (adj > clientAdj) {
14528                            // If this process has recently shown UI, and
14529                            // the process that is binding to it is less
14530                            // important than being visible, then we don't
14531                            // care about the binding as much as we care
14532                            // about letting this process get into the LRU
14533                            // list to be killed and restarted if needed for
14534                            // memory.
14535                            if (app.hasShownUi && app != mHomeProcess
14536                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14537                                adjType = "cch-bound-ui-services";
14538                            } else {
14539                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14540                                        |Context.BIND_IMPORTANT)) != 0) {
14541                                    adj = clientAdj;
14542                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14543                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14544                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14545                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14546                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14547                                    adj = clientAdj;
14548                                } else {
14549                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14550                                        adj = ProcessList.VISIBLE_APP_ADJ;
14551                                    }
14552                                }
14553                                if (!client.cached) {
14554                                    app.cached = false;
14555                                }
14556                                if (client.keeping) {
14557                                    app.keeping = true;
14558                                }
14559                                adjType = "service";
14560                            }
14561                        }
14562                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14563                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14564                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14565                            }
14566                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14567                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14568                                    // Special handling of clients who are in the top state.
14569                                    // We *may* want to consider this process to be in the
14570                                    // top state as well, but only if there is not another
14571                                    // reason for it to be running.  Being on the top is a
14572                                    // special state, meaning you are specifically running
14573                                    // for the current top app.  If the process is already
14574                                    // running in the background for some other reason, it
14575                                    // is more important to continue considering it to be
14576                                    // in the background state.
14577                                    mayBeTop = true;
14578                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14579                                } else {
14580                                    // Special handling for above-top states (persistent
14581                                    // processes).  These should not bring the current process
14582                                    // into the top state, since they are not on top.  Instead
14583                                    // give them the best state after that.
14584                                    clientProcState =
14585                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14586                                }
14587                            }
14588                        } else {
14589                            if (clientProcState <
14590                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14591                                clientProcState =
14592                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14593                            }
14594                        }
14595                        if (procState > clientProcState) {
14596                            procState = clientProcState;
14597                        }
14598                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14599                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14600                            app.pendingUiClean = true;
14601                        }
14602                        if (adjType != null) {
14603                            app.adjType = adjType;
14604                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14605                                    .REASON_SERVICE_IN_USE;
14606                            app.adjSource = cr.binding.client;
14607                            app.adjSourceOom = clientAdj;
14608                            app.adjTarget = s.name;
14609                        }
14610                    }
14611                    final ActivityRecord a = cr.activity;
14612                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14613                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14614                                (a.visible || a.state == ActivityState.RESUMED
14615                                 || a.state == ActivityState.PAUSING)) {
14616                            adj = ProcessList.FOREGROUND_APP_ADJ;
14617                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14618                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14619                            }
14620                            app.cached = false;
14621                            app.adjType = "service";
14622                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14623                                    .REASON_SERVICE_IN_USE;
14624                            app.adjSource = a;
14625                            app.adjSourceOom = adj;
14626                            app.adjTarget = s.name;
14627                        }
14628                    }
14629                }
14630            }
14631        }
14632
14633        for (int provi = app.pubProviders.size()-1;
14634                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14635                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14636                        || procState > ActivityManager.PROCESS_STATE_TOP);
14637                provi--) {
14638            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14639            for (int i = cpr.connections.size()-1;
14640                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14641                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14642                            || procState > ActivityManager.PROCESS_STATE_TOP);
14643                    i--) {
14644                ContentProviderConnection conn = cpr.connections.get(i);
14645                ProcessRecord client = conn.client;
14646                if (client == app) {
14647                    // Being our own client is not interesting.
14648                    continue;
14649                }
14650                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14651                int clientProcState = client.curProcState;
14652                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14653                    // If the other app is cached for any reason, for purposes here
14654                    // we are going to consider it empty.
14655                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14656                }
14657                if (adj > clientAdj) {
14658                    if (app.hasShownUi && app != mHomeProcess
14659                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14660                        app.adjType = "cch-ui-provider";
14661                    } else {
14662                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14663                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14664                        app.adjType = "provider";
14665                    }
14666                    app.cached &= client.cached;
14667                    app.keeping |= client.keeping;
14668                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14669                            .REASON_PROVIDER_IN_USE;
14670                    app.adjSource = client;
14671                    app.adjSourceOom = clientAdj;
14672                    app.adjTarget = cpr.name;
14673                }
14674                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14675                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14676                        // Special handling of clients who are in the top state.
14677                        // We *may* want to consider this process to be in the
14678                        // top state as well, but only if there is not another
14679                        // reason for it to be running.  Being on the top is a
14680                        // special state, meaning you are specifically running
14681                        // for the current top app.  If the process is already
14682                        // running in the background for some other reason, it
14683                        // is more important to continue considering it to be
14684                        // in the background state.
14685                        mayBeTop = true;
14686                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14687                    } else {
14688                        // Special handling for above-top states (persistent
14689                        // processes).  These should not bring the current process
14690                        // into the top state, since they are not on top.  Instead
14691                        // give them the best state after that.
14692                        clientProcState =
14693                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14694                    }
14695                }
14696                if (procState > clientProcState) {
14697                    procState = clientProcState;
14698                }
14699                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14700                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14701                }
14702            }
14703            // If the provider has external (non-framework) process
14704            // dependencies, ensure that its adjustment is at least
14705            // FOREGROUND_APP_ADJ.
14706            if (cpr.hasExternalProcessHandles()) {
14707                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14708                    adj = ProcessList.FOREGROUND_APP_ADJ;
14709                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14710                    app.cached = false;
14711                    app.keeping = true;
14712                    app.adjType = "provider";
14713                    app.adjTarget = cpr.name;
14714                }
14715                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14716                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14717                }
14718            }
14719        }
14720
14721        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14722            // A client of one of our services or providers is in the top state.  We
14723            // *may* want to be in the top state, but not if we are already running in
14724            // the background for some other reason.  For the decision here, we are going
14725            // to pick out a few specific states that we want to remain in when a client
14726            // is top (states that tend to be longer-term) and otherwise allow it to go
14727            // to the top state.
14728            switch (procState) {
14729                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14730                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14731                case ActivityManager.PROCESS_STATE_SERVICE:
14732                    // These all are longer-term states, so pull them up to the top
14733                    // of the background states, but not all the way to the top state.
14734                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14735                    break;
14736                default:
14737                    // Otherwise, top is a better choice, so take it.
14738                    procState = ActivityManager.PROCESS_STATE_TOP;
14739                    break;
14740            }
14741        }
14742
14743        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14744            // This is a cached process, but with client activities.  Mark it so.
14745            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14746            app.adjType = "cch-client-act";
14747        }
14748
14749        if (adj == ProcessList.SERVICE_ADJ) {
14750            if (doingAll) {
14751                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14752                mNewNumServiceProcs++;
14753                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14754                if (!app.serviceb) {
14755                    // This service isn't far enough down on the LRU list to
14756                    // normally be a B service, but if we are low on RAM and it
14757                    // is large we want to force it down since we would prefer to
14758                    // keep launcher over it.
14759                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14760                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14761                        app.serviceHighRam = true;
14762                        app.serviceb = true;
14763                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14764                    } else {
14765                        mNewNumAServiceProcs++;
14766                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14767                    }
14768                } else {
14769                    app.serviceHighRam = false;
14770                }
14771            }
14772            if (app.serviceb) {
14773                adj = ProcessList.SERVICE_B_ADJ;
14774            }
14775        }
14776
14777        app.curRawAdj = adj;
14778
14779        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14780        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14781        if (adj > app.maxAdj) {
14782            adj = app.maxAdj;
14783            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14784                schedGroup = Process.THREAD_GROUP_DEFAULT;
14785            }
14786        }
14787        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14788            app.keeping = true;
14789        }
14790
14791        // Do final modification to adj.  Everything we do between here and applying
14792        // the final setAdj must be done in this function, because we will also use
14793        // it when computing the final cached adj later.  Note that we don't need to
14794        // worry about this for max adj above, since max adj will always be used to
14795        // keep it out of the cached vaues.
14796        adj = app.modifyRawOomAdj(adj);
14797
14798        app.curProcState = procState;
14799
14800        int importance = app.memImportance;
14801        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14802            app.curAdj = adj;
14803            app.curSchedGroup = schedGroup;
14804            if (!interesting) {
14805                // For this reporting, if there is not something explicitly
14806                // interesting in this process then we will push it to the
14807                // background importance.
14808                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14809            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14810                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14811            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14812                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14813            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14814                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14815            } else if (adj >= ProcessList.SERVICE_ADJ) {
14816                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14817            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14818                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14819            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14820                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14821            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14822                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14823            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14824                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14825            } else {
14826                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14827            }
14828        }
14829
14830        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14831        if (foregroundActivities != app.foregroundActivities) {
14832            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14833        }
14834        if (changes != 0) {
14835            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14836            app.memImportance = importance;
14837            app.foregroundActivities = foregroundActivities;
14838            int i = mPendingProcessChanges.size()-1;
14839            ProcessChangeItem item = null;
14840            while (i >= 0) {
14841                item = mPendingProcessChanges.get(i);
14842                if (item.pid == app.pid) {
14843                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14844                    break;
14845                }
14846                i--;
14847            }
14848            if (i < 0) {
14849                // No existing item in pending changes; need a new one.
14850                final int NA = mAvailProcessChanges.size();
14851                if (NA > 0) {
14852                    item = mAvailProcessChanges.remove(NA-1);
14853                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14854                } else {
14855                    item = new ProcessChangeItem();
14856                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14857                }
14858                item.changes = 0;
14859                item.pid = app.pid;
14860                item.uid = app.info.uid;
14861                if (mPendingProcessChanges.size() == 0) {
14862                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14863                            "*** Enqueueing dispatch processes changed!");
14864                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14865                }
14866                mPendingProcessChanges.add(item);
14867            }
14868            item.changes |= changes;
14869            item.importance = importance;
14870            item.foregroundActivities = foregroundActivities;
14871            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14872                    + Integer.toHexString(System.identityHashCode(item))
14873                    + " " + app.toShortString() + ": changes=" + item.changes
14874                    + " importance=" + item.importance
14875                    + " foreground=" + item.foregroundActivities
14876                    + " type=" + app.adjType + " source=" + app.adjSource
14877                    + " target=" + app.adjTarget);
14878        }
14879
14880        return app.curRawAdj;
14881    }
14882
14883    /**
14884     * Schedule PSS collection of a process.
14885     */
14886    void requestPssLocked(ProcessRecord proc, int procState) {
14887        if (mPendingPssProcesses.contains(proc)) {
14888            return;
14889        }
14890        if (mPendingPssProcesses.size() == 0) {
14891            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14892        }
14893        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14894        proc.pssProcState = procState;
14895        mPendingPssProcesses.add(proc);
14896    }
14897
14898    /**
14899     * Schedule PSS collection of all processes.
14900     */
14901    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14902        if (!always) {
14903            if (now < (mLastFullPssTime +
14904                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14905                return;
14906            }
14907        }
14908        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14909        mLastFullPssTime = now;
14910        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14911        mPendingPssProcesses.clear();
14912        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14913            ProcessRecord app = mLruProcesses.get(i);
14914            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14915                app.pssProcState = app.setProcState;
14916                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14917                        mSleeping, now);
14918                mPendingPssProcesses.add(app);
14919            }
14920        }
14921        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14922    }
14923
14924    /**
14925     * Ask a given process to GC right now.
14926     */
14927    final void performAppGcLocked(ProcessRecord app) {
14928        try {
14929            app.lastRequestedGc = SystemClock.uptimeMillis();
14930            if (app.thread != null) {
14931                if (app.reportLowMemory) {
14932                    app.reportLowMemory = false;
14933                    app.thread.scheduleLowMemory();
14934                } else {
14935                    app.thread.processInBackground();
14936                }
14937            }
14938        } catch (Exception e) {
14939            // whatever.
14940        }
14941    }
14942
14943    /**
14944     * Returns true if things are idle enough to perform GCs.
14945     */
14946    private final boolean canGcNowLocked() {
14947        boolean processingBroadcasts = false;
14948        for (BroadcastQueue q : mBroadcastQueues) {
14949            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14950                processingBroadcasts = true;
14951            }
14952        }
14953        return !processingBroadcasts
14954                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14955    }
14956
14957    /**
14958     * Perform GCs on all processes that are waiting for it, but only
14959     * if things are idle.
14960     */
14961    final void performAppGcsLocked() {
14962        final int N = mProcessesToGc.size();
14963        if (N <= 0) {
14964            return;
14965        }
14966        if (canGcNowLocked()) {
14967            while (mProcessesToGc.size() > 0) {
14968                ProcessRecord proc = mProcessesToGc.remove(0);
14969                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14970                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14971                            <= SystemClock.uptimeMillis()) {
14972                        // To avoid spamming the system, we will GC processes one
14973                        // at a time, waiting a few seconds between each.
14974                        performAppGcLocked(proc);
14975                        scheduleAppGcsLocked();
14976                        return;
14977                    } else {
14978                        // It hasn't been long enough since we last GCed this
14979                        // process...  put it in the list to wait for its time.
14980                        addProcessToGcListLocked(proc);
14981                        break;
14982                    }
14983                }
14984            }
14985
14986            scheduleAppGcsLocked();
14987        }
14988    }
14989
14990    /**
14991     * If all looks good, perform GCs on all processes waiting for them.
14992     */
14993    final void performAppGcsIfAppropriateLocked() {
14994        if (canGcNowLocked()) {
14995            performAppGcsLocked();
14996            return;
14997        }
14998        // Still not idle, wait some more.
14999        scheduleAppGcsLocked();
15000    }
15001
15002    /**
15003     * Schedule the execution of all pending app GCs.
15004     */
15005    final void scheduleAppGcsLocked() {
15006        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15007
15008        if (mProcessesToGc.size() > 0) {
15009            // Schedule a GC for the time to the next process.
15010            ProcessRecord proc = mProcessesToGc.get(0);
15011            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15012
15013            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15014            long now = SystemClock.uptimeMillis();
15015            if (when < (now+GC_TIMEOUT)) {
15016                when = now + GC_TIMEOUT;
15017            }
15018            mHandler.sendMessageAtTime(msg, when);
15019        }
15020    }
15021
15022    /**
15023     * Add a process to the array of processes waiting to be GCed.  Keeps the
15024     * list in sorted order by the last GC time.  The process can't already be
15025     * on the list.
15026     */
15027    final void addProcessToGcListLocked(ProcessRecord proc) {
15028        boolean added = false;
15029        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15030            if (mProcessesToGc.get(i).lastRequestedGc <
15031                    proc.lastRequestedGc) {
15032                added = true;
15033                mProcessesToGc.add(i+1, proc);
15034                break;
15035            }
15036        }
15037        if (!added) {
15038            mProcessesToGc.add(0, proc);
15039        }
15040    }
15041
15042    /**
15043     * Set up to ask a process to GC itself.  This will either do it
15044     * immediately, or put it on the list of processes to gc the next
15045     * time things are idle.
15046     */
15047    final void scheduleAppGcLocked(ProcessRecord app) {
15048        long now = SystemClock.uptimeMillis();
15049        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15050            return;
15051        }
15052        if (!mProcessesToGc.contains(app)) {
15053            addProcessToGcListLocked(app);
15054            scheduleAppGcsLocked();
15055        }
15056    }
15057
15058    final void checkExcessivePowerUsageLocked(boolean doKills) {
15059        updateCpuStatsNow();
15060
15061        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15062        boolean doWakeKills = doKills;
15063        boolean doCpuKills = doKills;
15064        if (mLastPowerCheckRealtime == 0) {
15065            doWakeKills = false;
15066        }
15067        if (mLastPowerCheckUptime == 0) {
15068            doCpuKills = false;
15069        }
15070        if (stats.isScreenOn()) {
15071            doWakeKills = false;
15072        }
15073        final long curRealtime = SystemClock.elapsedRealtime();
15074        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15075        final long curUptime = SystemClock.uptimeMillis();
15076        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15077        mLastPowerCheckRealtime = curRealtime;
15078        mLastPowerCheckUptime = curUptime;
15079        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15080            doWakeKills = false;
15081        }
15082        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15083            doCpuKills = false;
15084        }
15085        int i = mLruProcesses.size();
15086        while (i > 0) {
15087            i--;
15088            ProcessRecord app = mLruProcesses.get(i);
15089            if (!app.keeping) {
15090                long wtime;
15091                synchronized (stats) {
15092                    wtime = stats.getProcessWakeTime(app.info.uid,
15093                            app.pid, curRealtime);
15094                }
15095                long wtimeUsed = wtime - app.lastWakeTime;
15096                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15097                if (DEBUG_POWER) {
15098                    StringBuilder sb = new StringBuilder(128);
15099                    sb.append("Wake for ");
15100                    app.toShortString(sb);
15101                    sb.append(": over ");
15102                    TimeUtils.formatDuration(realtimeSince, sb);
15103                    sb.append(" used ");
15104                    TimeUtils.formatDuration(wtimeUsed, sb);
15105                    sb.append(" (");
15106                    sb.append((wtimeUsed*100)/realtimeSince);
15107                    sb.append("%)");
15108                    Slog.i(TAG, sb.toString());
15109                    sb.setLength(0);
15110                    sb.append("CPU for ");
15111                    app.toShortString(sb);
15112                    sb.append(": over ");
15113                    TimeUtils.formatDuration(uptimeSince, sb);
15114                    sb.append(" used ");
15115                    TimeUtils.formatDuration(cputimeUsed, sb);
15116                    sb.append(" (");
15117                    sb.append((cputimeUsed*100)/uptimeSince);
15118                    sb.append("%)");
15119                    Slog.i(TAG, sb.toString());
15120                }
15121                // If a process has held a wake lock for more
15122                // than 50% of the time during this period,
15123                // that sounds bad.  Kill!
15124                if (doWakeKills && realtimeSince > 0
15125                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15126                    synchronized (stats) {
15127                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15128                                realtimeSince, wtimeUsed);
15129                    }
15130                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15131                            + " during " + realtimeSince);
15132                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15133                } else if (doCpuKills && uptimeSince > 0
15134                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15135                    synchronized (stats) {
15136                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15137                                uptimeSince, cputimeUsed);
15138                    }
15139                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15140                            + " during " + uptimeSince);
15141                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15142                } else {
15143                    app.lastWakeTime = wtime;
15144                    app.lastCpuTime = app.curCpuTime;
15145                }
15146            }
15147        }
15148    }
15149
15150    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15151            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15152        boolean success = true;
15153
15154        if (app.curRawAdj != app.setRawAdj) {
15155            if (wasKeeping && !app.keeping) {
15156                // This app is no longer something we want to keep.  Note
15157                // its current wake lock time to later know to kill it if
15158                // it is not behaving well.
15159                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15160                synchronized (stats) {
15161                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15162                            app.pid, SystemClock.elapsedRealtime());
15163                }
15164                app.lastCpuTime = app.curCpuTime;
15165            }
15166
15167            app.setRawAdj = app.curRawAdj;
15168        }
15169
15170        if (app.curAdj != app.setAdj) {
15171            ProcessList.setOomAdj(app.pid, app.curAdj);
15172            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15173                TAG, "Set " + app.pid + " " + app.processName +
15174                " adj " + app.curAdj + ": " + app.adjType);
15175            app.setAdj = app.curAdj;
15176        }
15177
15178        if (app.setSchedGroup != app.curSchedGroup) {
15179            app.setSchedGroup = app.curSchedGroup;
15180            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15181                    "Setting process group of " + app.processName
15182                    + " to " + app.curSchedGroup);
15183            if (app.waitingToKill != null &&
15184                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15185                killUnneededProcessLocked(app, app.waitingToKill);
15186                success = false;
15187            } else {
15188                if (true) {
15189                    long oldId = Binder.clearCallingIdentity();
15190                    try {
15191                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15192                    } catch (Exception e) {
15193                        Slog.w(TAG, "Failed setting process group of " + app.pid
15194                                + " to " + app.curSchedGroup);
15195                        e.printStackTrace();
15196                    } finally {
15197                        Binder.restoreCallingIdentity(oldId);
15198                    }
15199                } else {
15200                    if (app.thread != null) {
15201                        try {
15202                            app.thread.setSchedulingGroup(app.curSchedGroup);
15203                        } catch (RemoteException e) {
15204                        }
15205                    }
15206                }
15207                Process.setSwappiness(app.pid,
15208                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15209            }
15210        }
15211        if (app.repProcState != app.curProcState) {
15212            app.repProcState = app.curProcState;
15213            if (!reportingProcessState && app.thread != null) {
15214                try {
15215                    if (false) {
15216                        //RuntimeException h = new RuntimeException("here");
15217                        Slog.i(TAG, "Sending new process state " + app.repProcState
15218                                + " to " + app /*, h*/);
15219                    }
15220                    app.thread.setProcessState(app.repProcState);
15221                } catch (RemoteException e) {
15222                }
15223            }
15224        }
15225        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15226                app.setProcState)) {
15227            app.lastStateTime = now;
15228            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15229                    mSleeping, now);
15230            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15231                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15232                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15233                    + (app.nextPssTime-now) + ": " + app);
15234        } else {
15235            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15236                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15237                requestPssLocked(app, app.setProcState);
15238                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15239                        mSleeping, now);
15240            } else if (false && DEBUG_PSS) {
15241                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15242            }
15243        }
15244        if (app.setProcState != app.curProcState) {
15245            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15246                    "Proc state change of " + app.processName
15247                    + " to " + app.curProcState);
15248            app.setProcState = app.curProcState;
15249            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15250                app.notCachedSinceIdle = false;
15251            }
15252            if (!doingAll) {
15253                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15254            } else {
15255                app.procStateChanged = true;
15256            }
15257        }
15258        return success;
15259    }
15260
15261    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15262        if (proc.thread != null && proc.baseProcessTracker != null) {
15263            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15264        }
15265    }
15266
15267    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15268            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15269        if (app.thread == null) {
15270            return false;
15271        }
15272
15273        final boolean wasKeeping = app.keeping;
15274
15275        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15276
15277        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15278                reportingProcessState, now);
15279    }
15280
15281    private final ActivityRecord resumedAppLocked() {
15282        return mStackSupervisor.resumedAppLocked();
15283    }
15284
15285    final boolean updateOomAdjLocked(ProcessRecord app) {
15286        return updateOomAdjLocked(app, false);
15287    }
15288
15289    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15290        final ActivityRecord TOP_ACT = resumedAppLocked();
15291        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15292        final boolean wasCached = app.cached;
15293
15294        mAdjSeq++;
15295
15296        // This is the desired cached adjusment we want to tell it to use.
15297        // If our app is currently cached, we know it, and that is it.  Otherwise,
15298        // we don't know it yet, and it needs to now be cached we will then
15299        // need to do a complete oom adj.
15300        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15301                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15302        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15303                SystemClock.uptimeMillis());
15304        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15305            // Changed to/from cached state, so apps after it in the LRU
15306            // list may also be changed.
15307            updateOomAdjLocked();
15308        }
15309        return success;
15310    }
15311
15312    final void updateOomAdjLocked() {
15313        final ActivityRecord TOP_ACT = resumedAppLocked();
15314        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15315        final long now = SystemClock.uptimeMillis();
15316        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15317        final int N = mLruProcesses.size();
15318
15319        if (false) {
15320            RuntimeException e = new RuntimeException();
15321            e.fillInStackTrace();
15322            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15323        }
15324
15325        mAdjSeq++;
15326        mNewNumServiceProcs = 0;
15327        mNewNumAServiceProcs = 0;
15328
15329        final int emptyProcessLimit;
15330        final int cachedProcessLimit;
15331        if (mProcessLimit <= 0) {
15332            emptyProcessLimit = cachedProcessLimit = 0;
15333        } else if (mProcessLimit == 1) {
15334            emptyProcessLimit = 1;
15335            cachedProcessLimit = 0;
15336        } else {
15337            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15338            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15339        }
15340
15341        // Let's determine how many processes we have running vs.
15342        // how many slots we have for background processes; we may want
15343        // to put multiple processes in a slot of there are enough of
15344        // them.
15345        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15346                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15347        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15348        if (numEmptyProcs > cachedProcessLimit) {
15349            // If there are more empty processes than our limit on cached
15350            // processes, then use the cached process limit for the factor.
15351            // This ensures that the really old empty processes get pushed
15352            // down to the bottom, so if we are running low on memory we will
15353            // have a better chance at keeping around more cached processes
15354            // instead of a gazillion empty processes.
15355            numEmptyProcs = cachedProcessLimit;
15356        }
15357        int emptyFactor = numEmptyProcs/numSlots;
15358        if (emptyFactor < 1) emptyFactor = 1;
15359        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15360        if (cachedFactor < 1) cachedFactor = 1;
15361        int stepCached = 0;
15362        int stepEmpty = 0;
15363        int numCached = 0;
15364        int numEmpty = 0;
15365        int numTrimming = 0;
15366
15367        mNumNonCachedProcs = 0;
15368        mNumCachedHiddenProcs = 0;
15369
15370        // First update the OOM adjustment for each of the
15371        // application processes based on their current state.
15372        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15373        int nextCachedAdj = curCachedAdj+1;
15374        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15375        int nextEmptyAdj = curEmptyAdj+2;
15376        for (int i=N-1; i>=0; i--) {
15377            ProcessRecord app = mLruProcesses.get(i);
15378            if (!app.killedByAm && app.thread != null) {
15379                app.procStateChanged = false;
15380                final boolean wasKeeping = app.keeping;
15381                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15382
15383                // If we haven't yet assigned the final cached adj
15384                // to the process, do that now.
15385                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15386                    switch (app.curProcState) {
15387                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15388                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15389                            // This process is a cached process holding activities...
15390                            // assign it the next cached value for that type, and then
15391                            // step that cached level.
15392                            app.curRawAdj = curCachedAdj;
15393                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15394                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15395                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15396                                    + ")");
15397                            if (curCachedAdj != nextCachedAdj) {
15398                                stepCached++;
15399                                if (stepCached >= cachedFactor) {
15400                                    stepCached = 0;
15401                                    curCachedAdj = nextCachedAdj;
15402                                    nextCachedAdj += 2;
15403                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15404                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15405                                    }
15406                                }
15407                            }
15408                            break;
15409                        default:
15410                            // For everything else, assign next empty cached process
15411                            // level and bump that up.  Note that this means that
15412                            // long-running services that have dropped down to the
15413                            // cached level will be treated as empty (since their process
15414                            // state is still as a service), which is what we want.
15415                            app.curRawAdj = curEmptyAdj;
15416                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15417                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15418                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15419                                    + ")");
15420                            if (curEmptyAdj != nextEmptyAdj) {
15421                                stepEmpty++;
15422                                if (stepEmpty >= emptyFactor) {
15423                                    stepEmpty = 0;
15424                                    curEmptyAdj = nextEmptyAdj;
15425                                    nextEmptyAdj += 2;
15426                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15427                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15428                                    }
15429                                }
15430                            }
15431                            break;
15432                    }
15433                }
15434
15435                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15436
15437                // Count the number of process types.
15438                switch (app.curProcState) {
15439                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15440                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15441                        mNumCachedHiddenProcs++;
15442                        numCached++;
15443                        if (numCached > cachedProcessLimit) {
15444                            killUnneededProcessLocked(app, "cached #" + numCached);
15445                        }
15446                        break;
15447                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15448                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15449                                && app.lastActivityTime < oldTime) {
15450                            killUnneededProcessLocked(app, "empty for "
15451                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15452                                    / 1000) + "s");
15453                        } else {
15454                            numEmpty++;
15455                            if (numEmpty > emptyProcessLimit) {
15456                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15457                            }
15458                        }
15459                        break;
15460                    default:
15461                        mNumNonCachedProcs++;
15462                        break;
15463                }
15464
15465                if (app.isolated && app.services.size() <= 0) {
15466                    // If this is an isolated process, and there are no
15467                    // services running in it, then the process is no longer
15468                    // needed.  We agressively kill these because we can by
15469                    // definition not re-use the same process again, and it is
15470                    // good to avoid having whatever code was running in them
15471                    // left sitting around after no longer needed.
15472                    killUnneededProcessLocked(app, "isolated not needed");
15473                }
15474
15475                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15476                        && !app.killedByAm) {
15477                    numTrimming++;
15478                }
15479            }
15480        }
15481
15482        mNumServiceProcs = mNewNumServiceProcs;
15483
15484        // Now determine the memory trimming level of background processes.
15485        // Unfortunately we need to start at the back of the list to do this
15486        // properly.  We only do this if the number of background apps we
15487        // are managing to keep around is less than half the maximum we desire;
15488        // if we are keeping a good number around, we'll let them use whatever
15489        // memory they want.
15490        final int numCachedAndEmpty = numCached + numEmpty;
15491        int memFactor;
15492        if (numCached <= ProcessList.TRIM_CACHED_APPS
15493                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15494            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15495                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15496            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15497                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15498            } else {
15499                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15500            }
15501        } else {
15502            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15503        }
15504        // We always allow the memory level to go up (better).  We only allow it to go
15505        // down if we are in a state where that is allowed, *and* the total number of processes
15506        // has gone down since last time.
15507        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15508                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15509                + " last=" + mLastNumProcesses);
15510        if (memFactor > mLastMemoryLevel) {
15511            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15512                memFactor = mLastMemoryLevel;
15513                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15514            }
15515        }
15516        mLastMemoryLevel = memFactor;
15517        mLastNumProcesses = mLruProcesses.size();
15518        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15519        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15520        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15521            if (mLowRamStartTime == 0) {
15522                mLowRamStartTime = now;
15523            }
15524            int step = 0;
15525            int fgTrimLevel;
15526            switch (memFactor) {
15527                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15528                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15529                    break;
15530                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15531                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15532                    break;
15533                default:
15534                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15535                    break;
15536            }
15537            int factor = numTrimming/3;
15538            int minFactor = 2;
15539            if (mHomeProcess != null) minFactor++;
15540            if (mPreviousProcess != null) minFactor++;
15541            if (factor < minFactor) factor = minFactor;
15542            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15543            for (int i=N-1; i>=0; i--) {
15544                ProcessRecord app = mLruProcesses.get(i);
15545                if (allChanged || app.procStateChanged) {
15546                    setProcessTrackerState(app, trackerMemFactor, now);
15547                    app.procStateChanged = false;
15548                }
15549                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15550                        && !app.killedByAm) {
15551                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15552                        try {
15553                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15554                                    "Trimming memory of " + app.processName
15555                                    + " to " + curLevel);
15556                            app.thread.scheduleTrimMemory(curLevel);
15557                        } catch (RemoteException e) {
15558                        }
15559                        if (false) {
15560                            // For now we won't do this; our memory trimming seems
15561                            // to be good enough at this point that destroying
15562                            // activities causes more harm than good.
15563                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15564                                    && app != mHomeProcess && app != mPreviousProcess) {
15565                                // Need to do this on its own message because the stack may not
15566                                // be in a consistent state at this point.
15567                                // For these apps we will also finish their activities
15568                                // to help them free memory.
15569                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15570                            }
15571                        }
15572                    }
15573                    app.trimMemoryLevel = curLevel;
15574                    step++;
15575                    if (step >= factor) {
15576                        step = 0;
15577                        switch (curLevel) {
15578                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15579                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15580                                break;
15581                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15582                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15583                                break;
15584                        }
15585                    }
15586                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15587                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15588                            && app.thread != null) {
15589                        try {
15590                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15591                                    "Trimming memory of heavy-weight " + app.processName
15592                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15593                            app.thread.scheduleTrimMemory(
15594                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15595                        } catch (RemoteException e) {
15596                        }
15597                    }
15598                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15599                } else {
15600                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15601                            || app.systemNoUi) && app.pendingUiClean) {
15602                        // If this application is now in the background and it
15603                        // had done UI, then give it the special trim level to
15604                        // have it free UI resources.
15605                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15606                        if (app.trimMemoryLevel < level && app.thread != null) {
15607                            try {
15608                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15609                                        "Trimming memory of bg-ui " + app.processName
15610                                        + " to " + level);
15611                                app.thread.scheduleTrimMemory(level);
15612                            } catch (RemoteException e) {
15613                            }
15614                        }
15615                        app.pendingUiClean = false;
15616                    }
15617                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15618                        try {
15619                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15620                                    "Trimming memory of fg " + app.processName
15621                                    + " to " + fgTrimLevel);
15622                            app.thread.scheduleTrimMemory(fgTrimLevel);
15623                        } catch (RemoteException e) {
15624                        }
15625                    }
15626                    app.trimMemoryLevel = fgTrimLevel;
15627                }
15628            }
15629        } else {
15630            if (mLowRamStartTime != 0) {
15631                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15632                mLowRamStartTime = 0;
15633            }
15634            for (int i=N-1; i>=0; i--) {
15635                ProcessRecord app = mLruProcesses.get(i);
15636                if (allChanged || app.procStateChanged) {
15637                    setProcessTrackerState(app, trackerMemFactor, now);
15638                    app.procStateChanged = false;
15639                }
15640                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15641                        || app.systemNoUi) && app.pendingUiClean) {
15642                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15643                            && app.thread != null) {
15644                        try {
15645                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15646                                    "Trimming memory of ui hidden " + app.processName
15647                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15648                            app.thread.scheduleTrimMemory(
15649                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15650                        } catch (RemoteException e) {
15651                        }
15652                    }
15653                    app.pendingUiClean = false;
15654                }
15655                app.trimMemoryLevel = 0;
15656            }
15657        }
15658
15659        if (mAlwaysFinishActivities) {
15660            // Need to do this on its own message because the stack may not
15661            // be in a consistent state at this point.
15662            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15663        }
15664
15665        if (allChanged) {
15666            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15667        }
15668
15669        if (mProcessStats.shouldWriteNowLocked(now)) {
15670            mHandler.post(new Runnable() {
15671                @Override public void run() {
15672                    synchronized (ActivityManagerService.this) {
15673                        mProcessStats.writeStateAsyncLocked();
15674                    }
15675                }
15676            });
15677        }
15678
15679        if (DEBUG_OOM_ADJ) {
15680            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15681        }
15682    }
15683
15684    final void trimApplications() {
15685        synchronized (this) {
15686            int i;
15687
15688            // First remove any unused application processes whose package
15689            // has been removed.
15690            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15691                final ProcessRecord app = mRemovedProcesses.get(i);
15692                if (app.activities.size() == 0
15693                        && app.curReceiver == null && app.services.size() == 0) {
15694                    Slog.i(
15695                        TAG, "Exiting empty application process "
15696                        + app.processName + " ("
15697                        + (app.thread != null ? app.thread.asBinder() : null)
15698                        + ")\n");
15699                    if (app.pid > 0 && app.pid != MY_PID) {
15700                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15701                                app.processName, app.setAdj, "empty");
15702                        app.killedByAm = true;
15703                        Process.killProcessQuiet(app.pid);
15704                    } else {
15705                        try {
15706                            app.thread.scheduleExit();
15707                        } catch (Exception e) {
15708                            // Ignore exceptions.
15709                        }
15710                    }
15711                    cleanUpApplicationRecordLocked(app, false, true, -1);
15712                    mRemovedProcesses.remove(i);
15713
15714                    if (app.persistent) {
15715                        if (app.persistent) {
15716                            addAppLocked(app.info, false);
15717                        }
15718                    }
15719                }
15720            }
15721
15722            // Now update the oom adj for all processes.
15723            updateOomAdjLocked();
15724        }
15725    }
15726
15727    /** This method sends the specified signal to each of the persistent apps */
15728    public void signalPersistentProcesses(int sig) throws RemoteException {
15729        if (sig != Process.SIGNAL_USR1) {
15730            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15731        }
15732
15733        synchronized (this) {
15734            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15735                    != PackageManager.PERMISSION_GRANTED) {
15736                throw new SecurityException("Requires permission "
15737                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15738            }
15739
15740            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15741                ProcessRecord r = mLruProcesses.get(i);
15742                if (r.thread != null && r.persistent) {
15743                    Process.sendSignal(r.pid, sig);
15744                }
15745            }
15746        }
15747    }
15748
15749    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15750        if (proc == null || proc == mProfileProc) {
15751            proc = mProfileProc;
15752            path = mProfileFile;
15753            profileType = mProfileType;
15754            clearProfilerLocked();
15755        }
15756        if (proc == null) {
15757            return;
15758        }
15759        try {
15760            proc.thread.profilerControl(false, path, null, profileType);
15761        } catch (RemoteException e) {
15762            throw new IllegalStateException("Process disappeared");
15763        }
15764    }
15765
15766    private void clearProfilerLocked() {
15767        if (mProfileFd != null) {
15768            try {
15769                mProfileFd.close();
15770            } catch (IOException e) {
15771            }
15772        }
15773        mProfileApp = null;
15774        mProfileProc = null;
15775        mProfileFile = null;
15776        mProfileType = 0;
15777        mAutoStopProfiler = false;
15778    }
15779
15780    public boolean profileControl(String process, int userId, boolean start,
15781            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15782
15783        try {
15784            synchronized (this) {
15785                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15786                // its own permission.
15787                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15788                        != PackageManager.PERMISSION_GRANTED) {
15789                    throw new SecurityException("Requires permission "
15790                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15791                }
15792
15793                if (start && fd == null) {
15794                    throw new IllegalArgumentException("null fd");
15795                }
15796
15797                ProcessRecord proc = null;
15798                if (process != null) {
15799                    proc = findProcessLocked(process, userId, "profileControl");
15800                }
15801
15802                if (start && (proc == null || proc.thread == null)) {
15803                    throw new IllegalArgumentException("Unknown process: " + process);
15804                }
15805
15806                if (start) {
15807                    stopProfilerLocked(null, null, 0);
15808                    setProfileApp(proc.info, proc.processName, path, fd, false);
15809                    mProfileProc = proc;
15810                    mProfileType = profileType;
15811                    try {
15812                        fd = fd.dup();
15813                    } catch (IOException e) {
15814                        fd = null;
15815                    }
15816                    proc.thread.profilerControl(start, path, fd, profileType);
15817                    fd = null;
15818                    mProfileFd = null;
15819                } else {
15820                    stopProfilerLocked(proc, path, profileType);
15821                    if (fd != null) {
15822                        try {
15823                            fd.close();
15824                        } catch (IOException e) {
15825                        }
15826                    }
15827                }
15828
15829                return true;
15830            }
15831        } catch (RemoteException e) {
15832            throw new IllegalStateException("Process disappeared");
15833        } finally {
15834            if (fd != null) {
15835                try {
15836                    fd.close();
15837                } catch (IOException e) {
15838                }
15839            }
15840        }
15841    }
15842
15843    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15844        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15845                userId, true, true, callName, null);
15846        ProcessRecord proc = null;
15847        try {
15848            int pid = Integer.parseInt(process);
15849            synchronized (mPidsSelfLocked) {
15850                proc = mPidsSelfLocked.get(pid);
15851            }
15852        } catch (NumberFormatException e) {
15853        }
15854
15855        if (proc == null) {
15856            ArrayMap<String, SparseArray<ProcessRecord>> all
15857                    = mProcessNames.getMap();
15858            SparseArray<ProcessRecord> procs = all.get(process);
15859            if (procs != null && procs.size() > 0) {
15860                proc = procs.valueAt(0);
15861                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15862                    for (int i=1; i<procs.size(); i++) {
15863                        ProcessRecord thisProc = procs.valueAt(i);
15864                        if (thisProc.userId == userId) {
15865                            proc = thisProc;
15866                            break;
15867                        }
15868                    }
15869                }
15870            }
15871        }
15872
15873        return proc;
15874    }
15875
15876    public boolean dumpHeap(String process, int userId, boolean managed,
15877            String path, ParcelFileDescriptor fd) throws RemoteException {
15878
15879        try {
15880            synchronized (this) {
15881                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15882                // its own permission (same as profileControl).
15883                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15884                        != PackageManager.PERMISSION_GRANTED) {
15885                    throw new SecurityException("Requires permission "
15886                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15887                }
15888
15889                if (fd == null) {
15890                    throw new IllegalArgumentException("null fd");
15891                }
15892
15893                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15894                if (proc == null || proc.thread == null) {
15895                    throw new IllegalArgumentException("Unknown process: " + process);
15896                }
15897
15898                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15899                if (!isDebuggable) {
15900                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15901                        throw new SecurityException("Process not debuggable: " + proc);
15902                    }
15903                }
15904
15905                proc.thread.dumpHeap(managed, path, fd);
15906                fd = null;
15907                return true;
15908            }
15909        } catch (RemoteException e) {
15910            throw new IllegalStateException("Process disappeared");
15911        } finally {
15912            if (fd != null) {
15913                try {
15914                    fd.close();
15915                } catch (IOException e) {
15916                }
15917            }
15918        }
15919    }
15920
15921    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15922    public void monitor() {
15923        synchronized (this) { }
15924    }
15925
15926    void onCoreSettingsChange(Bundle settings) {
15927        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15928            ProcessRecord processRecord = mLruProcesses.get(i);
15929            try {
15930                if (processRecord.thread != null) {
15931                    processRecord.thread.setCoreSettings(settings);
15932                }
15933            } catch (RemoteException re) {
15934                /* ignore */
15935            }
15936        }
15937    }
15938
15939    // Multi-user methods
15940
15941    @Override
15942    public boolean switchUser(final int userId) {
15943        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15944                != PackageManager.PERMISSION_GRANTED) {
15945            String msg = "Permission Denial: switchUser() from pid="
15946                    + Binder.getCallingPid()
15947                    + ", uid=" + Binder.getCallingUid()
15948                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15949            Slog.w(TAG, msg);
15950            throw new SecurityException(msg);
15951        }
15952
15953        final long ident = Binder.clearCallingIdentity();
15954        try {
15955            synchronized (this) {
15956                final int oldUserId = mCurrentUserId;
15957                if (oldUserId == userId) {
15958                    return true;
15959                }
15960
15961                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15962                if (userInfo == null) {
15963                    Slog.w(TAG, "No user info for user #" + userId);
15964                    return false;
15965                }
15966
15967                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15968                        R.anim.screen_user_enter);
15969
15970                boolean needStart = false;
15971
15972                // If the user we are switching to is not currently started, then
15973                // we need to start it now.
15974                if (mStartedUsers.get(userId) == null) {
15975                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
15976                    updateStartedUserArrayLocked();
15977                    needStart = true;
15978                }
15979
15980                mCurrentUserId = userId;
15981                final Integer userIdInt = Integer.valueOf(userId);
15982                mUserLru.remove(userIdInt);
15983                mUserLru.add(userIdInt);
15984
15985                mWindowManager.setCurrentUser(userId);
15986
15987                // Once the internal notion of the active user has switched, we lock the device
15988                // with the option to show the user switcher on the keyguard.
15989                mWindowManager.lockNow(null);
15990
15991                final UserStartedState uss = mStartedUsers.get(userId);
15992
15993                // Make sure user is in the started state.  If it is currently
15994                // stopping, we need to knock that off.
15995                if (uss.mState == UserStartedState.STATE_STOPPING) {
15996                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
15997                    // so we can just fairly silently bring the user back from
15998                    // the almost-dead.
15999                    uss.mState = UserStartedState.STATE_RUNNING;
16000                    updateStartedUserArrayLocked();
16001                    needStart = true;
16002                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16003                    // This means ACTION_SHUTDOWN has been sent, so we will
16004                    // need to treat this as a new boot of the user.
16005                    uss.mState = UserStartedState.STATE_BOOTING;
16006                    updateStartedUserArrayLocked();
16007                    needStart = true;
16008                }
16009
16010                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16011                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16012                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16013                        oldUserId, userId, uss));
16014                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16015                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16016                if (needStart) {
16017                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16018                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16019                            | Intent.FLAG_RECEIVER_FOREGROUND);
16020                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16021                    broadcastIntentLocked(null, null, intent,
16022                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16023                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16024                }
16025
16026                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16027                    if (userId != 0) {
16028                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16029                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16030                        broadcastIntentLocked(null, null, intent, null,
16031                                new IIntentReceiver.Stub() {
16032                                    public void performReceive(Intent intent, int resultCode,
16033                                            String data, Bundle extras, boolean ordered,
16034                                            boolean sticky, int sendingUser) {
16035                                        userInitialized(uss, userId);
16036                                    }
16037                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16038                                true, false, MY_PID, Process.SYSTEM_UID,
16039                                userId);
16040                        uss.initializing = true;
16041                    } else {
16042                        getUserManagerLocked().makeInitialized(userInfo.id);
16043                    }
16044                }
16045
16046                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16047                if (homeInFront) {
16048                    startHomeActivityLocked(userId);
16049                } else {
16050                    mStackSupervisor.resumeTopActivitiesLocked();
16051                }
16052
16053                EventLogTags.writeAmSwitchUser(userId);
16054                getUserManagerLocked().userForeground(userId);
16055                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16056                if (needStart) {
16057                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16058                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16059                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16060                    broadcastIntentLocked(null, null, intent,
16061                            null, new IIntentReceiver.Stub() {
16062                                @Override
16063                                public void performReceive(Intent intent, int resultCode, String data,
16064                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16065                                        throws RemoteException {
16066                                }
16067                            }, 0, null, null,
16068                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16069                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16070                }
16071            }
16072        } finally {
16073            Binder.restoreCallingIdentity(ident);
16074        }
16075
16076        return true;
16077    }
16078
16079    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16080        long ident = Binder.clearCallingIdentity();
16081        try {
16082            Intent intent;
16083            if (oldUserId >= 0) {
16084                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16085                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16086                        | Intent.FLAG_RECEIVER_FOREGROUND);
16087                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16088                broadcastIntentLocked(null, null, intent,
16089                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16090                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16091            }
16092            if (newUserId >= 0) {
16093                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16094                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16095                        | Intent.FLAG_RECEIVER_FOREGROUND);
16096                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16097                broadcastIntentLocked(null, null, intent,
16098                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16099                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16100                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16101                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16102                        | Intent.FLAG_RECEIVER_FOREGROUND);
16103                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16104                broadcastIntentLocked(null, null, intent,
16105                        null, null, 0, null, null,
16106                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16107                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16108            }
16109        } finally {
16110            Binder.restoreCallingIdentity(ident);
16111        }
16112    }
16113
16114    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16115            final int newUserId) {
16116        final int N = mUserSwitchObservers.beginBroadcast();
16117        if (N > 0) {
16118            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16119                int mCount = 0;
16120                @Override
16121                public void sendResult(Bundle data) throws RemoteException {
16122                    synchronized (ActivityManagerService.this) {
16123                        if (mCurUserSwitchCallback == this) {
16124                            mCount++;
16125                            if (mCount == N) {
16126                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16127                            }
16128                        }
16129                    }
16130                }
16131            };
16132            synchronized (this) {
16133                uss.switching = true;
16134                mCurUserSwitchCallback = callback;
16135            }
16136            for (int i=0; i<N; i++) {
16137                try {
16138                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16139                            newUserId, callback);
16140                } catch (RemoteException e) {
16141                }
16142            }
16143        } else {
16144            synchronized (this) {
16145                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16146            }
16147        }
16148        mUserSwitchObservers.finishBroadcast();
16149    }
16150
16151    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16152        synchronized (this) {
16153            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16154            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16155        }
16156    }
16157
16158    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16159        mCurUserSwitchCallback = null;
16160        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16161        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16162                oldUserId, newUserId, uss));
16163    }
16164
16165    void userInitialized(UserStartedState uss, int newUserId) {
16166        completeSwitchAndInitalize(uss, newUserId, true, false);
16167    }
16168
16169    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16170        completeSwitchAndInitalize(uss, newUserId, false, true);
16171    }
16172
16173    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16174            boolean clearInitializing, boolean clearSwitching) {
16175        boolean unfrozen = false;
16176        synchronized (this) {
16177            if (clearInitializing) {
16178                uss.initializing = false;
16179                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16180            }
16181            if (clearSwitching) {
16182                uss.switching = false;
16183            }
16184            if (!uss.switching && !uss.initializing) {
16185                mWindowManager.stopFreezingScreen();
16186                unfrozen = true;
16187            }
16188        }
16189        if (unfrozen) {
16190            final int N = mUserSwitchObservers.beginBroadcast();
16191            for (int i=0; i<N; i++) {
16192                try {
16193                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16194                } catch (RemoteException e) {
16195                }
16196            }
16197            mUserSwitchObservers.finishBroadcast();
16198        }
16199    }
16200
16201    void finishUserSwitch(UserStartedState uss) {
16202        synchronized (this) {
16203            if (uss.mState == UserStartedState.STATE_BOOTING
16204                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16205                uss.mState = UserStartedState.STATE_RUNNING;
16206                final int userId = uss.mHandle.getIdentifier();
16207                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16208                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16209                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16210                broadcastIntentLocked(null, null, intent,
16211                        null, null, 0, null, null,
16212                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16213                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16214            }
16215            int num = mUserLru.size();
16216            int i = 0;
16217            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16218                Integer oldUserId = mUserLru.get(i);
16219                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16220                if (oldUss == null) {
16221                    // Shouldn't happen, but be sane if it does.
16222                    mUserLru.remove(i);
16223                    num--;
16224                    continue;
16225                }
16226                if (oldUss.mState == UserStartedState.STATE_STOPPING
16227                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16228                    // This user is already stopping, doesn't count.
16229                    num--;
16230                    i++;
16231                    continue;
16232                }
16233                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16234                    // Owner and current can't be stopped, but count as running.
16235                    i++;
16236                    continue;
16237                }
16238                // This is a user to be stopped.
16239                stopUserLocked(oldUserId, null);
16240                num--;
16241                i++;
16242            }
16243        }
16244    }
16245
16246    @Override
16247    public int stopUser(final int userId, final IStopUserCallback callback) {
16248        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16249                != PackageManager.PERMISSION_GRANTED) {
16250            String msg = "Permission Denial: switchUser() from pid="
16251                    + Binder.getCallingPid()
16252                    + ", uid=" + Binder.getCallingUid()
16253                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16254            Slog.w(TAG, msg);
16255            throw new SecurityException(msg);
16256        }
16257        if (userId <= 0) {
16258            throw new IllegalArgumentException("Can't stop primary user " + userId);
16259        }
16260        synchronized (this) {
16261            return stopUserLocked(userId, callback);
16262        }
16263    }
16264
16265    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16266        if (mCurrentUserId == userId) {
16267            return ActivityManager.USER_OP_IS_CURRENT;
16268        }
16269
16270        final UserStartedState uss = mStartedUsers.get(userId);
16271        if (uss == null) {
16272            // User is not started, nothing to do...  but we do need to
16273            // callback if requested.
16274            if (callback != null) {
16275                mHandler.post(new Runnable() {
16276                    @Override
16277                    public void run() {
16278                        try {
16279                            callback.userStopped(userId);
16280                        } catch (RemoteException e) {
16281                        }
16282                    }
16283                });
16284            }
16285            return ActivityManager.USER_OP_SUCCESS;
16286        }
16287
16288        if (callback != null) {
16289            uss.mStopCallbacks.add(callback);
16290        }
16291
16292        if (uss.mState != UserStartedState.STATE_STOPPING
16293                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16294            uss.mState = UserStartedState.STATE_STOPPING;
16295            updateStartedUserArrayLocked();
16296
16297            long ident = Binder.clearCallingIdentity();
16298            try {
16299                // We are going to broadcast ACTION_USER_STOPPING and then
16300                // once that is done send a final ACTION_SHUTDOWN and then
16301                // stop the user.
16302                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16303                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16304                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16305                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16306                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16307                // This is the result receiver for the final shutdown broadcast.
16308                final IIntentReceiver shutdownReceiver = 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                        finishUserStop(uss);
16313                    }
16314                };
16315                // This is the result receiver for the initial stopping broadcast.
16316                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16317                    @Override
16318                    public void performReceive(Intent intent, int resultCode, String data,
16319                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16320                        // On to the next.
16321                        synchronized (ActivityManagerService.this) {
16322                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16323                                // Whoops, we are being started back up.  Abort, abort!
16324                                return;
16325                            }
16326                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16327                        }
16328                        broadcastIntentLocked(null, null, shutdownIntent,
16329                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16330                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16331                    }
16332                };
16333                // Kick things off.
16334                broadcastIntentLocked(null, null, stoppingIntent,
16335                        null, stoppingReceiver, 0, null, null,
16336                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16337                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16338            } finally {
16339                Binder.restoreCallingIdentity(ident);
16340            }
16341        }
16342
16343        return ActivityManager.USER_OP_SUCCESS;
16344    }
16345
16346    void finishUserStop(UserStartedState uss) {
16347        final int userId = uss.mHandle.getIdentifier();
16348        boolean stopped;
16349        ArrayList<IStopUserCallback> callbacks;
16350        synchronized (this) {
16351            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16352            if (mStartedUsers.get(userId) != uss) {
16353                stopped = false;
16354            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16355                stopped = false;
16356            } else {
16357                stopped = true;
16358                // User can no longer run.
16359                mStartedUsers.remove(userId);
16360                mUserLru.remove(Integer.valueOf(userId));
16361                updateStartedUserArrayLocked();
16362
16363                // Clean up all state and processes associated with the user.
16364                // Kill all the processes for the user.
16365                forceStopUserLocked(userId, "finish user");
16366            }
16367        }
16368
16369        for (int i=0; i<callbacks.size(); i++) {
16370            try {
16371                if (stopped) callbacks.get(i).userStopped(userId);
16372                else callbacks.get(i).userStopAborted(userId);
16373            } catch (RemoteException e) {
16374            }
16375        }
16376
16377        mStackSupervisor.removeUserLocked(userId);
16378    }
16379
16380    @Override
16381    public UserInfo getCurrentUser() {
16382        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16383                != PackageManager.PERMISSION_GRANTED) && (
16384                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16385                != PackageManager.PERMISSION_GRANTED)) {
16386            String msg = "Permission Denial: getCurrentUser() from pid="
16387                    + Binder.getCallingPid()
16388                    + ", uid=" + Binder.getCallingUid()
16389                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16390            Slog.w(TAG, msg);
16391            throw new SecurityException(msg);
16392        }
16393        synchronized (this) {
16394            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16395        }
16396    }
16397
16398    int getCurrentUserIdLocked() {
16399        return mCurrentUserId;
16400    }
16401
16402    @Override
16403    public boolean isUserRunning(int userId, boolean orStopped) {
16404        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16405                != PackageManager.PERMISSION_GRANTED) {
16406            String msg = "Permission Denial: isUserRunning() from pid="
16407                    + Binder.getCallingPid()
16408                    + ", uid=" + Binder.getCallingUid()
16409                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16410            Slog.w(TAG, msg);
16411            throw new SecurityException(msg);
16412        }
16413        synchronized (this) {
16414            return isUserRunningLocked(userId, orStopped);
16415        }
16416    }
16417
16418    boolean isUserRunningLocked(int userId, boolean orStopped) {
16419        UserStartedState state = mStartedUsers.get(userId);
16420        if (state == null) {
16421            return false;
16422        }
16423        if (orStopped) {
16424            return true;
16425        }
16426        return state.mState != UserStartedState.STATE_STOPPING
16427                && state.mState != UserStartedState.STATE_SHUTDOWN;
16428    }
16429
16430    @Override
16431    public int[] getRunningUserIds() {
16432        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16433                != PackageManager.PERMISSION_GRANTED) {
16434            String msg = "Permission Denial: isUserRunning() from pid="
16435                    + Binder.getCallingPid()
16436                    + ", uid=" + Binder.getCallingUid()
16437                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16438            Slog.w(TAG, msg);
16439            throw new SecurityException(msg);
16440        }
16441        synchronized (this) {
16442            return mStartedUserArray;
16443        }
16444    }
16445
16446    private void updateStartedUserArrayLocked() {
16447        int num = 0;
16448        for (int i=0; i<mStartedUsers.size();  i++) {
16449            UserStartedState uss = mStartedUsers.valueAt(i);
16450            // This list does not include stopping users.
16451            if (uss.mState != UserStartedState.STATE_STOPPING
16452                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16453                num++;
16454            }
16455        }
16456        mStartedUserArray = new int[num];
16457        num = 0;
16458        for (int i=0; i<mStartedUsers.size();  i++) {
16459            UserStartedState uss = mStartedUsers.valueAt(i);
16460            if (uss.mState != UserStartedState.STATE_STOPPING
16461                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16462                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16463                num++;
16464            }
16465        }
16466    }
16467
16468    @Override
16469    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16470        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16471                != PackageManager.PERMISSION_GRANTED) {
16472            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16473                    + Binder.getCallingPid()
16474                    + ", uid=" + Binder.getCallingUid()
16475                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16476            Slog.w(TAG, msg);
16477            throw new SecurityException(msg);
16478        }
16479
16480        mUserSwitchObservers.register(observer);
16481    }
16482
16483    @Override
16484    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16485        mUserSwitchObservers.unregister(observer);
16486    }
16487
16488    private boolean userExists(int userId) {
16489        if (userId == 0) {
16490            return true;
16491        }
16492        UserManagerService ums = getUserManagerLocked();
16493        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16494    }
16495
16496    int[] getUsersLocked() {
16497        UserManagerService ums = getUserManagerLocked();
16498        return ums != null ? ums.getUserIds() : new int[] { 0 };
16499    }
16500
16501    UserManagerService getUserManagerLocked() {
16502        if (mUserManager == null) {
16503            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16504            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16505        }
16506        return mUserManager;
16507    }
16508
16509    private int applyUserId(int uid, int userId) {
16510        return UserHandle.getUid(userId, uid);
16511    }
16512
16513    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16514        if (info == null) return null;
16515        ApplicationInfo newInfo = new ApplicationInfo(info);
16516        newInfo.uid = applyUserId(info.uid, userId);
16517        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16518                + info.packageName;
16519        return newInfo;
16520    }
16521
16522    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16523        if (aInfo == null
16524                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16525            return aInfo;
16526        }
16527
16528        ActivityInfo info = new ActivityInfo(aInfo);
16529        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16530        return info;
16531    }
16532
16533    private final class LocalService extends ActivityManagerInternal {
16534        @Override
16535        public void goingToSleep() {
16536            ActivityManagerService.this.goingToSleep();
16537        }
16538
16539        @Override
16540        public void wakingUp() {
16541            ActivityManagerService.this.wakingUp();
16542        }
16543    }
16544}
16545