ActivityManagerService.java revision f4c909bcb87d6f103c9f9e8255fa61bd86f4de67
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.util.FastPrintWriter;
46import com.android.internal.util.FastXmlSerializer;
47import com.android.internal.util.MemInfoReader;
48import com.android.internal.util.Preconditions;
49import com.android.server.AppOpsService;
50import com.android.server.AttributeCache;
51import com.android.server.IntentResolver;
52import com.android.server.LocalServices;
53import com.android.server.ServiceThread;
54import com.android.server.SystemService;
55import com.android.server.Watchdog;
56import com.android.server.am.ActivityStack.ActivityState;
57import com.android.server.firewall.IntentFirewall;
58import com.android.server.pm.UserManagerService;
59import com.android.server.wm.AppTransition;
60import com.android.server.wm.WindowManagerService;
61import com.google.android.collect.Lists;
62import com.google.android.collect.Maps;
63
64import dalvik.system.Zygote;
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    String mDebugApp = null;
934    boolean mWaitForDebugger = false;
935    boolean mDebugTransient = false;
936    String mOrigDebugApp = null;
937    boolean mOrigWaitForDebugger = false;
938    boolean mAlwaysFinishActivities = false;
939    IActivityController mController = null;
940    String mProfileApp = null;
941    ProcessRecord mProfileProc = null;
942    String mProfileFile;
943    ParcelFileDescriptor mProfileFd;
944    int mProfileType = 0;
945    boolean mAutoStopProfiler = false;
946    String mOpenGlTraceApp = null;
947
948    static class ProcessChangeItem {
949        static final int CHANGE_ACTIVITIES = 1<<0;
950        static final int CHANGE_IMPORTANCE= 1<<1;
951        int changes;
952        int uid;
953        int pid;
954        int importance;
955        boolean foregroundActivities;
956    }
957
958    final RemoteCallbackList<IProcessObserver> mProcessObservers
959            = new RemoteCallbackList<IProcessObserver>();
960    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
961
962    final ArrayList<ProcessChangeItem> mPendingProcessChanges
963            = new ArrayList<ProcessChangeItem>();
964    final ArrayList<ProcessChangeItem> mAvailProcessChanges
965            = new ArrayList<ProcessChangeItem>();
966
967    /**
968     * Runtime CPU use collection thread.  This object's lock is used to
969     * protect all related state.
970     */
971    final Thread mProcessCpuThread;
972
973    /**
974     * Used to collect process stats when showing not responding dialog.
975     * Protected by mProcessCpuThread.
976     */
977    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
978            MONITOR_THREAD_CPU_USAGE);
979    final AtomicLong mLastCpuTime = new AtomicLong(0);
980    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
981
982    long mLastWriteTime = 0;
983
984    /**
985     * Used to retain an update lock when the foreground activity is in
986     * immersive mode.
987     */
988    final UpdateLock mUpdateLock = new UpdateLock("immersive");
989
990    /**
991     * Set to true after the system has finished booting.
992     */
993    boolean mBooted = false;
994
995    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
996    int mProcessLimitOverride = -1;
997
998    WindowManagerService mWindowManager;
999
1000    final ActivityThread mSystemThread;
1001
1002    int mCurrentUserId = 0;
1003    private UserManagerService mUserManager;
1004
1005    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1006        final ProcessRecord mApp;
1007        final int mPid;
1008        final IApplicationThread mAppThread;
1009
1010        AppDeathRecipient(ProcessRecord app, int pid,
1011                IApplicationThread thread) {
1012            if (localLOGV) Slog.v(
1013                TAG, "New death recipient " + this
1014                + " for thread " + thread.asBinder());
1015            mApp = app;
1016            mPid = pid;
1017            mAppThread = thread;
1018        }
1019
1020        @Override
1021        public void binderDied() {
1022            if (localLOGV) Slog.v(
1023                TAG, "Death received in " + this
1024                + " for thread " + mAppThread.asBinder());
1025            synchronized(ActivityManagerService.this) {
1026                appDiedLocked(mApp, mPid, mAppThread);
1027            }
1028        }
1029    }
1030
1031    static final int SHOW_ERROR_MSG = 1;
1032    static final int SHOW_NOT_RESPONDING_MSG = 2;
1033    static final int SHOW_FACTORY_ERROR_MSG = 3;
1034    static final int UPDATE_CONFIGURATION_MSG = 4;
1035    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1036    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1037    static final int SERVICE_TIMEOUT_MSG = 12;
1038    static final int UPDATE_TIME_ZONE = 13;
1039    static final int SHOW_UID_ERROR_MSG = 14;
1040    static final int IM_FEELING_LUCKY_MSG = 15;
1041    static final int PROC_START_TIMEOUT_MSG = 20;
1042    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1043    static final int KILL_APPLICATION_MSG = 22;
1044    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1045    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1046    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1047    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1048    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1049    static final int CLEAR_DNS_CACHE_MSG = 28;
1050    static final int UPDATE_HTTP_PROXY_MSG = 29;
1051    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1052    static final int DISPATCH_PROCESSES_CHANGED = 31;
1053    static final int DISPATCH_PROCESS_DIED = 32;
1054    static final int REPORT_MEM_USAGE_MSG = 33;
1055    static final int REPORT_USER_SWITCH_MSG = 34;
1056    static final int CONTINUE_USER_SWITCH_MSG = 35;
1057    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1058    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1059    static final int PERSIST_URI_GRANTS_MSG = 38;
1060    static final int REQUEST_ALL_PSS_MSG = 39;
1061
1062    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1063    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1064    static final int FIRST_COMPAT_MODE_MSG = 300;
1065    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1066
1067    AlertDialog mUidAlert;
1068    CompatModeDialog mCompatModeDialog;
1069    long mLastMemUsageReportTime = 0;
1070
1071    /**
1072     * Flag whether the current user is a "monkey", i.e. whether
1073     * the UI is driven by a UI automation tool.
1074     */
1075    private boolean mUserIsMonkey;
1076
1077    final ServiceThread mHandlerThread;
1078    final MainHandler mHandler;
1079
1080    final class MainHandler extends Handler {
1081        public MainHandler(Looper looper) {
1082            super(looper, null, true);
1083        }
1084
1085        @Override
1086        public void handleMessage(Message msg) {
1087            switch (msg.what) {
1088            case SHOW_ERROR_MSG: {
1089                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1090                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1091                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1092                synchronized (ActivityManagerService.this) {
1093                    ProcessRecord proc = (ProcessRecord)data.get("app");
1094                    AppErrorResult res = (AppErrorResult) data.get("result");
1095                    if (proc != null && proc.crashDialog != null) {
1096                        Slog.e(TAG, "App already has crash dialog: " + proc);
1097                        if (res != null) {
1098                            res.set(0);
1099                        }
1100                        return;
1101                    }
1102                    if (!showBackground && UserHandle.getAppId(proc.uid)
1103                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1104                            && proc.pid != MY_PID) {
1105                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1106                        if (res != null) {
1107                            res.set(0);
1108                        }
1109                        return;
1110                    }
1111                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1112                        Dialog d = new AppErrorDialog(mContext,
1113                                ActivityManagerService.this, res, proc);
1114                        d.show();
1115                        proc.crashDialog = d;
1116                    } else {
1117                        // The device is asleep, so just pretend that the user
1118                        // saw a crash dialog and hit "force quit".
1119                        if (res != null) {
1120                            res.set(0);
1121                        }
1122                    }
1123                }
1124
1125                ensureBootCompleted();
1126            } break;
1127            case SHOW_NOT_RESPONDING_MSG: {
1128                synchronized (ActivityManagerService.this) {
1129                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1130                    ProcessRecord proc = (ProcessRecord)data.get("app");
1131                    if (proc != null && proc.anrDialog != null) {
1132                        Slog.e(TAG, "App already has anr dialog: " + proc);
1133                        return;
1134                    }
1135
1136                    Intent intent = new Intent("android.intent.action.ANR");
1137                    if (!mProcessesReady) {
1138                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1139                                | Intent.FLAG_RECEIVER_FOREGROUND);
1140                    }
1141                    broadcastIntentLocked(null, null, intent,
1142                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1143                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1144
1145                    if (mShowDialogs) {
1146                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1147                                mContext, proc, (ActivityRecord)data.get("activity"),
1148                                msg.arg1 != 0);
1149                        d.show();
1150                        proc.anrDialog = d;
1151                    } else {
1152                        // Just kill the app if there is no dialog to be shown.
1153                        killAppAtUsersRequest(proc, null);
1154                    }
1155                }
1156
1157                ensureBootCompleted();
1158            } break;
1159            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1160                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1161                synchronized (ActivityManagerService.this) {
1162                    ProcessRecord proc = (ProcessRecord) data.get("app");
1163                    if (proc == null) {
1164                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1165                        break;
1166                    }
1167                    if (proc.crashDialog != null) {
1168                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1169                        return;
1170                    }
1171                    AppErrorResult res = (AppErrorResult) data.get("result");
1172                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1173                        Dialog d = new StrictModeViolationDialog(mContext,
1174                                ActivityManagerService.this, res, proc);
1175                        d.show();
1176                        proc.crashDialog = d;
1177                    } else {
1178                        // The device is asleep, so just pretend that the user
1179                        // saw a crash dialog and hit "force quit".
1180                        res.set(0);
1181                    }
1182                }
1183                ensureBootCompleted();
1184            } break;
1185            case SHOW_FACTORY_ERROR_MSG: {
1186                Dialog d = new FactoryErrorDialog(
1187                    mContext, msg.getData().getCharSequence("msg"));
1188                d.show();
1189                ensureBootCompleted();
1190            } break;
1191            case UPDATE_CONFIGURATION_MSG: {
1192                final ContentResolver resolver = mContext.getContentResolver();
1193                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1194            } break;
1195            case GC_BACKGROUND_PROCESSES_MSG: {
1196                synchronized (ActivityManagerService.this) {
1197                    performAppGcsIfAppropriateLocked();
1198                }
1199            } break;
1200            case WAIT_FOR_DEBUGGER_MSG: {
1201                synchronized (ActivityManagerService.this) {
1202                    ProcessRecord app = (ProcessRecord)msg.obj;
1203                    if (msg.arg1 != 0) {
1204                        if (!app.waitedForDebugger) {
1205                            Dialog d = new AppWaitingForDebuggerDialog(
1206                                    ActivityManagerService.this,
1207                                    mContext, app);
1208                            app.waitDialog = d;
1209                            app.waitedForDebugger = true;
1210                            d.show();
1211                        }
1212                    } else {
1213                        if (app.waitDialog != null) {
1214                            app.waitDialog.dismiss();
1215                            app.waitDialog = null;
1216                        }
1217                    }
1218                }
1219            } break;
1220            case SERVICE_TIMEOUT_MSG: {
1221                if (mDidDexOpt) {
1222                    mDidDexOpt = false;
1223                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1224                    nmsg.obj = msg.obj;
1225                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1226                    return;
1227                }
1228                mServices.serviceTimeout((ProcessRecord)msg.obj);
1229            } break;
1230            case UPDATE_TIME_ZONE: {
1231                synchronized (ActivityManagerService.this) {
1232                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1233                        ProcessRecord r = mLruProcesses.get(i);
1234                        if (r.thread != null) {
1235                            try {
1236                                r.thread.updateTimeZone();
1237                            } catch (RemoteException ex) {
1238                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1239                            }
1240                        }
1241                    }
1242                }
1243            } break;
1244            case CLEAR_DNS_CACHE_MSG: {
1245                synchronized (ActivityManagerService.this) {
1246                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1247                        ProcessRecord r = mLruProcesses.get(i);
1248                        if (r.thread != null) {
1249                            try {
1250                                r.thread.clearDnsCache();
1251                            } catch (RemoteException ex) {
1252                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1253                            }
1254                        }
1255                    }
1256                }
1257            } break;
1258            case UPDATE_HTTP_PROXY_MSG: {
1259                ProxyProperties proxy = (ProxyProperties)msg.obj;
1260                String host = "";
1261                String port = "";
1262                String exclList = "";
1263                String pacFileUrl = null;
1264                if (proxy != null) {
1265                    host = proxy.getHost();
1266                    port = Integer.toString(proxy.getPort());
1267                    exclList = proxy.getExclusionList();
1268                    pacFileUrl = proxy.getPacFileUrl();
1269                }
1270                synchronized (ActivityManagerService.this) {
1271                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1272                        ProcessRecord r = mLruProcesses.get(i);
1273                        if (r.thread != null) {
1274                            try {
1275                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1276                            } catch (RemoteException ex) {
1277                                Slog.w(TAG, "Failed to update http proxy for: " +
1278                                        r.info.processName);
1279                            }
1280                        }
1281                    }
1282                }
1283            } break;
1284            case SHOW_UID_ERROR_MSG: {
1285                String title = "System UIDs Inconsistent";
1286                String text = "UIDs on the system are inconsistent, you need to wipe your"
1287                        + " data partition or your device will be unstable.";
1288                Log.e(TAG, title + ": " + text);
1289                if (mShowDialogs) {
1290                    // XXX This is a temporary dialog, no need to localize.
1291                    AlertDialog d = new BaseErrorDialog(mContext);
1292                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1293                    d.setCancelable(false);
1294                    d.setTitle(title);
1295                    d.setMessage(text);
1296                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1297                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1298                    mUidAlert = d;
1299                    d.show();
1300                }
1301            } break;
1302            case IM_FEELING_LUCKY_MSG: {
1303                if (mUidAlert != null) {
1304                    mUidAlert.dismiss();
1305                    mUidAlert = null;
1306                }
1307            } break;
1308            case PROC_START_TIMEOUT_MSG: {
1309                if (mDidDexOpt) {
1310                    mDidDexOpt = false;
1311                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1312                    nmsg.obj = msg.obj;
1313                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1314                    return;
1315                }
1316                ProcessRecord app = (ProcessRecord)msg.obj;
1317                synchronized (ActivityManagerService.this) {
1318                    processStartTimedOutLocked(app);
1319                }
1320            } break;
1321            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1322                synchronized (ActivityManagerService.this) {
1323                    doPendingActivityLaunchesLocked(true);
1324                }
1325            } break;
1326            case KILL_APPLICATION_MSG: {
1327                synchronized (ActivityManagerService.this) {
1328                    int appid = msg.arg1;
1329                    boolean restart = (msg.arg2 == 1);
1330                    Bundle bundle = (Bundle)msg.obj;
1331                    String pkg = bundle.getString("pkg");
1332                    String reason = bundle.getString("reason");
1333                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1334                            UserHandle.USER_ALL, reason);
1335                }
1336            } break;
1337            case FINALIZE_PENDING_INTENT_MSG: {
1338                ((PendingIntentRecord)msg.obj).completeFinalize();
1339            } break;
1340            case POST_HEAVY_NOTIFICATION_MSG: {
1341                INotificationManager inm = NotificationManager.getService();
1342                if (inm == null) {
1343                    return;
1344                }
1345
1346                ActivityRecord root = (ActivityRecord)msg.obj;
1347                ProcessRecord process = root.app;
1348                if (process == null) {
1349                    return;
1350                }
1351
1352                try {
1353                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1354                    String text = mContext.getString(R.string.heavy_weight_notification,
1355                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1356                    Notification notification = new Notification();
1357                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1358                    notification.when = 0;
1359                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1360                    notification.tickerText = text;
1361                    notification.defaults = 0; // please be quiet
1362                    notification.sound = null;
1363                    notification.vibrate = null;
1364                    notification.setLatestEventInfo(context, text,
1365                            mContext.getText(R.string.heavy_weight_notification_detail),
1366                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1367                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1368                                    new UserHandle(root.userId)));
1369
1370                    try {
1371                        int[] outId = new int[1];
1372                        inm.enqueueNotificationWithTag("android", "android", null,
1373                                R.string.heavy_weight_notification,
1374                                notification, outId, root.userId);
1375                    } catch (RuntimeException e) {
1376                        Slog.w(ActivityManagerService.TAG,
1377                                "Error showing notification for heavy-weight app", e);
1378                    } catch (RemoteException e) {
1379                    }
1380                } catch (NameNotFoundException e) {
1381                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1382                }
1383            } break;
1384            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1385                INotificationManager inm = NotificationManager.getService();
1386                if (inm == null) {
1387                    return;
1388                }
1389                try {
1390                    inm.cancelNotificationWithTag("android", null,
1391                            R.string.heavy_weight_notification,  msg.arg1);
1392                } catch (RuntimeException e) {
1393                    Slog.w(ActivityManagerService.TAG,
1394                            "Error canceling notification for service", e);
1395                } catch (RemoteException e) {
1396                }
1397            } break;
1398            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1399                synchronized (ActivityManagerService.this) {
1400                    checkExcessivePowerUsageLocked(true);
1401                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1402                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1403                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1404                }
1405            } break;
1406            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1407                synchronized (ActivityManagerService.this) {
1408                    ActivityRecord ar = (ActivityRecord)msg.obj;
1409                    if (mCompatModeDialog != null) {
1410                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1411                                ar.info.applicationInfo.packageName)) {
1412                            return;
1413                        }
1414                        mCompatModeDialog.dismiss();
1415                        mCompatModeDialog = null;
1416                    }
1417                    if (ar != null && false) {
1418                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1419                                ar.packageName)) {
1420                            int mode = mCompatModePackages.computeCompatModeLocked(
1421                                    ar.info.applicationInfo);
1422                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1423                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1424                                mCompatModeDialog = new CompatModeDialog(
1425                                        ActivityManagerService.this, mContext,
1426                                        ar.info.applicationInfo);
1427                                mCompatModeDialog.show();
1428                            }
1429                        }
1430                    }
1431                }
1432                break;
1433            }
1434            case DISPATCH_PROCESSES_CHANGED: {
1435                dispatchProcessesChanged();
1436                break;
1437            }
1438            case DISPATCH_PROCESS_DIED: {
1439                final int pid = msg.arg1;
1440                final int uid = msg.arg2;
1441                dispatchProcessDied(pid, uid);
1442                break;
1443            }
1444            case REPORT_MEM_USAGE_MSG: {
1445                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1446                Thread thread = new Thread() {
1447                    @Override public void run() {
1448                        final SparseArray<ProcessMemInfo> infoMap
1449                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1450                        for (int i=0, N=memInfos.size(); i<N; i++) {
1451                            ProcessMemInfo mi = memInfos.get(i);
1452                            infoMap.put(mi.pid, mi);
1453                        }
1454                        updateCpuStatsNow();
1455                        synchronized (mProcessCpuThread) {
1456                            final int N = mProcessCpuTracker.countStats();
1457                            for (int i=0; i<N; i++) {
1458                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1459                                if (st.vsize > 0) {
1460                                    long pss = Debug.getPss(st.pid, null);
1461                                    if (pss > 0) {
1462                                        if (infoMap.indexOfKey(st.pid) < 0) {
1463                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1464                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1465                                            mi.pss = pss;
1466                                            memInfos.add(mi);
1467                                        }
1468                                    }
1469                                }
1470                            }
1471                        }
1472
1473                        long totalPss = 0;
1474                        for (int i=0, N=memInfos.size(); i<N; i++) {
1475                            ProcessMemInfo mi = memInfos.get(i);
1476                            if (mi.pss == 0) {
1477                                mi.pss = Debug.getPss(mi.pid, null);
1478                            }
1479                            totalPss += mi.pss;
1480                        }
1481                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1482                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1483                                if (lhs.oomAdj != rhs.oomAdj) {
1484                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1485                                }
1486                                if (lhs.pss != rhs.pss) {
1487                                    return lhs.pss < rhs.pss ? 1 : -1;
1488                                }
1489                                return 0;
1490                            }
1491                        });
1492
1493                        StringBuilder tag = new StringBuilder(128);
1494                        StringBuilder stack = new StringBuilder(128);
1495                        tag.append("Low on memory -- ");
1496                        appendMemBucket(tag, totalPss, "total", false);
1497                        appendMemBucket(stack, totalPss, "total", true);
1498
1499                        StringBuilder logBuilder = new StringBuilder(1024);
1500                        logBuilder.append("Low on memory:\n");
1501
1502                        boolean firstLine = true;
1503                        int lastOomAdj = Integer.MIN_VALUE;
1504                        for (int i=0, N=memInfos.size(); i<N; i++) {
1505                            ProcessMemInfo mi = memInfos.get(i);
1506
1507                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1508                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1509                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1510                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1511                                if (lastOomAdj != mi.oomAdj) {
1512                                    lastOomAdj = mi.oomAdj;
1513                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1514                                        tag.append(" / ");
1515                                    }
1516                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1517                                        if (firstLine) {
1518                                            stack.append(":");
1519                                            firstLine = false;
1520                                        }
1521                                        stack.append("\n\t at ");
1522                                    } else {
1523                                        stack.append("$");
1524                                    }
1525                                } else {
1526                                    tag.append(" ");
1527                                    stack.append("$");
1528                                }
1529                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1530                                    appendMemBucket(tag, mi.pss, mi.name, false);
1531                                }
1532                                appendMemBucket(stack, mi.pss, mi.name, true);
1533                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1534                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1535                                    stack.append("(");
1536                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1537                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1538                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1539                                            stack.append(":");
1540                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1541                                        }
1542                                    }
1543                                    stack.append(")");
1544                                }
1545                            }
1546
1547                            logBuilder.append("  ");
1548                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1549                            logBuilder.append(' ');
1550                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1551                            logBuilder.append(' ');
1552                            ProcessList.appendRamKb(logBuilder, mi.pss);
1553                            logBuilder.append(" kB: ");
1554                            logBuilder.append(mi.name);
1555                            logBuilder.append(" (");
1556                            logBuilder.append(mi.pid);
1557                            logBuilder.append(") ");
1558                            logBuilder.append(mi.adjType);
1559                            logBuilder.append('\n');
1560                            if (mi.adjReason != null) {
1561                                logBuilder.append("                      ");
1562                                logBuilder.append(mi.adjReason);
1563                                logBuilder.append('\n');
1564                            }
1565                        }
1566
1567                        logBuilder.append("           ");
1568                        ProcessList.appendRamKb(logBuilder, totalPss);
1569                        logBuilder.append(" kB: TOTAL\n");
1570
1571                        long[] infos = new long[Debug.MEMINFO_COUNT];
1572                        Debug.getMemInfo(infos);
1573                        logBuilder.append("  MemInfo: ");
1574                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1575                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1576                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1577                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1578                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1579                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1580                            logBuilder.append("  ZRAM: ");
1581                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1582                            logBuilder.append(" kB RAM, ");
1583                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1584                            logBuilder.append(" kB swap total, ");
1585                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1586                            logBuilder.append(" kB swap free\n");
1587                        }
1588                        Slog.i(TAG, logBuilder.toString());
1589
1590                        StringBuilder dropBuilder = new StringBuilder(1024);
1591                        /*
1592                        StringWriter oomSw = new StringWriter();
1593                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1594                        StringWriter catSw = new StringWriter();
1595                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1596                        String[] emptyArgs = new String[] { };
1597                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1598                        oomPw.flush();
1599                        String oomString = oomSw.toString();
1600                        */
1601                        dropBuilder.append(stack);
1602                        dropBuilder.append('\n');
1603                        dropBuilder.append('\n');
1604                        dropBuilder.append(logBuilder);
1605                        dropBuilder.append('\n');
1606                        /*
1607                        dropBuilder.append(oomString);
1608                        dropBuilder.append('\n');
1609                        */
1610                        StringWriter catSw = new StringWriter();
1611                        synchronized (ActivityManagerService.this) {
1612                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1613                            String[] emptyArgs = new String[] { };
1614                            catPw.println();
1615                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1616                            catPw.println();
1617                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1618                                    false, false, null);
1619                            catPw.println();
1620                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1621                            catPw.flush();
1622                        }
1623                        dropBuilder.append(catSw.toString());
1624                        addErrorToDropBox("lowmem", null, "system_server", null,
1625                                null, tag.toString(), dropBuilder.toString(), null, null);
1626                        //Slog.i(TAG, "Sent to dropbox:");
1627                        //Slog.i(TAG, dropBuilder.toString());
1628                        synchronized (ActivityManagerService.this) {
1629                            long now = SystemClock.uptimeMillis();
1630                            if (mLastMemUsageReportTime < now) {
1631                                mLastMemUsageReportTime = now;
1632                            }
1633                        }
1634                    }
1635                };
1636                thread.start();
1637                break;
1638            }
1639            case REPORT_USER_SWITCH_MSG: {
1640                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1641                break;
1642            }
1643            case CONTINUE_USER_SWITCH_MSG: {
1644                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1645                break;
1646            }
1647            case USER_SWITCH_TIMEOUT_MSG: {
1648                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1649                break;
1650            }
1651            case IMMERSIVE_MODE_LOCK_MSG: {
1652                final boolean nextState = (msg.arg1 != 0);
1653                if (mUpdateLock.isHeld() != nextState) {
1654                    if (DEBUG_IMMERSIVE) {
1655                        final ActivityRecord r = (ActivityRecord) msg.obj;
1656                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1657                    }
1658                    if (nextState) {
1659                        mUpdateLock.acquire();
1660                    } else {
1661                        mUpdateLock.release();
1662                    }
1663                }
1664                break;
1665            }
1666            case PERSIST_URI_GRANTS_MSG: {
1667                writeGrantedUriPermissions();
1668                break;
1669            }
1670            case REQUEST_ALL_PSS_MSG: {
1671                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1672                break;
1673            }
1674            }
1675        }
1676    };
1677
1678    static final int COLLECT_PSS_BG_MSG = 1;
1679
1680    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1681        @Override
1682        public void handleMessage(Message msg) {
1683            switch (msg.what) {
1684            case COLLECT_PSS_BG_MSG: {
1685                int i=0, num=0;
1686                long start = SystemClock.uptimeMillis();
1687                long[] tmp = new long[1];
1688                do {
1689                    ProcessRecord proc;
1690                    int procState;
1691                    int pid;
1692                    synchronized (ActivityManagerService.this) {
1693                        if (i >= mPendingPssProcesses.size()) {
1694                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1695                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1696                            mPendingPssProcesses.clear();
1697                            return;
1698                        }
1699                        proc = mPendingPssProcesses.get(i);
1700                        procState = proc.pssProcState;
1701                        if (proc.thread != null && procState == proc.setProcState) {
1702                            pid = proc.pid;
1703                        } else {
1704                            proc = null;
1705                            pid = 0;
1706                        }
1707                        i++;
1708                    }
1709                    if (proc != null) {
1710                        long pss = Debug.getPss(pid, tmp);
1711                        synchronized (ActivityManagerService.this) {
1712                            if (proc.thread != null && proc.setProcState == procState
1713                                    && proc.pid == pid) {
1714                                num++;
1715                                proc.lastPssTime = SystemClock.uptimeMillis();
1716                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1717                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1718                                        + ": " + pss + " lastPss=" + proc.lastPss
1719                                        + " state=" + ProcessList.makeProcStateString(procState));
1720                                if (proc.initialIdlePss == 0) {
1721                                    proc.initialIdlePss = pss;
1722                                }
1723                                proc.lastPss = pss;
1724                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1725                                    proc.lastCachedPss = pss;
1726                                }
1727                            }
1728                        }
1729                    }
1730                } while (true);
1731            }
1732            }
1733        }
1734    };
1735
1736    public void setSystemProcess() {
1737        try {
1738            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1739            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1740            ServiceManager.addService("meminfo", new MemBinder(this));
1741            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1742            ServiceManager.addService("dbinfo", new DbBinder(this));
1743            if (MONITOR_CPU_USAGE) {
1744                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1745            }
1746            ServiceManager.addService("permission", new PermissionController(this));
1747
1748            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1749                    "android", STOCK_PM_FLAGS);
1750            mSystemThread.installSystemApplicationInfo(info);
1751
1752            synchronized (this) {
1753                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1754                app.persistent = true;
1755                app.pid = MY_PID;
1756                app.maxAdj = ProcessList.SYSTEM_ADJ;
1757                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1758                mProcessNames.put(app.processName, app.uid, app);
1759                synchronized (mPidsSelfLocked) {
1760                    mPidsSelfLocked.put(app.pid, app);
1761                }
1762                updateLruProcessLocked(app, false, null);
1763                updateOomAdjLocked();
1764            }
1765        } catch (PackageManager.NameNotFoundException e) {
1766            throw new RuntimeException(
1767                    "Unable to find android system package", e);
1768        }
1769    }
1770
1771    public void setWindowManager(WindowManagerService wm) {
1772        mWindowManager = wm;
1773        mStackSupervisor.setWindowManager(wm);
1774    }
1775
1776    public void startObservingNativeCrashes() {
1777        final NativeCrashListener ncl = new NativeCrashListener(this);
1778        ncl.start();
1779    }
1780
1781    public IAppOpsService getAppOpsService() {
1782        return mAppOpsService;
1783    }
1784
1785    static class MemBinder extends Binder {
1786        ActivityManagerService mActivityManagerService;
1787        MemBinder(ActivityManagerService activityManagerService) {
1788            mActivityManagerService = activityManagerService;
1789        }
1790
1791        @Override
1792        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1793            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1794                    != PackageManager.PERMISSION_GRANTED) {
1795                pw.println("Permission Denial: can't dump meminfo from from pid="
1796                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1797                        + " without permission " + android.Manifest.permission.DUMP);
1798                return;
1799            }
1800
1801            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1802        }
1803    }
1804
1805    static class GraphicsBinder extends Binder {
1806        ActivityManagerService mActivityManagerService;
1807        GraphicsBinder(ActivityManagerService activityManagerService) {
1808            mActivityManagerService = activityManagerService;
1809        }
1810
1811        @Override
1812        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1813            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1814                    != PackageManager.PERMISSION_GRANTED) {
1815                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1816                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1817                        + " without permission " + android.Manifest.permission.DUMP);
1818                return;
1819            }
1820
1821            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1822        }
1823    }
1824
1825    static class DbBinder extends Binder {
1826        ActivityManagerService mActivityManagerService;
1827        DbBinder(ActivityManagerService activityManagerService) {
1828            mActivityManagerService = activityManagerService;
1829        }
1830
1831        @Override
1832        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1833            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1834                    != PackageManager.PERMISSION_GRANTED) {
1835                pw.println("Permission Denial: can't dump dbinfo from from pid="
1836                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1837                        + " without permission " + android.Manifest.permission.DUMP);
1838                return;
1839            }
1840
1841            mActivityManagerService.dumpDbInfo(fd, pw, args);
1842        }
1843    }
1844
1845    static class CpuBinder extends Binder {
1846        ActivityManagerService mActivityManagerService;
1847        CpuBinder(ActivityManagerService activityManagerService) {
1848            mActivityManagerService = activityManagerService;
1849        }
1850
1851        @Override
1852        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1853            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1854                    != PackageManager.PERMISSION_GRANTED) {
1855                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1856                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1857                        + " without permission " + android.Manifest.permission.DUMP);
1858                return;
1859            }
1860
1861            synchronized (mActivityManagerService.mProcessCpuThread) {
1862                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1863                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1864                        SystemClock.uptimeMillis()));
1865            }
1866        }
1867    }
1868
1869    public static final class Lifecycle extends SystemService {
1870        private final ActivityManagerService mService;
1871
1872        public Lifecycle(Context context) {
1873            super(context);
1874            mService = new ActivityManagerService(context);
1875        }
1876
1877        @Override
1878        public void onStart() {
1879            mService.start();
1880        }
1881
1882        public ActivityManagerService getService() {
1883            return mService;
1884        }
1885    }
1886
1887    // Note: This method is invoked on the main thread but may need to attach various
1888    // handlers to other threads.  So take care to be explicit about the looper.
1889    public ActivityManagerService(Context systemContext) {
1890        mContext = systemContext;
1891        mFactoryTest = FactoryTest.getMode();
1892        mSystemThread = ActivityThread.currentActivityThread();
1893
1894        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1895
1896        mHandlerThread = new ServiceThread(TAG,
1897                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1898        mHandlerThread.start();
1899        mHandler = new MainHandler(mHandlerThread.getLooper());
1900
1901        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1902                "foreground", BROADCAST_FG_TIMEOUT, false);
1903        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1904                "background", BROADCAST_BG_TIMEOUT, true);
1905        mBroadcastQueues[0] = mFgBroadcastQueue;
1906        mBroadcastQueues[1] = mBgBroadcastQueue;
1907
1908        mServices = new ActiveServices(this);
1909        mProviderMap = new ProviderMap(this);
1910
1911        // TODO: Move creation of battery stats service outside of activity manager service.
1912        File dataDir = Environment.getDataDirectory();
1913        File systemDir = new File(dataDir, "system");
1914        systemDir.mkdirs();
1915        mBatteryStatsService = new BatteryStatsService(new File(
1916                systemDir, "batterystats.bin").toString(), mHandler);
1917        mBatteryStatsService.getActiveStatistics().readLocked();
1918        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1919        mOnBattery = DEBUG_POWER ? true
1920                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1921        mBatteryStatsService.getActiveStatistics().setCallback(this);
1922
1923        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1924
1925        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1926        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1927
1928        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1929
1930        // User 0 is the first and only user that runs at boot.
1931        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1932        mUserLru.add(Integer.valueOf(0));
1933        updateStartedUserArrayLocked();
1934
1935        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1936            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1937
1938        mConfiguration.setToDefaults();
1939        mConfiguration.setLocale(Locale.getDefault());
1940
1941        mConfigurationSeq = mConfiguration.seq = 1;
1942        mProcessCpuTracker.init();
1943
1944        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1945        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1946        mStackSupervisor = new ActivityStackSupervisor(this);
1947
1948        mProcessCpuThread = new Thread("CpuTracker") {
1949            @Override
1950            public void run() {
1951                while (true) {
1952                    try {
1953                        try {
1954                            synchronized(this) {
1955                                final long now = SystemClock.uptimeMillis();
1956                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1957                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1958                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1959                                //        + ", write delay=" + nextWriteDelay);
1960                                if (nextWriteDelay < nextCpuDelay) {
1961                                    nextCpuDelay = nextWriteDelay;
1962                                }
1963                                if (nextCpuDelay > 0) {
1964                                    mProcessCpuMutexFree.set(true);
1965                                    this.wait(nextCpuDelay);
1966                                }
1967                            }
1968                        } catch (InterruptedException e) {
1969                        }
1970                        updateCpuStatsNow();
1971                    } catch (Exception e) {
1972                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1973                    }
1974                }
1975            }
1976        };
1977
1978        Watchdog.getInstance().addMonitor(this);
1979        Watchdog.getInstance().addThread(mHandler);
1980    }
1981
1982    private void start() {
1983        mProcessCpuThread.start();
1984
1985        mBatteryStatsService.publish(mContext);
1986        mUsageStatsService.publish(mContext);
1987        mAppOpsService.publish(mContext);
1988
1989        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
1990    }
1991
1992    @Override
1993    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1994            throws RemoteException {
1995        if (code == SYSPROPS_TRANSACTION) {
1996            // We need to tell all apps about the system property change.
1997            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1998            synchronized(this) {
1999                final int NP = mProcessNames.getMap().size();
2000                for (int ip=0; ip<NP; ip++) {
2001                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2002                    final int NA = apps.size();
2003                    for (int ia=0; ia<NA; ia++) {
2004                        ProcessRecord app = apps.valueAt(ia);
2005                        if (app.thread != null) {
2006                            procs.add(app.thread.asBinder());
2007                        }
2008                    }
2009                }
2010            }
2011
2012            int N = procs.size();
2013            for (int i=0; i<N; i++) {
2014                Parcel data2 = Parcel.obtain();
2015                try {
2016                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2017                } catch (RemoteException e) {
2018                }
2019                data2.recycle();
2020            }
2021        }
2022        try {
2023            return super.onTransact(code, data, reply, flags);
2024        } catch (RuntimeException e) {
2025            // The activity manager only throws security exceptions, so let's
2026            // log all others.
2027            if (!(e instanceof SecurityException)) {
2028                Slog.wtf(TAG, "Activity Manager Crash", e);
2029            }
2030            throw e;
2031        }
2032    }
2033
2034    void updateCpuStats() {
2035        final long now = SystemClock.uptimeMillis();
2036        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2037            return;
2038        }
2039        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2040            synchronized (mProcessCpuThread) {
2041                mProcessCpuThread.notify();
2042            }
2043        }
2044    }
2045
2046    void updateCpuStatsNow() {
2047        synchronized (mProcessCpuThread) {
2048            mProcessCpuMutexFree.set(false);
2049            final long now = SystemClock.uptimeMillis();
2050            boolean haveNewCpuStats = false;
2051
2052            if (MONITOR_CPU_USAGE &&
2053                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2054                mLastCpuTime.set(now);
2055                haveNewCpuStats = true;
2056                mProcessCpuTracker.update();
2057                //Slog.i(TAG, mProcessCpu.printCurrentState());
2058                //Slog.i(TAG, "Total CPU usage: "
2059                //        + mProcessCpu.getTotalCpuPercent() + "%");
2060
2061                // Slog the cpu usage if the property is set.
2062                if ("true".equals(SystemProperties.get("events.cpu"))) {
2063                    int user = mProcessCpuTracker.getLastUserTime();
2064                    int system = mProcessCpuTracker.getLastSystemTime();
2065                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2066                    int irq = mProcessCpuTracker.getLastIrqTime();
2067                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2068                    int idle = mProcessCpuTracker.getLastIdleTime();
2069
2070                    int total = user + system + iowait + irq + softIrq + idle;
2071                    if (total == 0) total = 1;
2072
2073                    EventLog.writeEvent(EventLogTags.CPU,
2074                            ((user+system+iowait+irq+softIrq) * 100) / total,
2075                            (user * 100) / total,
2076                            (system * 100) / total,
2077                            (iowait * 100) / total,
2078                            (irq * 100) / total,
2079                            (softIrq * 100) / total);
2080                }
2081            }
2082
2083            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2084            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2085            synchronized(bstats) {
2086                synchronized(mPidsSelfLocked) {
2087                    if (haveNewCpuStats) {
2088                        if (mOnBattery) {
2089                            int perc = bstats.startAddingCpuLocked();
2090                            int totalUTime = 0;
2091                            int totalSTime = 0;
2092                            final int N = mProcessCpuTracker.countStats();
2093                            for (int i=0; i<N; i++) {
2094                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2095                                if (!st.working) {
2096                                    continue;
2097                                }
2098                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2099                                int otherUTime = (st.rel_utime*perc)/100;
2100                                int otherSTime = (st.rel_stime*perc)/100;
2101                                totalUTime += otherUTime;
2102                                totalSTime += otherSTime;
2103                                if (pr != null) {
2104                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
2105                                            st.name, st.pid);
2106                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2107                                            st.rel_stime-otherSTime);
2108                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2109                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2110                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
2111                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2112                                    if (ps == null) {
2113                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
2114                                                "(Unknown)");
2115                                    }
2116                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2117                                            st.rel_stime-otherSTime);
2118                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2119                                } else {
2120                                    BatteryStatsImpl.Uid.Proc ps =
2121                                            bstats.getProcessStatsLocked(st.name, st.pid);
2122                                    if (ps != null) {
2123                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2124                                                st.rel_stime-otherSTime);
2125                                        ps.addSpeedStepTimes(cpuSpeedTimes);
2126                                    }
2127                                }
2128                            }
2129                            bstats.finishAddingCpuLocked(perc, totalUTime,
2130                                    totalSTime, cpuSpeedTimes);
2131                        }
2132                    }
2133                }
2134
2135                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2136                    mLastWriteTime = now;
2137                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2138                }
2139            }
2140        }
2141    }
2142
2143    @Override
2144    public void batteryNeedsCpuUpdate() {
2145        updateCpuStatsNow();
2146    }
2147
2148    @Override
2149    public void batteryPowerChanged(boolean onBattery) {
2150        // When plugging in, update the CPU stats first before changing
2151        // the plug state.
2152        updateCpuStatsNow();
2153        synchronized (this) {
2154            synchronized(mPidsSelfLocked) {
2155                mOnBattery = DEBUG_POWER ? true : onBattery;
2156            }
2157        }
2158    }
2159
2160    /**
2161     * Initialize the application bind args. These are passed to each
2162     * process when the bindApplication() IPC is sent to the process. They're
2163     * lazily setup to make sure the services are running when they're asked for.
2164     */
2165    private HashMap<String, IBinder> getCommonServicesLocked() {
2166        if (mAppBindArgs == null) {
2167            mAppBindArgs = new HashMap<String, IBinder>();
2168
2169            // Setup the application init args
2170            mAppBindArgs.put("package", ServiceManager.getService("package"));
2171            mAppBindArgs.put("window", ServiceManager.getService("window"));
2172            mAppBindArgs.put(Context.ALARM_SERVICE,
2173                    ServiceManager.getService(Context.ALARM_SERVICE));
2174        }
2175        return mAppBindArgs;
2176    }
2177
2178    final void setFocusedActivityLocked(ActivityRecord r) {
2179        if (mFocusedActivity != r) {
2180            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2181            mFocusedActivity = r;
2182            mStackSupervisor.setFocusedStack(r);
2183            if (r != null) {
2184                mWindowManager.setFocusedApp(r.appToken, true);
2185            }
2186            applyUpdateLockStateLocked(r);
2187        }
2188    }
2189
2190    @Override
2191    public void setFocusedStack(int stackId) {
2192        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2193        synchronized (ActivityManagerService.this) {
2194            ActivityStack stack = mStackSupervisor.getStack(stackId);
2195            if (stack != null) {
2196                ActivityRecord r = stack.topRunningActivityLocked(null);
2197                if (r != null) {
2198                    setFocusedActivityLocked(r);
2199                }
2200            }
2201        }
2202    }
2203
2204    @Override
2205    public void notifyActivityDrawn(IBinder token) {
2206        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2207        synchronized (this) {
2208            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2209            if (r != null) {
2210                r.task.stack.notifyActivityDrawnLocked(r);
2211            }
2212        }
2213    }
2214
2215    final void applyUpdateLockStateLocked(ActivityRecord r) {
2216        // Modifications to the UpdateLock state are done on our handler, outside
2217        // the activity manager's locks.  The new state is determined based on the
2218        // state *now* of the relevant activity record.  The object is passed to
2219        // the handler solely for logging detail, not to be consulted/modified.
2220        final boolean nextState = r != null && r.immersive;
2221        mHandler.sendMessage(
2222                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2223    }
2224
2225    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2226        Message msg = Message.obtain();
2227        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2228        msg.obj = r.task.askedCompatMode ? null : r;
2229        mHandler.sendMessage(msg);
2230    }
2231
2232    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2233            String what, Object obj, ProcessRecord srcApp) {
2234        app.lastActivityTime = now;
2235
2236        if (app.activities.size() > 0) {
2237            // Don't want to touch dependent processes that are hosting activities.
2238            return index;
2239        }
2240
2241        int lrui = mLruProcesses.lastIndexOf(app);
2242        if (lrui < 0) {
2243            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2244                    + what + " " + obj + " from " + srcApp);
2245            return index;
2246        }
2247
2248        if (lrui >= index) {
2249            // Don't want to cause this to move dependent processes *back* in the
2250            // list as if they were less frequently used.
2251            return index;
2252        }
2253
2254        if (lrui >= mLruProcessActivityStart) {
2255            // Don't want to touch dependent processes that are hosting activities.
2256            return index;
2257        }
2258
2259        mLruProcesses.remove(lrui);
2260        if (index > 0) {
2261            index--;
2262        }
2263        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2264                + " in LRU list: " + app);
2265        mLruProcesses.add(index, app);
2266        return index;
2267    }
2268
2269    final void removeLruProcessLocked(ProcessRecord app) {
2270        int lrui = mLruProcesses.lastIndexOf(app);
2271        if (lrui >= 0) {
2272            if (lrui <= mLruProcessActivityStart) {
2273                mLruProcessActivityStart--;
2274            }
2275            if (lrui <= mLruProcessServiceStart) {
2276                mLruProcessServiceStart--;
2277            }
2278            mLruProcesses.remove(lrui);
2279        }
2280    }
2281
2282    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2283            ProcessRecord client) {
2284        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2285        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2286        if (!activityChange && hasActivity) {
2287            // The process has activties, so we are only going to allow activity-based
2288            // adjustments move it.  It should be kept in the front of the list with other
2289            // processes that have activities, and we don't want those to change their
2290            // order except due to activity operations.
2291            return;
2292        }
2293
2294        mLruSeq++;
2295        final long now = SystemClock.uptimeMillis();
2296        app.lastActivityTime = now;
2297
2298        // First a quick reject: if the app is already at the position we will
2299        // put it, then there is nothing to do.
2300        if (hasActivity) {
2301            final int N = mLruProcesses.size();
2302            if (N > 0 && mLruProcesses.get(N-1) == app) {
2303                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2304                return;
2305            }
2306        } else {
2307            if (mLruProcessServiceStart > 0
2308                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2309                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2310                return;
2311            }
2312        }
2313
2314        int lrui = mLruProcesses.lastIndexOf(app);
2315
2316        if (app.persistent && lrui >= 0) {
2317            // We don't care about the position of persistent processes, as long as
2318            // they are in the list.
2319            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2320            return;
2321        }
2322
2323        /* In progress: compute new position first, so we can avoid doing work
2324           if the process is not actually going to move.  Not yet working.
2325        int addIndex;
2326        int nextIndex;
2327        boolean inActivity = false, inService = false;
2328        if (hasActivity) {
2329            // Process has activities, put it at the very tipsy-top.
2330            addIndex = mLruProcesses.size();
2331            nextIndex = mLruProcessServiceStart;
2332            inActivity = true;
2333        } else if (hasService) {
2334            // Process has services, put it at the top of the service list.
2335            addIndex = mLruProcessActivityStart;
2336            nextIndex = mLruProcessServiceStart;
2337            inActivity = true;
2338            inService = true;
2339        } else  {
2340            // Process not otherwise of interest, it goes to the top of the non-service area.
2341            addIndex = mLruProcessServiceStart;
2342            if (client != null) {
2343                int clientIndex = mLruProcesses.lastIndexOf(client);
2344                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2345                        + app);
2346                if (clientIndex >= 0 && addIndex > clientIndex) {
2347                    addIndex = clientIndex;
2348                }
2349            }
2350            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2351        }
2352
2353        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2354                + mLruProcessActivityStart + "): " + app);
2355        */
2356
2357        if (lrui >= 0) {
2358            if (lrui < mLruProcessActivityStart) {
2359                mLruProcessActivityStart--;
2360            }
2361            if (lrui < mLruProcessServiceStart) {
2362                mLruProcessServiceStart--;
2363            }
2364            /*
2365            if (addIndex > lrui) {
2366                addIndex--;
2367            }
2368            if (nextIndex > lrui) {
2369                nextIndex--;
2370            }
2371            */
2372            mLruProcesses.remove(lrui);
2373        }
2374
2375        /*
2376        mLruProcesses.add(addIndex, app);
2377        if (inActivity) {
2378            mLruProcessActivityStart++;
2379        }
2380        if (inService) {
2381            mLruProcessActivityStart++;
2382        }
2383        */
2384
2385        int nextIndex;
2386        if (hasActivity) {
2387            final int N = mLruProcesses.size();
2388            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2389                // Process doesn't have activities, but has clients with
2390                // activities...  move it up, but one below the top (the top
2391                // should always have a real activity).
2392                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2393                mLruProcesses.add(N-1, app);
2394                // To keep it from spamming the LRU list (by making a bunch of clients),
2395                // we will push down any other entries owned by the app.
2396                final int uid = app.info.uid;
2397                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2398                    ProcessRecord subProc = mLruProcesses.get(i);
2399                    if (subProc.info.uid == uid) {
2400                        // We want to push this one down the list.  If the process after
2401                        // it is for the same uid, however, don't do so, because we don't
2402                        // want them internally to be re-ordered.
2403                        if (mLruProcesses.get(i-1).info.uid != uid) {
2404                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2405                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2406                            ProcessRecord tmp = mLruProcesses.get(i);
2407                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2408                            mLruProcesses.set(i-1, tmp);
2409                            i--;
2410                        }
2411                    } else {
2412                        // A gap, we can stop here.
2413                        break;
2414                    }
2415                }
2416            } else {
2417                // Process has activities, put it at the very tipsy-top.
2418                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2419                mLruProcesses.add(app);
2420            }
2421            nextIndex = mLruProcessServiceStart;
2422        } else if (hasService) {
2423            // Process has services, put it at the top of the service list.
2424            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2425            mLruProcesses.add(mLruProcessActivityStart, app);
2426            nextIndex = mLruProcessServiceStart;
2427            mLruProcessActivityStart++;
2428        } else  {
2429            // Process not otherwise of interest, it goes to the top of the non-service area.
2430            int index = mLruProcessServiceStart;
2431            if (client != null) {
2432                // If there is a client, don't allow the process to be moved up higher
2433                // in the list than that client.
2434                int clientIndex = mLruProcesses.lastIndexOf(client);
2435                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2436                        + " when updating " + app);
2437                if (clientIndex <= lrui) {
2438                    // Don't allow the client index restriction to push it down farther in the
2439                    // list than it already is.
2440                    clientIndex = lrui;
2441                }
2442                if (clientIndex >= 0 && index > clientIndex) {
2443                    index = clientIndex;
2444                }
2445            }
2446            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2447            mLruProcesses.add(index, app);
2448            nextIndex = index-1;
2449            mLruProcessActivityStart++;
2450            mLruProcessServiceStart++;
2451        }
2452
2453        // If the app is currently using a content provider or service,
2454        // bump those processes as well.
2455        for (int j=app.connections.size()-1; j>=0; j--) {
2456            ConnectionRecord cr = app.connections.valueAt(j);
2457            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2458                    && cr.binding.service.app != null
2459                    && cr.binding.service.app.lruSeq != mLruSeq
2460                    && !cr.binding.service.app.persistent) {
2461                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2462                        "service connection", cr, app);
2463            }
2464        }
2465        for (int j=app.conProviders.size()-1; j>=0; j--) {
2466            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2467            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2468                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2469                        "provider reference", cpr, app);
2470            }
2471        }
2472    }
2473
2474    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2475        if (uid == Process.SYSTEM_UID) {
2476            // The system gets to run in any process.  If there are multiple
2477            // processes with the same uid, just pick the first (this
2478            // should never happen).
2479            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2480            if (procs == null) return null;
2481            final int N = procs.size();
2482            for (int i = 0; i < N; i++) {
2483                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2484            }
2485        }
2486        ProcessRecord proc = mProcessNames.get(processName, uid);
2487        if (false && proc != null && !keepIfLarge
2488                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2489                && proc.lastCachedPss >= 4000) {
2490            // Turn this condition on to cause killing to happen regularly, for testing.
2491            if (proc.baseProcessTracker != null) {
2492                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2493            }
2494            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2495                    + "k from cached");
2496        } else if (proc != null && !keepIfLarge
2497                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2498                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2499            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2500            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2501                if (proc.baseProcessTracker != null) {
2502                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2503                }
2504                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2505                        + "k from cached");
2506            }
2507        }
2508        return proc;
2509    }
2510
2511    void ensurePackageDexOpt(String packageName) {
2512        IPackageManager pm = AppGlobals.getPackageManager();
2513        try {
2514            if (pm.performDexOpt(packageName)) {
2515                mDidDexOpt = true;
2516            }
2517        } catch (RemoteException e) {
2518        }
2519    }
2520
2521    boolean isNextTransitionForward() {
2522        int transit = mWindowManager.getPendingAppTransition();
2523        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2524                || transit == AppTransition.TRANSIT_TASK_OPEN
2525                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2526    }
2527
2528    final ProcessRecord startProcessLocked(String processName,
2529            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2530            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2531            boolean isolated, boolean keepIfLarge) {
2532        ProcessRecord app;
2533        if (!isolated) {
2534            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2535        } else {
2536            // If this is an isolated process, it can't re-use an existing process.
2537            app = null;
2538        }
2539        // We don't have to do anything more if:
2540        // (1) There is an existing application record; and
2541        // (2) The caller doesn't think it is dead, OR there is no thread
2542        //     object attached to it so we know it couldn't have crashed; and
2543        // (3) There is a pid assigned to it, so it is either starting or
2544        //     already running.
2545        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2546                + " app=" + app + " knownToBeDead=" + knownToBeDead
2547                + " thread=" + (app != null ? app.thread : null)
2548                + " pid=" + (app != null ? app.pid : -1));
2549        if (app != null && app.pid > 0) {
2550            if (!knownToBeDead || app.thread == null) {
2551                // We already have the app running, or are waiting for it to
2552                // come up (we have a pid but not yet its thread), so keep it.
2553                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2554                // If this is a new package in the process, add the package to the list
2555                app.addPackage(info.packageName, mProcessStats);
2556                return app;
2557            }
2558
2559            // An application record is attached to a previous process,
2560            // clean it up now.
2561            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2562            handleAppDiedLocked(app, true, true);
2563        }
2564
2565        String hostingNameStr = hostingName != null
2566                ? hostingName.flattenToShortString() : null;
2567
2568        if (!isolated) {
2569            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2570                // If we are in the background, then check to see if this process
2571                // is bad.  If so, we will just silently fail.
2572                if (mBadProcesses.get(info.processName, info.uid) != null) {
2573                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2574                            + "/" + info.processName);
2575                    return null;
2576                }
2577            } else {
2578                // When the user is explicitly starting a process, then clear its
2579                // crash count so that we won't make it bad until they see at
2580                // least one crash dialog again, and make the process good again
2581                // if it had been bad.
2582                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2583                        + "/" + info.processName);
2584                mProcessCrashTimes.remove(info.processName, info.uid);
2585                if (mBadProcesses.get(info.processName, info.uid) != null) {
2586                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2587                            UserHandle.getUserId(info.uid), info.uid,
2588                            info.processName);
2589                    mBadProcesses.remove(info.processName, info.uid);
2590                    if (app != null) {
2591                        app.bad = false;
2592                    }
2593                }
2594            }
2595        }
2596
2597        if (app == null) {
2598            app = newProcessRecordLocked(info, processName, isolated);
2599            if (app == null) {
2600                Slog.w(TAG, "Failed making new process record for "
2601                        + processName + "/" + info.uid + " isolated=" + isolated);
2602                return null;
2603            }
2604            mProcessNames.put(processName, app.uid, app);
2605            if (isolated) {
2606                mIsolatedProcesses.put(app.uid, app);
2607            }
2608        } else {
2609            // If this is a new package in the process, add the package to the list
2610            app.addPackage(info.packageName, mProcessStats);
2611        }
2612
2613        // If the system is not ready yet, then hold off on starting this
2614        // process until it is.
2615        if (!mProcessesReady
2616                && !isAllowedWhileBooting(info)
2617                && !allowWhileBooting) {
2618            if (!mProcessesOnHold.contains(app)) {
2619                mProcessesOnHold.add(app);
2620            }
2621            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2622            return app;
2623        }
2624
2625        startProcessLocked(app, hostingType, hostingNameStr);
2626        return (app.pid != 0) ? app : null;
2627    }
2628
2629    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2630        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2631    }
2632
2633    private final void startProcessLocked(ProcessRecord app,
2634            String hostingType, String hostingNameStr) {
2635        if (app.pid > 0 && app.pid != MY_PID) {
2636            synchronized (mPidsSelfLocked) {
2637                mPidsSelfLocked.remove(app.pid);
2638                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2639            }
2640            app.setPid(0);
2641        }
2642
2643        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2644                "startProcessLocked removing on hold: " + app);
2645        mProcessesOnHold.remove(app);
2646
2647        updateCpuStats();
2648
2649        try {
2650            int uid = app.uid;
2651
2652            int[] gids = null;
2653            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2654            if (!app.isolated) {
2655                int[] permGids = null;
2656                try {
2657                    final PackageManager pm = mContext.getPackageManager();
2658                    permGids = pm.getPackageGids(app.info.packageName);
2659
2660                    if (Environment.isExternalStorageEmulated()) {
2661                        if (pm.checkPermission(
2662                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2663                                app.info.packageName) == PERMISSION_GRANTED) {
2664                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2665                        } else {
2666                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2667                        }
2668                    }
2669                } catch (PackageManager.NameNotFoundException e) {
2670                    Slog.w(TAG, "Unable to retrieve gids", e);
2671                }
2672
2673                /*
2674                 * Add shared application GID so applications can share some
2675                 * resources like shared libraries
2676                 */
2677                if (permGids == null) {
2678                    gids = new int[1];
2679                } else {
2680                    gids = new int[permGids.length + 1];
2681                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2682                }
2683                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2684            }
2685            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2686                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2687                        && mTopComponent != null
2688                        && app.processName.equals(mTopComponent.getPackageName())) {
2689                    uid = 0;
2690                }
2691                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2692                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2693                    uid = 0;
2694                }
2695            }
2696            int debugFlags = 0;
2697            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2698                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2699                // Also turn on CheckJNI for debuggable apps. It's quite
2700                // awkward to turn on otherwise.
2701                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2702            }
2703            // Run the app in safe mode if its manifest requests so or the
2704            // system is booted in safe mode.
2705            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2706                Zygote.systemInSafeMode == true) {
2707                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2708            }
2709            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2710                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2711            }
2712            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2713                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2714            }
2715            if ("1".equals(SystemProperties.get("debug.assert"))) {
2716                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2717            }
2718
2719            // Start the process.  It will either succeed and return a result containing
2720            // the PID of the new process, or else throw a RuntimeException.
2721            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2722                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2723                    app.info.targetSdkVersion, app.info.seinfo, null);
2724
2725            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2726            synchronized (bs) {
2727                if (bs.isOnBattery()) {
2728                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2729                }
2730            }
2731
2732            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2733                    UserHandle.getUserId(uid), startResult.pid, uid,
2734                    app.processName, hostingType,
2735                    hostingNameStr != null ? hostingNameStr : "");
2736
2737            if (app.persistent) {
2738                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2739            }
2740
2741            StringBuilder buf = mStringBuilder;
2742            buf.setLength(0);
2743            buf.append("Start proc ");
2744            buf.append(app.processName);
2745            buf.append(" for ");
2746            buf.append(hostingType);
2747            if (hostingNameStr != null) {
2748                buf.append(" ");
2749                buf.append(hostingNameStr);
2750            }
2751            buf.append(": pid=");
2752            buf.append(startResult.pid);
2753            buf.append(" uid=");
2754            buf.append(uid);
2755            buf.append(" gids={");
2756            if (gids != null) {
2757                for (int gi=0; gi<gids.length; gi++) {
2758                    if (gi != 0) buf.append(", ");
2759                    buf.append(gids[gi]);
2760
2761                }
2762            }
2763            buf.append("}");
2764            Slog.i(TAG, buf.toString());
2765            app.setPid(startResult.pid);
2766            app.usingWrapper = startResult.usingWrapper;
2767            app.removed = false;
2768            synchronized (mPidsSelfLocked) {
2769                this.mPidsSelfLocked.put(startResult.pid, app);
2770                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2771                msg.obj = app;
2772                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2773                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2774            }
2775        } catch (RuntimeException e) {
2776            // XXX do better error recovery.
2777            app.setPid(0);
2778            Slog.e(TAG, "Failure starting process " + app.processName, e);
2779        }
2780    }
2781
2782    void updateUsageStats(ActivityRecord component, boolean resumed) {
2783        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2784        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2785        if (resumed) {
2786            mUsageStatsService.noteResumeComponent(component.realActivity);
2787            synchronized (stats) {
2788                stats.noteActivityResumedLocked(component.app.uid);
2789            }
2790        } else {
2791            mUsageStatsService.notePauseComponent(component.realActivity);
2792            synchronized (stats) {
2793                stats.noteActivityPausedLocked(component.app.uid);
2794            }
2795        }
2796    }
2797
2798    Intent getHomeIntent() {
2799        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2800        intent.setComponent(mTopComponent);
2801        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2802            intent.addCategory(Intent.CATEGORY_HOME);
2803        }
2804        return intent;
2805    }
2806
2807    boolean startHomeActivityLocked(int userId) {
2808        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2809                && mTopAction == null) {
2810            // We are running in factory test mode, but unable to find
2811            // the factory test app, so just sit around displaying the
2812            // error message and don't try to start anything.
2813            return false;
2814        }
2815        Intent intent = getHomeIntent();
2816        ActivityInfo aInfo =
2817            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2818        if (aInfo != null) {
2819            intent.setComponent(new ComponentName(
2820                    aInfo.applicationInfo.packageName, aInfo.name));
2821            // Don't do this if the home app is currently being
2822            // instrumented.
2823            aInfo = new ActivityInfo(aInfo);
2824            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2825            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2826                    aInfo.applicationInfo.uid, true);
2827            if (app == null || app.instrumentationClass == null) {
2828                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2829                mStackSupervisor.startHomeActivity(intent, aInfo);
2830            }
2831        }
2832
2833        return true;
2834    }
2835
2836    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2837        ActivityInfo ai = null;
2838        ComponentName comp = intent.getComponent();
2839        try {
2840            if (comp != null) {
2841                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2842            } else {
2843                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2844                        intent,
2845                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2846                            flags, userId);
2847
2848                if (info != null) {
2849                    ai = info.activityInfo;
2850                }
2851            }
2852        } catch (RemoteException e) {
2853            // ignore
2854        }
2855
2856        return ai;
2857    }
2858
2859    /**
2860     * Starts the "new version setup screen" if appropriate.
2861     */
2862    void startSetupActivityLocked() {
2863        // Only do this once per boot.
2864        if (mCheckedForSetup) {
2865            return;
2866        }
2867
2868        // We will show this screen if the current one is a different
2869        // version than the last one shown, and we are not running in
2870        // low-level factory test mode.
2871        final ContentResolver resolver = mContext.getContentResolver();
2872        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2873                Settings.Global.getInt(resolver,
2874                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2875            mCheckedForSetup = true;
2876
2877            // See if we should be showing the platform update setup UI.
2878            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2879            List<ResolveInfo> ris = mContext.getPackageManager()
2880                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2881
2882            // We don't allow third party apps to replace this.
2883            ResolveInfo ri = null;
2884            for (int i=0; ris != null && i<ris.size(); i++) {
2885                if ((ris.get(i).activityInfo.applicationInfo.flags
2886                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2887                    ri = ris.get(i);
2888                    break;
2889                }
2890            }
2891
2892            if (ri != null) {
2893                String vers = ri.activityInfo.metaData != null
2894                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2895                        : null;
2896                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2897                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2898                            Intent.METADATA_SETUP_VERSION);
2899                }
2900                String lastVers = Settings.Secure.getString(
2901                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2902                if (vers != null && !vers.equals(lastVers)) {
2903                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2904                    intent.setComponent(new ComponentName(
2905                            ri.activityInfo.packageName, ri.activityInfo.name));
2906                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2907                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2908                }
2909            }
2910        }
2911    }
2912
2913    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2914        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2915    }
2916
2917    void enforceNotIsolatedCaller(String caller) {
2918        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2919            throw new SecurityException("Isolated process not allowed to call " + caller);
2920        }
2921    }
2922
2923    @Override
2924    public int getFrontActivityScreenCompatMode() {
2925        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2926        synchronized (this) {
2927            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2928        }
2929    }
2930
2931    @Override
2932    public void setFrontActivityScreenCompatMode(int mode) {
2933        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2934                "setFrontActivityScreenCompatMode");
2935        synchronized (this) {
2936            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2937        }
2938    }
2939
2940    @Override
2941    public int getPackageScreenCompatMode(String packageName) {
2942        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2943        synchronized (this) {
2944            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2945        }
2946    }
2947
2948    @Override
2949    public void setPackageScreenCompatMode(String packageName, int mode) {
2950        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2951                "setPackageScreenCompatMode");
2952        synchronized (this) {
2953            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2954        }
2955    }
2956
2957    @Override
2958    public boolean getPackageAskScreenCompat(String packageName) {
2959        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2960        synchronized (this) {
2961            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2962        }
2963    }
2964
2965    @Override
2966    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2967        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2968                "setPackageAskScreenCompat");
2969        synchronized (this) {
2970            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2971        }
2972    }
2973
2974    private void dispatchProcessesChanged() {
2975        int N;
2976        synchronized (this) {
2977            N = mPendingProcessChanges.size();
2978            if (mActiveProcessChanges.length < N) {
2979                mActiveProcessChanges = new ProcessChangeItem[N];
2980            }
2981            mPendingProcessChanges.toArray(mActiveProcessChanges);
2982            mAvailProcessChanges.addAll(mPendingProcessChanges);
2983            mPendingProcessChanges.clear();
2984            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2985        }
2986
2987        int i = mProcessObservers.beginBroadcast();
2988        while (i > 0) {
2989            i--;
2990            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2991            if (observer != null) {
2992                try {
2993                    for (int j=0; j<N; j++) {
2994                        ProcessChangeItem item = mActiveProcessChanges[j];
2995                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2996                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2997                                    + item.pid + " uid=" + item.uid + ": "
2998                                    + item.foregroundActivities);
2999                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3000                                    item.foregroundActivities);
3001                        }
3002                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3003                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3004                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3005                            observer.onImportanceChanged(item.pid, item.uid,
3006                                    item.importance);
3007                        }
3008                    }
3009                } catch (RemoteException e) {
3010                }
3011            }
3012        }
3013        mProcessObservers.finishBroadcast();
3014    }
3015
3016    private void dispatchProcessDied(int pid, int uid) {
3017        int i = mProcessObservers.beginBroadcast();
3018        while (i > 0) {
3019            i--;
3020            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3021            if (observer != null) {
3022                try {
3023                    observer.onProcessDied(pid, uid);
3024                } catch (RemoteException e) {
3025                }
3026            }
3027        }
3028        mProcessObservers.finishBroadcast();
3029    }
3030
3031    final void doPendingActivityLaunchesLocked(boolean doResume) {
3032        final int N = mPendingActivityLaunches.size();
3033        if (N <= 0) {
3034            return;
3035        }
3036        for (int i=0; i<N; i++) {
3037            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3038            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3039                    doResume && i == (N-1), null);
3040        }
3041        mPendingActivityLaunches.clear();
3042    }
3043
3044    @Override
3045    public final int startActivity(IApplicationThread caller, String callingPackage,
3046            Intent intent, String resolvedType, IBinder resultTo,
3047            String resultWho, int requestCode, int startFlags,
3048            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3049        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3050                resultWho, requestCode,
3051                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3052    }
3053
3054    @Override
3055    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3056            Intent intent, String resolvedType, IBinder resultTo,
3057            String resultWho, int requestCode, int startFlags,
3058            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3059        enforceNotIsolatedCaller("startActivity");
3060        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3061                false, true, "startActivity", null);
3062        // TODO: Switch to user app stacks here.
3063        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3064                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3065                null, null, options, userId, null);
3066    }
3067
3068    @Override
3069    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3070            Intent intent, String resolvedType, IBinder resultTo,
3071            String resultWho, int requestCode, int startFlags, String profileFile,
3072            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3073        enforceNotIsolatedCaller("startActivityAndWait");
3074        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3075                false, true, "startActivityAndWait", null);
3076        WaitResult res = new WaitResult();
3077        // TODO: Switch to user app stacks here.
3078        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3079                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3080                res, null, options, UserHandle.getCallingUserId(), null);
3081        return res;
3082    }
3083
3084    @Override
3085    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3086            Intent intent, String resolvedType, IBinder resultTo,
3087            String resultWho, int requestCode, int startFlags, Configuration config,
3088            Bundle options, int userId) {
3089        enforceNotIsolatedCaller("startActivityWithConfig");
3090        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3091                false, true, "startActivityWithConfig", null);
3092        // TODO: Switch to user app stacks here.
3093        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3094                resolvedType, resultTo, resultWho, requestCode, startFlags,
3095                null, null, null, config, options, userId, null);
3096        return ret;
3097    }
3098
3099    @Override
3100    public int startActivityIntentSender(IApplicationThread caller,
3101            IntentSender intent, Intent fillInIntent, String resolvedType,
3102            IBinder resultTo, String resultWho, int requestCode,
3103            int flagsMask, int flagsValues, Bundle options) {
3104        enforceNotIsolatedCaller("startActivityIntentSender");
3105        // Refuse possible leaked file descriptors
3106        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3107            throw new IllegalArgumentException("File descriptors passed in Intent");
3108        }
3109
3110        IIntentSender sender = intent.getTarget();
3111        if (!(sender instanceof PendingIntentRecord)) {
3112            throw new IllegalArgumentException("Bad PendingIntent object");
3113        }
3114
3115        PendingIntentRecord pir = (PendingIntentRecord)sender;
3116
3117        synchronized (this) {
3118            // If this is coming from the currently resumed activity, it is
3119            // effectively saying that app switches are allowed at this point.
3120            final ActivityStack stack = getFocusedStack();
3121            if (stack.mResumedActivity != null &&
3122                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3123                mAppSwitchesAllowedTime = 0;
3124            }
3125        }
3126        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3127                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3128        return ret;
3129    }
3130
3131    @Override
3132    public boolean startNextMatchingActivity(IBinder callingActivity,
3133            Intent intent, Bundle options) {
3134        // Refuse possible leaked file descriptors
3135        if (intent != null && intent.hasFileDescriptors() == true) {
3136            throw new IllegalArgumentException("File descriptors passed in Intent");
3137        }
3138
3139        synchronized (this) {
3140            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3141            if (r == null) {
3142                ActivityOptions.abort(options);
3143                return false;
3144            }
3145            if (r.app == null || r.app.thread == null) {
3146                // The caller is not running...  d'oh!
3147                ActivityOptions.abort(options);
3148                return false;
3149            }
3150            intent = new Intent(intent);
3151            // The caller is not allowed to change the data.
3152            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3153            // And we are resetting to find the next component...
3154            intent.setComponent(null);
3155
3156            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3157
3158            ActivityInfo aInfo = null;
3159            try {
3160                List<ResolveInfo> resolves =
3161                    AppGlobals.getPackageManager().queryIntentActivities(
3162                            intent, r.resolvedType,
3163                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3164                            UserHandle.getCallingUserId());
3165
3166                // Look for the original activity in the list...
3167                final int N = resolves != null ? resolves.size() : 0;
3168                for (int i=0; i<N; i++) {
3169                    ResolveInfo rInfo = resolves.get(i);
3170                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3171                            && rInfo.activityInfo.name.equals(r.info.name)) {
3172                        // We found the current one...  the next matching is
3173                        // after it.
3174                        i++;
3175                        if (i<N) {
3176                            aInfo = resolves.get(i).activityInfo;
3177                        }
3178                        if (debug) {
3179                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3180                                    + "/" + r.info.name);
3181                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3182                                    + "/" + aInfo.name);
3183                        }
3184                        break;
3185                    }
3186                }
3187            } catch (RemoteException e) {
3188            }
3189
3190            if (aInfo == null) {
3191                // Nobody who is next!
3192                ActivityOptions.abort(options);
3193                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3194                return false;
3195            }
3196
3197            intent.setComponent(new ComponentName(
3198                    aInfo.applicationInfo.packageName, aInfo.name));
3199            intent.setFlags(intent.getFlags()&~(
3200                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3201                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3202                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3203                    Intent.FLAG_ACTIVITY_NEW_TASK));
3204
3205            // Okay now we need to start the new activity, replacing the
3206            // currently running activity.  This is a little tricky because
3207            // we want to start the new one as if the current one is finished,
3208            // but not finish the current one first so that there is no flicker.
3209            // And thus...
3210            final boolean wasFinishing = r.finishing;
3211            r.finishing = true;
3212
3213            // Propagate reply information over to the new activity.
3214            final ActivityRecord resultTo = r.resultTo;
3215            final String resultWho = r.resultWho;
3216            final int requestCode = r.requestCode;
3217            r.resultTo = null;
3218            if (resultTo != null) {
3219                resultTo.removeResultsLocked(r, resultWho, requestCode);
3220            }
3221
3222            final long origId = Binder.clearCallingIdentity();
3223            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3224                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3225                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3226                    options, false, null, null);
3227            Binder.restoreCallingIdentity(origId);
3228
3229            r.finishing = wasFinishing;
3230            if (res != ActivityManager.START_SUCCESS) {
3231                return false;
3232            }
3233            return true;
3234        }
3235    }
3236
3237    final int startActivityInPackage(int uid, String callingPackage,
3238            Intent intent, String resolvedType, IBinder resultTo,
3239            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3240                    IActivityContainer container) {
3241
3242        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3243                false, true, "startActivityInPackage", null);
3244
3245        // TODO: Switch to user app stacks here.
3246        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3247                resultTo, resultWho, requestCode, startFlags,
3248                null, null, null, null, options, userId, container);
3249        return ret;
3250    }
3251
3252    @Override
3253    public final int startActivities(IApplicationThread caller, String callingPackage,
3254            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3255            int userId) {
3256        enforceNotIsolatedCaller("startActivities");
3257        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3258                false, true, "startActivity", null);
3259        // TODO: Switch to user app stacks here.
3260        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3261                resolvedTypes, resultTo, options, userId);
3262        return ret;
3263    }
3264
3265    final int startActivitiesInPackage(int uid, String callingPackage,
3266            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3267            Bundle options, int userId) {
3268
3269        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3270                false, true, "startActivityInPackage", null);
3271        // TODO: Switch to user app stacks here.
3272        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3273                resultTo, options, userId);
3274        return ret;
3275    }
3276
3277    final void addRecentTaskLocked(TaskRecord task) {
3278        int N = mRecentTasks.size();
3279        // Quick case: check if the top-most recent task is the same.
3280        if (N > 0 && mRecentTasks.get(0) == task) {
3281            return;
3282        }
3283        // Remove any existing entries that are the same kind of task.
3284        for (int i=0; i<N; i++) {
3285            TaskRecord tr = mRecentTasks.get(i);
3286            if (task.userId == tr.userId
3287                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3288                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3289                tr.disposeThumbnail();
3290                mRecentTasks.remove(i);
3291                i--;
3292                N--;
3293                if (task.intent == null) {
3294                    // If the new recent task we are adding is not fully
3295                    // specified, then replace it with the existing recent task.
3296                    task = tr;
3297                }
3298            }
3299        }
3300        if (N >= MAX_RECENT_TASKS) {
3301            mRecentTasks.remove(N-1).disposeThumbnail();
3302        }
3303        mRecentTasks.add(0, task);
3304    }
3305
3306    @Override
3307    public void reportActivityFullyDrawn(IBinder token) {
3308        synchronized (this) {
3309            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3310            if (r == null) {
3311                return;
3312            }
3313            r.reportFullyDrawnLocked();
3314        }
3315    }
3316
3317    @Override
3318    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3319        synchronized (this) {
3320            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3321            if (r == null) {
3322                return;
3323            }
3324            final long origId = Binder.clearCallingIdentity();
3325            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3326            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3327                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3328            if (config != null) {
3329                r.frozenBeforeDestroy = true;
3330                if (!updateConfigurationLocked(config, r, false, false)) {
3331                    mStackSupervisor.resumeTopActivitiesLocked();
3332                }
3333            }
3334            Binder.restoreCallingIdentity(origId);
3335        }
3336    }
3337
3338    @Override
3339    public int getRequestedOrientation(IBinder token) {
3340        synchronized (this) {
3341            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3342            if (r == null) {
3343                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3344            }
3345            return mWindowManager.getAppOrientation(r.appToken);
3346        }
3347    }
3348
3349    /**
3350     * This is the internal entry point for handling Activity.finish().
3351     *
3352     * @param token The Binder token referencing the Activity we want to finish.
3353     * @param resultCode Result code, if any, from this Activity.
3354     * @param resultData Result data (Intent), if any, from this Activity.
3355     *
3356     * @return Returns true if the activity successfully finished, or false if it is still running.
3357     */
3358    @Override
3359    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3360        // Refuse possible leaked file descriptors
3361        if (resultData != null && resultData.hasFileDescriptors() == true) {
3362            throw new IllegalArgumentException("File descriptors passed in Intent");
3363        }
3364
3365        synchronized(this) {
3366            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3367            if (r == null) {
3368                return true;
3369            }
3370            if (mController != null) {
3371                // Find the first activity that is not finishing.
3372                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3373                if (next != null) {
3374                    // ask watcher if this is allowed
3375                    boolean resumeOK = true;
3376                    try {
3377                        resumeOK = mController.activityResuming(next.packageName);
3378                    } catch (RemoteException e) {
3379                        mController = null;
3380                        Watchdog.getInstance().setActivityController(null);
3381                    }
3382
3383                    if (!resumeOK) {
3384                        return false;
3385                    }
3386                }
3387            }
3388            final long origId = Binder.clearCallingIdentity();
3389            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3390                    resultData, "app-request", true);
3391            Binder.restoreCallingIdentity(origId);
3392            return res;
3393        }
3394    }
3395
3396    @Override
3397    public final void finishHeavyWeightApp() {
3398        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3399                != PackageManager.PERMISSION_GRANTED) {
3400            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3401                    + Binder.getCallingPid()
3402                    + ", uid=" + Binder.getCallingUid()
3403                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3404            Slog.w(TAG, msg);
3405            throw new SecurityException(msg);
3406        }
3407
3408        synchronized(this) {
3409            if (mHeavyWeightProcess == null) {
3410                return;
3411            }
3412
3413            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3414                    mHeavyWeightProcess.activities);
3415            for (int i=0; i<activities.size(); i++) {
3416                ActivityRecord r = activities.get(i);
3417                if (!r.finishing) {
3418                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3419                            null, "finish-heavy", true);
3420                }
3421            }
3422
3423            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3424                    mHeavyWeightProcess.userId, 0));
3425            mHeavyWeightProcess = null;
3426        }
3427    }
3428
3429    @Override
3430    public void crashApplication(int uid, int initialPid, String packageName,
3431            String message) {
3432        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3433                != PackageManager.PERMISSION_GRANTED) {
3434            String msg = "Permission Denial: crashApplication() from pid="
3435                    + Binder.getCallingPid()
3436                    + ", uid=" + Binder.getCallingUid()
3437                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3438            Slog.w(TAG, msg);
3439            throw new SecurityException(msg);
3440        }
3441
3442        synchronized(this) {
3443            ProcessRecord proc = null;
3444
3445            // Figure out which process to kill.  We don't trust that initialPid
3446            // still has any relation to current pids, so must scan through the
3447            // list.
3448            synchronized (mPidsSelfLocked) {
3449                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3450                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3451                    if (p.uid != uid) {
3452                        continue;
3453                    }
3454                    if (p.pid == initialPid) {
3455                        proc = p;
3456                        break;
3457                    }
3458                    if (p.pkgList.containsKey(packageName)) {
3459                        proc = p;
3460                    }
3461                }
3462            }
3463
3464            if (proc == null) {
3465                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3466                        + " initialPid=" + initialPid
3467                        + " packageName=" + packageName);
3468                return;
3469            }
3470
3471            if (proc.thread != null) {
3472                if (proc.pid == Process.myPid()) {
3473                    Log.w(TAG, "crashApplication: trying to crash self!");
3474                    return;
3475                }
3476                long ident = Binder.clearCallingIdentity();
3477                try {
3478                    proc.thread.scheduleCrash(message);
3479                } catch (RemoteException e) {
3480                }
3481                Binder.restoreCallingIdentity(ident);
3482            }
3483        }
3484    }
3485
3486    @Override
3487    public final void finishSubActivity(IBinder token, String resultWho,
3488            int requestCode) {
3489        synchronized(this) {
3490            final long origId = Binder.clearCallingIdentity();
3491            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3492            if (r != null) {
3493                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3494            }
3495            Binder.restoreCallingIdentity(origId);
3496        }
3497    }
3498
3499    @Override
3500    public boolean finishActivityAffinity(IBinder token) {
3501        synchronized(this) {
3502            final long origId = Binder.clearCallingIdentity();
3503            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3504            boolean res = false;
3505            if (r != null) {
3506                res = r.task.stack.finishActivityAffinityLocked(r);
3507            }
3508            Binder.restoreCallingIdentity(origId);
3509            return res;
3510        }
3511    }
3512
3513    @Override
3514    public boolean willActivityBeVisible(IBinder token) {
3515        synchronized(this) {
3516            ActivityStack stack = ActivityRecord.getStackLocked(token);
3517            if (stack != null) {
3518                return stack.willActivityBeVisibleLocked(token);
3519            }
3520            return false;
3521        }
3522    }
3523
3524    @Override
3525    public void overridePendingTransition(IBinder token, String packageName,
3526            int enterAnim, int exitAnim) {
3527        synchronized(this) {
3528            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3529            if (self == null) {
3530                return;
3531            }
3532
3533            final long origId = Binder.clearCallingIdentity();
3534
3535            if (self.state == ActivityState.RESUMED
3536                    || self.state == ActivityState.PAUSING) {
3537                mWindowManager.overridePendingAppTransition(packageName,
3538                        enterAnim, exitAnim, null);
3539            }
3540
3541            Binder.restoreCallingIdentity(origId);
3542        }
3543    }
3544
3545    /**
3546     * Main function for removing an existing process from the activity manager
3547     * as a result of that process going away.  Clears out all connections
3548     * to the process.
3549     */
3550    private final void handleAppDiedLocked(ProcessRecord app,
3551            boolean restarting, boolean allowRestart) {
3552        int pid = app.pid;
3553        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3554        if (!restarting) {
3555            removeLruProcessLocked(app);
3556            if (pid > 0) {
3557                ProcessList.remove(pid);
3558            }
3559        }
3560
3561        if (mProfileProc == app) {
3562            clearProfilerLocked();
3563        }
3564
3565        // Remove this application's activities from active lists.
3566        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3567
3568        app.activities.clear();
3569
3570        if (app.instrumentationClass != null) {
3571            Slog.w(TAG, "Crash of app " + app.processName
3572                  + " running instrumentation " + app.instrumentationClass);
3573            Bundle info = new Bundle();
3574            info.putString("shortMsg", "Process crashed.");
3575            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3576        }
3577
3578        if (!restarting) {
3579            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3580                // If there was nothing to resume, and we are not already
3581                // restarting this process, but there is a visible activity that
3582                // is hosted by the process...  then make sure all visible
3583                // activities are running, taking care of restarting this
3584                // process.
3585                if (hasVisibleActivities) {
3586                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3587                }
3588            }
3589        }
3590    }
3591
3592    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3593        IBinder threadBinder = thread.asBinder();
3594        // Find the application record.
3595        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3596            ProcessRecord rec = mLruProcesses.get(i);
3597            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3598                return i;
3599            }
3600        }
3601        return -1;
3602    }
3603
3604    final ProcessRecord getRecordForAppLocked(
3605            IApplicationThread thread) {
3606        if (thread == null) {
3607            return null;
3608        }
3609
3610        int appIndex = getLRURecordIndexForAppLocked(thread);
3611        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3612    }
3613
3614    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3615        // If there are no longer any background processes running,
3616        // and the app that died was not running instrumentation,
3617        // then tell everyone we are now low on memory.
3618        boolean haveBg = false;
3619        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3620            ProcessRecord rec = mLruProcesses.get(i);
3621            if (rec.thread != null
3622                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3623                haveBg = true;
3624                break;
3625            }
3626        }
3627
3628        if (!haveBg) {
3629            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3630            if (doReport) {
3631                long now = SystemClock.uptimeMillis();
3632                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3633                    doReport = false;
3634                } else {
3635                    mLastMemUsageReportTime = now;
3636                }
3637            }
3638            final ArrayList<ProcessMemInfo> memInfos
3639                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3640            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3641            long now = SystemClock.uptimeMillis();
3642            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3643                ProcessRecord rec = mLruProcesses.get(i);
3644                if (rec == dyingProc || rec.thread == null) {
3645                    continue;
3646                }
3647                if (doReport) {
3648                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3649                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3650                }
3651                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3652                    // The low memory report is overriding any current
3653                    // state for a GC request.  Make sure to do
3654                    // heavy/important/visible/foreground processes first.
3655                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3656                        rec.lastRequestedGc = 0;
3657                    } else {
3658                        rec.lastRequestedGc = rec.lastLowMemory;
3659                    }
3660                    rec.reportLowMemory = true;
3661                    rec.lastLowMemory = now;
3662                    mProcessesToGc.remove(rec);
3663                    addProcessToGcListLocked(rec);
3664                }
3665            }
3666            if (doReport) {
3667                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3668                mHandler.sendMessage(msg);
3669            }
3670            scheduleAppGcsLocked();
3671        }
3672    }
3673
3674    final void appDiedLocked(ProcessRecord app, int pid,
3675            IApplicationThread thread) {
3676
3677        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3678        synchronized (stats) {
3679            stats.noteProcessDiedLocked(app.info.uid, pid);
3680        }
3681
3682        // Clean up already done if the process has been re-started.
3683        if (app.pid == pid && app.thread != null &&
3684                app.thread.asBinder() == thread.asBinder()) {
3685            boolean doLowMem = app.instrumentationClass == null;
3686            boolean doOomAdj = doLowMem;
3687            if (!app.killedByAm) {
3688                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3689                        + ") has died.");
3690                mAllowLowerMemLevel = true;
3691            } else {
3692                // Note that we always want to do oom adj to update our state with the
3693                // new number of procs.
3694                mAllowLowerMemLevel = false;
3695                doLowMem = false;
3696            }
3697            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3698            if (DEBUG_CLEANUP) Slog.v(
3699                TAG, "Dying app: " + app + ", pid: " + pid
3700                + ", thread: " + thread.asBinder());
3701            handleAppDiedLocked(app, false, true);
3702
3703            if (doOomAdj) {
3704                updateOomAdjLocked();
3705            }
3706            if (doLowMem) {
3707                doLowMemReportIfNeededLocked(app);
3708            }
3709        } else if (app.pid != pid) {
3710            // A new process has already been started.
3711            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3712                    + ") has died and restarted (pid " + app.pid + ").");
3713            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3714        } else if (DEBUG_PROCESSES) {
3715            Slog.d(TAG, "Received spurious death notification for thread "
3716                    + thread.asBinder());
3717        }
3718    }
3719
3720    /**
3721     * If a stack trace dump file is configured, dump process stack traces.
3722     * @param clearTraces causes the dump file to be erased prior to the new
3723     *    traces being written, if true; when false, the new traces will be
3724     *    appended to any existing file content.
3725     * @param firstPids of dalvik VM processes to dump stack traces for first
3726     * @param lastPids of dalvik VM processes to dump stack traces for last
3727     * @param nativeProcs optional list of native process names to dump stack crawls
3728     * @return file containing stack traces, or null if no dump file is configured
3729     */
3730    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3731            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3732        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3733        if (tracesPath == null || tracesPath.length() == 0) {
3734            return null;
3735        }
3736
3737        File tracesFile = new File(tracesPath);
3738        try {
3739            File tracesDir = tracesFile.getParentFile();
3740            if (!tracesDir.exists()) {
3741                tracesFile.mkdirs();
3742                if (!SELinux.restorecon(tracesDir)) {
3743                    return null;
3744                }
3745            }
3746            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3747
3748            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3749            tracesFile.createNewFile();
3750            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3751        } catch (IOException e) {
3752            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3753            return null;
3754        }
3755
3756        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3757        return tracesFile;
3758    }
3759
3760    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3761            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3762        // Use a FileObserver to detect when traces finish writing.
3763        // The order of traces is considered important to maintain for legibility.
3764        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3765            @Override
3766            public synchronized void onEvent(int event, String path) { notify(); }
3767        };
3768
3769        try {
3770            observer.startWatching();
3771
3772            // First collect all of the stacks of the most important pids.
3773            if (firstPids != null) {
3774                try {
3775                    int num = firstPids.size();
3776                    for (int i = 0; i < num; i++) {
3777                        synchronized (observer) {
3778                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3779                            observer.wait(200);  // Wait for write-close, give up after 200msec
3780                        }
3781                    }
3782                } catch (InterruptedException e) {
3783                    Log.wtf(TAG, e);
3784                }
3785            }
3786
3787            // Next collect the stacks of the native pids
3788            if (nativeProcs != null) {
3789                int[] pids = Process.getPidsForCommands(nativeProcs);
3790                if (pids != null) {
3791                    for (int pid : pids) {
3792                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3793                    }
3794                }
3795            }
3796
3797            // Lastly, measure CPU usage.
3798            if (processCpuTracker != null) {
3799                processCpuTracker.init();
3800                System.gc();
3801                processCpuTracker.update();
3802                try {
3803                    synchronized (processCpuTracker) {
3804                        processCpuTracker.wait(500); // measure over 1/2 second.
3805                    }
3806                } catch (InterruptedException e) {
3807                }
3808                processCpuTracker.update();
3809
3810                // We'll take the stack crawls of just the top apps using CPU.
3811                final int N = processCpuTracker.countWorkingStats();
3812                int numProcs = 0;
3813                for (int i=0; i<N && numProcs<5; i++) {
3814                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3815                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3816                        numProcs++;
3817                        try {
3818                            synchronized (observer) {
3819                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3820                                observer.wait(200);  // Wait for write-close, give up after 200msec
3821                            }
3822                        } catch (InterruptedException e) {
3823                            Log.wtf(TAG, e);
3824                        }
3825
3826                    }
3827                }
3828            }
3829        } finally {
3830            observer.stopWatching();
3831        }
3832    }
3833
3834    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3835        if (true || IS_USER_BUILD) {
3836            return;
3837        }
3838        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3839        if (tracesPath == null || tracesPath.length() == 0) {
3840            return;
3841        }
3842
3843        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3844        StrictMode.allowThreadDiskWrites();
3845        try {
3846            final File tracesFile = new File(tracesPath);
3847            final File tracesDir = tracesFile.getParentFile();
3848            final File tracesTmp = new File(tracesDir, "__tmp__");
3849            try {
3850                if (!tracesDir.exists()) {
3851                    tracesFile.mkdirs();
3852                    if (!SELinux.restorecon(tracesDir.getPath())) {
3853                        return;
3854                    }
3855                }
3856                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3857
3858                if (tracesFile.exists()) {
3859                    tracesTmp.delete();
3860                    tracesFile.renameTo(tracesTmp);
3861                }
3862                StringBuilder sb = new StringBuilder();
3863                Time tobj = new Time();
3864                tobj.set(System.currentTimeMillis());
3865                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3866                sb.append(": ");
3867                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3868                sb.append(" since ");
3869                sb.append(msg);
3870                FileOutputStream fos = new FileOutputStream(tracesFile);
3871                fos.write(sb.toString().getBytes());
3872                if (app == null) {
3873                    fos.write("\n*** No application process!".getBytes());
3874                }
3875                fos.close();
3876                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3877            } catch (IOException e) {
3878                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3879                return;
3880            }
3881
3882            if (app != null) {
3883                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3884                firstPids.add(app.pid);
3885                dumpStackTraces(tracesPath, firstPids, null, null, null);
3886            }
3887
3888            File lastTracesFile = null;
3889            File curTracesFile = null;
3890            for (int i=9; i>=0; i--) {
3891                String name = String.format(Locale.US, "slow%02d.txt", i);
3892                curTracesFile = new File(tracesDir, name);
3893                if (curTracesFile.exists()) {
3894                    if (lastTracesFile != null) {
3895                        curTracesFile.renameTo(lastTracesFile);
3896                    } else {
3897                        curTracesFile.delete();
3898                    }
3899                }
3900                lastTracesFile = curTracesFile;
3901            }
3902            tracesFile.renameTo(curTracesFile);
3903            if (tracesTmp.exists()) {
3904                tracesTmp.renameTo(tracesFile);
3905            }
3906        } finally {
3907            StrictMode.setThreadPolicy(oldPolicy);
3908        }
3909    }
3910
3911    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3912            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3913        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3914        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3915
3916        if (mController != null) {
3917            try {
3918                // 0 == continue, -1 = kill process immediately
3919                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3920                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3921            } catch (RemoteException e) {
3922                mController = null;
3923                Watchdog.getInstance().setActivityController(null);
3924            }
3925        }
3926
3927        long anrTime = SystemClock.uptimeMillis();
3928        if (MONITOR_CPU_USAGE) {
3929            updateCpuStatsNow();
3930        }
3931
3932        synchronized (this) {
3933            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3934            if (mShuttingDown) {
3935                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3936                return;
3937            } else if (app.notResponding) {
3938                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3939                return;
3940            } else if (app.crashing) {
3941                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3942                return;
3943            }
3944
3945            // In case we come through here for the same app before completing
3946            // this one, mark as anring now so we will bail out.
3947            app.notResponding = true;
3948
3949            // Log the ANR to the event log.
3950            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3951                    app.processName, app.info.flags, annotation);
3952
3953            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3954            firstPids.add(app.pid);
3955
3956            int parentPid = app.pid;
3957            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3958            if (parentPid != app.pid) firstPids.add(parentPid);
3959
3960            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3961
3962            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3963                ProcessRecord r = mLruProcesses.get(i);
3964                if (r != null && r.thread != null) {
3965                    int pid = r.pid;
3966                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3967                        if (r.persistent) {
3968                            firstPids.add(pid);
3969                        } else {
3970                            lastPids.put(pid, Boolean.TRUE);
3971                        }
3972                    }
3973                }
3974            }
3975        }
3976
3977        // Log the ANR to the main log.
3978        StringBuilder info = new StringBuilder();
3979        info.setLength(0);
3980        info.append("ANR in ").append(app.processName);
3981        if (activity != null && activity.shortComponentName != null) {
3982            info.append(" (").append(activity.shortComponentName).append(")");
3983        }
3984        info.append("\n");
3985        info.append("PID: ").append(app.pid).append("\n");
3986        if (annotation != null) {
3987            info.append("Reason: ").append(annotation).append("\n");
3988        }
3989        if (parent != null && parent != activity) {
3990            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3991        }
3992
3993        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
3994
3995        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
3996                NATIVE_STACKS_OF_INTEREST);
3997
3998        String cpuInfo = null;
3999        if (MONITOR_CPU_USAGE) {
4000            updateCpuStatsNow();
4001            synchronized (mProcessCpuThread) {
4002                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4003            }
4004            info.append(processCpuTracker.printCurrentLoad());
4005            info.append(cpuInfo);
4006        }
4007
4008        info.append(processCpuTracker.printCurrentState(anrTime));
4009
4010        Slog.e(TAG, info.toString());
4011        if (tracesFile == null) {
4012            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4013            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4014        }
4015
4016        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4017                cpuInfo, tracesFile, null);
4018
4019        if (mController != null) {
4020            try {
4021                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4022                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4023                if (res != 0) {
4024                    if (res < 0 && app.pid != MY_PID) {
4025                        Process.killProcess(app.pid);
4026                    } else {
4027                        synchronized (this) {
4028                            mServices.scheduleServiceTimeoutLocked(app);
4029                        }
4030                    }
4031                    return;
4032                }
4033            } catch (RemoteException e) {
4034                mController = null;
4035                Watchdog.getInstance().setActivityController(null);
4036            }
4037        }
4038
4039        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4040        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4041                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4042
4043        synchronized (this) {
4044            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4045                killUnneededProcessLocked(app, "background ANR");
4046                return;
4047            }
4048
4049            // Set the app's notResponding state, and look up the errorReportReceiver
4050            makeAppNotRespondingLocked(app,
4051                    activity != null ? activity.shortComponentName : null,
4052                    annotation != null ? "ANR " + annotation : "ANR",
4053                    info.toString());
4054
4055            // Bring up the infamous App Not Responding dialog
4056            Message msg = Message.obtain();
4057            HashMap<String, Object> map = new HashMap<String, Object>();
4058            msg.what = SHOW_NOT_RESPONDING_MSG;
4059            msg.obj = map;
4060            msg.arg1 = aboveSystem ? 1 : 0;
4061            map.put("app", app);
4062            if (activity != null) {
4063                map.put("activity", activity);
4064            }
4065
4066            mHandler.sendMessage(msg);
4067        }
4068    }
4069
4070    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4071        if (!mLaunchWarningShown) {
4072            mLaunchWarningShown = true;
4073            mHandler.post(new Runnable() {
4074                @Override
4075                public void run() {
4076                    synchronized (ActivityManagerService.this) {
4077                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4078                        d.show();
4079                        mHandler.postDelayed(new Runnable() {
4080                            @Override
4081                            public void run() {
4082                                synchronized (ActivityManagerService.this) {
4083                                    d.dismiss();
4084                                    mLaunchWarningShown = false;
4085                                }
4086                            }
4087                        }, 4000);
4088                    }
4089                }
4090            });
4091        }
4092    }
4093
4094    @Override
4095    public boolean clearApplicationUserData(final String packageName,
4096            final IPackageDataObserver observer, int userId) {
4097        enforceNotIsolatedCaller("clearApplicationUserData");
4098        int uid = Binder.getCallingUid();
4099        int pid = Binder.getCallingPid();
4100        userId = handleIncomingUser(pid, uid,
4101                userId, false, true, "clearApplicationUserData", null);
4102        long callingId = Binder.clearCallingIdentity();
4103        try {
4104            IPackageManager pm = AppGlobals.getPackageManager();
4105            int pkgUid = -1;
4106            synchronized(this) {
4107                try {
4108                    pkgUid = pm.getPackageUid(packageName, userId);
4109                } catch (RemoteException e) {
4110                }
4111                if (pkgUid == -1) {
4112                    Slog.w(TAG, "Invalid packageName: " + packageName);
4113                    if (observer != null) {
4114                        try {
4115                            observer.onRemoveCompleted(packageName, false);
4116                        } catch (RemoteException e) {
4117                            Slog.i(TAG, "Observer no longer exists.");
4118                        }
4119                    }
4120                    return false;
4121                }
4122                if (uid == pkgUid || checkComponentPermission(
4123                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4124                        pid, uid, -1, true)
4125                        == PackageManager.PERMISSION_GRANTED) {
4126                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4127                } else {
4128                    throw new SecurityException("PID " + pid + " does not have permission "
4129                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4130                                    + " of package " + packageName);
4131                }
4132            }
4133
4134            try {
4135                // Clear application user data
4136                pm.clearApplicationUserData(packageName, observer, userId);
4137
4138                // Remove all permissions granted from/to this package
4139                removeUriPermissionsForPackageLocked(packageName, userId, true);
4140
4141                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4142                        Uri.fromParts("package", packageName, null));
4143                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4144                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4145                        null, null, 0, null, null, null, false, false, userId);
4146            } catch (RemoteException e) {
4147            }
4148        } finally {
4149            Binder.restoreCallingIdentity(callingId);
4150        }
4151        return true;
4152    }
4153
4154    @Override
4155    public void killBackgroundProcesses(final String packageName, int userId) {
4156        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4157                != PackageManager.PERMISSION_GRANTED &&
4158                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4159                        != PackageManager.PERMISSION_GRANTED) {
4160            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4161                    + Binder.getCallingPid()
4162                    + ", uid=" + Binder.getCallingUid()
4163                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4164            Slog.w(TAG, msg);
4165            throw new SecurityException(msg);
4166        }
4167
4168        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4169                userId, true, true, "killBackgroundProcesses", null);
4170        long callingId = Binder.clearCallingIdentity();
4171        try {
4172            IPackageManager pm = AppGlobals.getPackageManager();
4173            synchronized(this) {
4174                int appId = -1;
4175                try {
4176                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4177                } catch (RemoteException e) {
4178                }
4179                if (appId == -1) {
4180                    Slog.w(TAG, "Invalid packageName: " + packageName);
4181                    return;
4182                }
4183                killPackageProcessesLocked(packageName, appId, userId,
4184                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4185            }
4186        } finally {
4187            Binder.restoreCallingIdentity(callingId);
4188        }
4189    }
4190
4191    @Override
4192    public void killAllBackgroundProcesses() {
4193        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4194                != PackageManager.PERMISSION_GRANTED) {
4195            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4196                    + Binder.getCallingPid()
4197                    + ", uid=" + Binder.getCallingUid()
4198                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4199            Slog.w(TAG, msg);
4200            throw new SecurityException(msg);
4201        }
4202
4203        long callingId = Binder.clearCallingIdentity();
4204        try {
4205            synchronized(this) {
4206                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4207                final int NP = mProcessNames.getMap().size();
4208                for (int ip=0; ip<NP; ip++) {
4209                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4210                    final int NA = apps.size();
4211                    for (int ia=0; ia<NA; ia++) {
4212                        ProcessRecord app = apps.valueAt(ia);
4213                        if (app.persistent) {
4214                            // we don't kill persistent processes
4215                            continue;
4216                        }
4217                        if (app.removed) {
4218                            procs.add(app);
4219                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4220                            app.removed = true;
4221                            procs.add(app);
4222                        }
4223                    }
4224                }
4225
4226                int N = procs.size();
4227                for (int i=0; i<N; i++) {
4228                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4229                }
4230                mAllowLowerMemLevel = true;
4231                updateOomAdjLocked();
4232                doLowMemReportIfNeededLocked(null);
4233            }
4234        } finally {
4235            Binder.restoreCallingIdentity(callingId);
4236        }
4237    }
4238
4239    @Override
4240    public void forceStopPackage(final String packageName, int userId) {
4241        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4242                != PackageManager.PERMISSION_GRANTED) {
4243            String msg = "Permission Denial: forceStopPackage() from pid="
4244                    + Binder.getCallingPid()
4245                    + ", uid=" + Binder.getCallingUid()
4246                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4247            Slog.w(TAG, msg);
4248            throw new SecurityException(msg);
4249        }
4250        final int callingPid = Binder.getCallingPid();
4251        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4252                userId, true, true, "forceStopPackage", null);
4253        long callingId = Binder.clearCallingIdentity();
4254        try {
4255            IPackageManager pm = AppGlobals.getPackageManager();
4256            synchronized(this) {
4257                int[] users = userId == UserHandle.USER_ALL
4258                        ? getUsersLocked() : new int[] { userId };
4259                for (int user : users) {
4260                    int pkgUid = -1;
4261                    try {
4262                        pkgUid = pm.getPackageUid(packageName, user);
4263                    } catch (RemoteException e) {
4264                    }
4265                    if (pkgUid == -1) {
4266                        Slog.w(TAG, "Invalid packageName: " + packageName);
4267                        continue;
4268                    }
4269                    try {
4270                        pm.setPackageStoppedState(packageName, true, user);
4271                    } catch (RemoteException e) {
4272                    } catch (IllegalArgumentException e) {
4273                        Slog.w(TAG, "Failed trying to unstop package "
4274                                + packageName + ": " + e);
4275                    }
4276                    if (isUserRunningLocked(user, false)) {
4277                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4278                    }
4279                }
4280            }
4281        } finally {
4282            Binder.restoreCallingIdentity(callingId);
4283        }
4284    }
4285
4286    /*
4287     * The pkg name and app id have to be specified.
4288     */
4289    @Override
4290    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4291        if (pkg == null) {
4292            return;
4293        }
4294        // Make sure the uid is valid.
4295        if (appid < 0) {
4296            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4297            return;
4298        }
4299        int callerUid = Binder.getCallingUid();
4300        // Only the system server can kill an application
4301        if (callerUid == Process.SYSTEM_UID) {
4302            // Post an aysnc message to kill the application
4303            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4304            msg.arg1 = appid;
4305            msg.arg2 = 0;
4306            Bundle bundle = new Bundle();
4307            bundle.putString("pkg", pkg);
4308            bundle.putString("reason", reason);
4309            msg.obj = bundle;
4310            mHandler.sendMessage(msg);
4311        } else {
4312            throw new SecurityException(callerUid + " cannot kill pkg: " +
4313                    pkg);
4314        }
4315    }
4316
4317    @Override
4318    public void closeSystemDialogs(String reason) {
4319        enforceNotIsolatedCaller("closeSystemDialogs");
4320
4321        final int pid = Binder.getCallingPid();
4322        final int uid = Binder.getCallingUid();
4323        final long origId = Binder.clearCallingIdentity();
4324        try {
4325            synchronized (this) {
4326                // Only allow this from foreground processes, so that background
4327                // applications can't abuse it to prevent system UI from being shown.
4328                if (uid >= Process.FIRST_APPLICATION_UID) {
4329                    ProcessRecord proc;
4330                    synchronized (mPidsSelfLocked) {
4331                        proc = mPidsSelfLocked.get(pid);
4332                    }
4333                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4334                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4335                                + " from background process " + proc);
4336                        return;
4337                    }
4338                }
4339                closeSystemDialogsLocked(reason);
4340            }
4341        } finally {
4342            Binder.restoreCallingIdentity(origId);
4343        }
4344    }
4345
4346    void closeSystemDialogsLocked(String reason) {
4347        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4348        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4349                | Intent.FLAG_RECEIVER_FOREGROUND);
4350        if (reason != null) {
4351            intent.putExtra("reason", reason);
4352        }
4353        mWindowManager.closeSystemDialogs(reason);
4354
4355        mStackSupervisor.closeSystemDialogsLocked();
4356
4357        broadcastIntentLocked(null, null, intent, null,
4358                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4359                Process.SYSTEM_UID, UserHandle.USER_ALL);
4360    }
4361
4362    @Override
4363    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4364        enforceNotIsolatedCaller("getProcessMemoryInfo");
4365        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4366        for (int i=pids.length-1; i>=0; i--) {
4367            ProcessRecord proc;
4368            int oomAdj;
4369            synchronized (this) {
4370                synchronized (mPidsSelfLocked) {
4371                    proc = mPidsSelfLocked.get(pids[i]);
4372                    oomAdj = proc != null ? proc.setAdj : 0;
4373                }
4374            }
4375            infos[i] = new Debug.MemoryInfo();
4376            Debug.getMemoryInfo(pids[i], infos[i]);
4377            if (proc != null) {
4378                synchronized (this) {
4379                    if (proc.thread != null && proc.setAdj == oomAdj) {
4380                        // Record this for posterity if the process has been stable.
4381                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4382                                infos[i].getTotalUss(), false, proc.pkgList);
4383                    }
4384                }
4385            }
4386        }
4387        return infos;
4388    }
4389
4390    @Override
4391    public long[] getProcessPss(int[] pids) {
4392        enforceNotIsolatedCaller("getProcessPss");
4393        long[] pss = new long[pids.length];
4394        for (int i=pids.length-1; i>=0; i--) {
4395            ProcessRecord proc;
4396            int oomAdj;
4397            synchronized (this) {
4398                synchronized (mPidsSelfLocked) {
4399                    proc = mPidsSelfLocked.get(pids[i]);
4400                    oomAdj = proc != null ? proc.setAdj : 0;
4401                }
4402            }
4403            long[] tmpUss = new long[1];
4404            pss[i] = Debug.getPss(pids[i], tmpUss);
4405            if (proc != null) {
4406                synchronized (this) {
4407                    if (proc.thread != null && proc.setAdj == oomAdj) {
4408                        // Record this for posterity if the process has been stable.
4409                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4410                    }
4411                }
4412            }
4413        }
4414        return pss;
4415    }
4416
4417    @Override
4418    public void killApplicationProcess(String processName, int uid) {
4419        if (processName == null) {
4420            return;
4421        }
4422
4423        int callerUid = Binder.getCallingUid();
4424        // Only the system server can kill an application
4425        if (callerUid == Process.SYSTEM_UID) {
4426            synchronized (this) {
4427                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4428                if (app != null && app.thread != null) {
4429                    try {
4430                        app.thread.scheduleSuicide();
4431                    } catch (RemoteException e) {
4432                        // If the other end already died, then our work here is done.
4433                    }
4434                } else {
4435                    Slog.w(TAG, "Process/uid not found attempting kill of "
4436                            + processName + " / " + uid);
4437                }
4438            }
4439        } else {
4440            throw new SecurityException(callerUid + " cannot kill app process: " +
4441                    processName);
4442        }
4443    }
4444
4445    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4446        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4447                false, true, false, UserHandle.getUserId(uid), reason);
4448        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4449                Uri.fromParts("package", packageName, null));
4450        if (!mProcessesReady) {
4451            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4452                    | Intent.FLAG_RECEIVER_FOREGROUND);
4453        }
4454        intent.putExtra(Intent.EXTRA_UID, uid);
4455        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4456        broadcastIntentLocked(null, null, intent,
4457                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4458                false, false,
4459                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4460    }
4461
4462    private void forceStopUserLocked(int userId, String reason) {
4463        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
4464        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4465        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4466                | Intent.FLAG_RECEIVER_FOREGROUND);
4467        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4468        broadcastIntentLocked(null, null, intent,
4469                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4470                false, false,
4471                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4472    }
4473
4474    private final boolean killPackageProcessesLocked(String packageName, int appId,
4475            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4476            boolean doit, boolean evenPersistent, String reason) {
4477        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4478
4479        // Remove all processes this package may have touched: all with the
4480        // same UID (except for the system or root user), and all whose name
4481        // matches the package name.
4482        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4483        final int NP = mProcessNames.getMap().size();
4484        for (int ip=0; ip<NP; ip++) {
4485            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4486            final int NA = apps.size();
4487            for (int ia=0; ia<NA; ia++) {
4488                ProcessRecord app = apps.valueAt(ia);
4489                if (app.persistent && !evenPersistent) {
4490                    // we don't kill persistent processes
4491                    continue;
4492                }
4493                if (app.removed) {
4494                    if (doit) {
4495                        procs.add(app);
4496                    }
4497                    continue;
4498                }
4499
4500                // Skip process if it doesn't meet our oom adj requirement.
4501                if (app.setAdj < minOomAdj) {
4502                    continue;
4503                }
4504
4505                // If no package is specified, we call all processes under the
4506                // give user id.
4507                if (packageName == null) {
4508                    if (app.userId != userId) {
4509                        continue;
4510                    }
4511                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4512                        continue;
4513                    }
4514                // Package has been specified, we want to hit all processes
4515                // that match it.  We need to qualify this by the processes
4516                // that are running under the specified app and user ID.
4517                } else {
4518                    if (UserHandle.getAppId(app.uid) != appId) {
4519                        continue;
4520                    }
4521                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4522                        continue;
4523                    }
4524                    if (!app.pkgList.containsKey(packageName)) {
4525                        continue;
4526                    }
4527                }
4528
4529                // Process has passed all conditions, kill it!
4530                if (!doit) {
4531                    return true;
4532                }
4533                app.removed = true;
4534                procs.add(app);
4535            }
4536        }
4537
4538        int N = procs.size();
4539        for (int i=0; i<N; i++) {
4540            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4541        }
4542        updateOomAdjLocked();
4543        return N > 0;
4544    }
4545
4546    private final boolean forceStopPackageLocked(String name, int appId,
4547            boolean callerWillRestart, boolean purgeCache, boolean doit,
4548            boolean evenPersistent, int userId, String reason) {
4549        int i;
4550        int N;
4551
4552        if (userId == UserHandle.USER_ALL && name == null) {
4553            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4554        }
4555
4556        if (appId < 0 && name != null) {
4557            try {
4558                appId = UserHandle.getAppId(
4559                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4560            } catch (RemoteException e) {
4561            }
4562        }
4563
4564        if (doit) {
4565            if (name != null) {
4566                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4567                        + " user=" + userId + ": " + reason);
4568            } else {
4569                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4570            }
4571
4572            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4573            for (int ip=pmap.size()-1; ip>=0; ip--) {
4574                SparseArray<Long> ba = pmap.valueAt(ip);
4575                for (i=ba.size()-1; i>=0; i--) {
4576                    boolean remove = false;
4577                    final int entUid = ba.keyAt(i);
4578                    if (name != null) {
4579                        if (userId == UserHandle.USER_ALL) {
4580                            if (UserHandle.getAppId(entUid) == appId) {
4581                                remove = true;
4582                            }
4583                        } else {
4584                            if (entUid == UserHandle.getUid(userId, appId)) {
4585                                remove = true;
4586                            }
4587                        }
4588                    } else if (UserHandle.getUserId(entUid) == userId) {
4589                        remove = true;
4590                    }
4591                    if (remove) {
4592                        ba.removeAt(i);
4593                    }
4594                }
4595                if (ba.size() == 0) {
4596                    pmap.removeAt(ip);
4597                }
4598            }
4599        }
4600
4601        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4602                -100, callerWillRestart, true, doit, evenPersistent,
4603                name == null ? ("stop user " + userId) : ("stop " + name));
4604
4605        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4606            if (!doit) {
4607                return true;
4608            }
4609            didSomething = true;
4610        }
4611
4612        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4613            if (!doit) {
4614                return true;
4615            }
4616            didSomething = true;
4617        }
4618
4619        if (name == null) {
4620            // Remove all sticky broadcasts from this user.
4621            mStickyBroadcasts.remove(userId);
4622        }
4623
4624        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4625        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4626                userId, providers)) {
4627            if (!doit) {
4628                return true;
4629            }
4630            didSomething = true;
4631        }
4632        N = providers.size();
4633        for (i=0; i<N; i++) {
4634            removeDyingProviderLocked(null, providers.get(i), true);
4635        }
4636
4637        // Remove transient permissions granted from/to this package/user
4638        removeUriPermissionsForPackageLocked(name, userId, false);
4639
4640        if (name == null) {
4641            // Remove pending intents.  For now we only do this when force
4642            // stopping users, because we have some problems when doing this
4643            // for packages -- app widgets are not currently cleaned up for
4644            // such packages, so they can be left with bad pending intents.
4645            if (mIntentSenderRecords.size() > 0) {
4646                Iterator<WeakReference<PendingIntentRecord>> it
4647                        = mIntentSenderRecords.values().iterator();
4648                while (it.hasNext()) {
4649                    WeakReference<PendingIntentRecord> wpir = it.next();
4650                    if (wpir == null) {
4651                        it.remove();
4652                        continue;
4653                    }
4654                    PendingIntentRecord pir = wpir.get();
4655                    if (pir == null) {
4656                        it.remove();
4657                        continue;
4658                    }
4659                    if (name == null) {
4660                        // Stopping user, remove all objects for the user.
4661                        if (pir.key.userId != userId) {
4662                            // Not the same user, skip it.
4663                            continue;
4664                        }
4665                    } else {
4666                        if (UserHandle.getAppId(pir.uid) != appId) {
4667                            // Different app id, skip it.
4668                            continue;
4669                        }
4670                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4671                            // Different user, skip it.
4672                            continue;
4673                        }
4674                        if (!pir.key.packageName.equals(name)) {
4675                            // Different package, skip it.
4676                            continue;
4677                        }
4678                    }
4679                    if (!doit) {
4680                        return true;
4681                    }
4682                    didSomething = true;
4683                    it.remove();
4684                    pir.canceled = true;
4685                    if (pir.key.activity != null) {
4686                        pir.key.activity.pendingResults.remove(pir.ref);
4687                    }
4688                }
4689            }
4690        }
4691
4692        if (doit) {
4693            if (purgeCache && name != null) {
4694                AttributeCache ac = AttributeCache.instance();
4695                if (ac != null) {
4696                    ac.removePackage(name);
4697                }
4698            }
4699            if (mBooted) {
4700                mStackSupervisor.resumeTopActivitiesLocked();
4701                mStackSupervisor.scheduleIdleLocked();
4702            }
4703        }
4704
4705        return didSomething;
4706    }
4707
4708    private final boolean removeProcessLocked(ProcessRecord app,
4709            boolean callerWillRestart, boolean allowRestart, String reason) {
4710        final String name = app.processName;
4711        final int uid = app.uid;
4712        if (DEBUG_PROCESSES) Slog.d(
4713            TAG, "Force removing proc " + app.toShortString() + " (" + name
4714            + "/" + uid + ")");
4715
4716        mProcessNames.remove(name, uid);
4717        mIsolatedProcesses.remove(app.uid);
4718        if (mHeavyWeightProcess == app) {
4719            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4720                    mHeavyWeightProcess.userId, 0));
4721            mHeavyWeightProcess = null;
4722        }
4723        boolean needRestart = false;
4724        if (app.pid > 0 && app.pid != MY_PID) {
4725            int pid = app.pid;
4726            synchronized (mPidsSelfLocked) {
4727                mPidsSelfLocked.remove(pid);
4728                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4729            }
4730            killUnneededProcessLocked(app, reason);
4731            handleAppDiedLocked(app, true, allowRestart);
4732            removeLruProcessLocked(app);
4733
4734            if (app.persistent && !app.isolated) {
4735                if (!callerWillRestart) {
4736                    addAppLocked(app.info, false);
4737                } else {
4738                    needRestart = true;
4739                }
4740            }
4741        } else {
4742            mRemovedProcesses.add(app);
4743        }
4744
4745        return needRestart;
4746    }
4747
4748    private final void processStartTimedOutLocked(ProcessRecord app) {
4749        final int pid = app.pid;
4750        boolean gone = false;
4751        synchronized (mPidsSelfLocked) {
4752            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4753            if (knownApp != null && knownApp.thread == null) {
4754                mPidsSelfLocked.remove(pid);
4755                gone = true;
4756            }
4757        }
4758
4759        if (gone) {
4760            Slog.w(TAG, "Process " + app + " failed to attach");
4761            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4762                    pid, app.uid, app.processName);
4763            mProcessNames.remove(app.processName, app.uid);
4764            mIsolatedProcesses.remove(app.uid);
4765            if (mHeavyWeightProcess == app) {
4766                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4767                        mHeavyWeightProcess.userId, 0));
4768                mHeavyWeightProcess = null;
4769            }
4770            // Take care of any launching providers waiting for this process.
4771            checkAppInLaunchingProvidersLocked(app, true);
4772            // Take care of any services that are waiting for the process.
4773            mServices.processStartTimedOutLocked(app);
4774            killUnneededProcessLocked(app, "start timeout");
4775            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4776                Slog.w(TAG, "Unattached app died before backup, skipping");
4777                try {
4778                    IBackupManager bm = IBackupManager.Stub.asInterface(
4779                            ServiceManager.getService(Context.BACKUP_SERVICE));
4780                    bm.agentDisconnected(app.info.packageName);
4781                } catch (RemoteException e) {
4782                    // Can't happen; the backup manager is local
4783                }
4784            }
4785            if (isPendingBroadcastProcessLocked(pid)) {
4786                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4787                skipPendingBroadcastLocked(pid);
4788            }
4789        } else {
4790            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4791        }
4792    }
4793
4794    private final boolean attachApplicationLocked(IApplicationThread thread,
4795            int pid) {
4796
4797        // Find the application record that is being attached...  either via
4798        // the pid if we are running in multiple processes, or just pull the
4799        // next app record if we are emulating process with anonymous threads.
4800        ProcessRecord app;
4801        if (pid != MY_PID && pid >= 0) {
4802            synchronized (mPidsSelfLocked) {
4803                app = mPidsSelfLocked.get(pid);
4804            }
4805        } else {
4806            app = null;
4807        }
4808
4809        if (app == null) {
4810            Slog.w(TAG, "No pending application record for pid " + pid
4811                    + " (IApplicationThread " + thread + "); dropping process");
4812            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4813            if (pid > 0 && pid != MY_PID) {
4814                Process.killProcessQuiet(pid);
4815            } else {
4816                try {
4817                    thread.scheduleExit();
4818                } catch (Exception e) {
4819                    // Ignore exceptions.
4820                }
4821            }
4822            return false;
4823        }
4824
4825        // If this application record is still attached to a previous
4826        // process, clean it up now.
4827        if (app.thread != null) {
4828            handleAppDiedLocked(app, true, true);
4829        }
4830
4831        // Tell the process all about itself.
4832
4833        if (localLOGV) Slog.v(
4834                TAG, "Binding process pid " + pid + " to record " + app);
4835
4836        final String processName = app.processName;
4837        try {
4838            AppDeathRecipient adr = new AppDeathRecipient(
4839                    app, pid, thread);
4840            thread.asBinder().linkToDeath(adr, 0);
4841            app.deathRecipient = adr;
4842        } catch (RemoteException e) {
4843            app.resetPackageList(mProcessStats);
4844            startProcessLocked(app, "link fail", processName);
4845            return false;
4846        }
4847
4848        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4849
4850        app.makeActive(thread, mProcessStats);
4851        app.curAdj = app.setAdj = -100;
4852        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4853        app.forcingToForeground = null;
4854        app.foregroundServices = false;
4855        app.hasShownUi = false;
4856        app.debugging = false;
4857        app.cached = false;
4858
4859        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4860
4861        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4862        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4863
4864        if (!normalMode) {
4865            Slog.i(TAG, "Launching preboot mode app: " + app);
4866        }
4867
4868        if (localLOGV) Slog.v(
4869            TAG, "New app record " + app
4870            + " thread=" + thread.asBinder() + " pid=" + pid);
4871        try {
4872            int testMode = IApplicationThread.DEBUG_OFF;
4873            if (mDebugApp != null && mDebugApp.equals(processName)) {
4874                testMode = mWaitForDebugger
4875                    ? IApplicationThread.DEBUG_WAIT
4876                    : IApplicationThread.DEBUG_ON;
4877                app.debugging = true;
4878                if (mDebugTransient) {
4879                    mDebugApp = mOrigDebugApp;
4880                    mWaitForDebugger = mOrigWaitForDebugger;
4881                }
4882            }
4883            String profileFile = app.instrumentationProfileFile;
4884            ParcelFileDescriptor profileFd = null;
4885            boolean profileAutoStop = false;
4886            if (mProfileApp != null && mProfileApp.equals(processName)) {
4887                mProfileProc = app;
4888                profileFile = mProfileFile;
4889                profileFd = mProfileFd;
4890                profileAutoStop = mAutoStopProfiler;
4891            }
4892            boolean enableOpenGlTrace = false;
4893            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4894                enableOpenGlTrace = true;
4895                mOpenGlTraceApp = null;
4896            }
4897
4898            // If the app is being launched for restore or full backup, set it up specially
4899            boolean isRestrictedBackupMode = false;
4900            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4901                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4902                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4903                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4904            }
4905
4906            ensurePackageDexOpt(app.instrumentationInfo != null
4907                    ? app.instrumentationInfo.packageName
4908                    : app.info.packageName);
4909            if (app.instrumentationClass != null) {
4910                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4911            }
4912            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4913                    + processName + " with config " + mConfiguration);
4914            ApplicationInfo appInfo = app.instrumentationInfo != null
4915                    ? app.instrumentationInfo : app.info;
4916            app.compat = compatibilityInfoForPackageLocked(appInfo);
4917            if (profileFd != null) {
4918                profileFd = profileFd.dup();
4919            }
4920            thread.bindApplication(processName, appInfo, providers,
4921                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4922                    app.instrumentationArguments, app.instrumentationWatcher,
4923                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4924                    isRestrictedBackupMode || !normalMode, app.persistent,
4925                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4926                    mCoreSettingsObserver.getCoreSettingsLocked());
4927            updateLruProcessLocked(app, false, null);
4928            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4929        } catch (Exception e) {
4930            // todo: Yikes!  What should we do?  For now we will try to
4931            // start another process, but that could easily get us in
4932            // an infinite loop of restarting processes...
4933            Slog.w(TAG, "Exception thrown during bind!", e);
4934
4935            app.resetPackageList(mProcessStats);
4936            app.unlinkDeathRecipient();
4937            startProcessLocked(app, "bind fail", processName);
4938            return false;
4939        }
4940
4941        // Remove this record from the list of starting applications.
4942        mPersistentStartingProcesses.remove(app);
4943        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4944                "Attach application locked removing on hold: " + app);
4945        mProcessesOnHold.remove(app);
4946
4947        boolean badApp = false;
4948        boolean didSomething = false;
4949
4950        // See if the top visible activity is waiting to run in this process...
4951        if (normalMode) {
4952            try {
4953                if (mStackSupervisor.attachApplicationLocked(app)) {
4954                    didSomething = true;
4955                }
4956            } catch (Exception e) {
4957                badApp = true;
4958            }
4959        }
4960
4961        // Find any services that should be running in this process...
4962        if (!badApp) {
4963            try {
4964                didSomething |= mServices.attachApplicationLocked(app, processName);
4965            } catch (Exception e) {
4966                badApp = true;
4967            }
4968        }
4969
4970        // Check if a next-broadcast receiver is in this process...
4971        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4972            try {
4973                didSomething |= sendPendingBroadcastsLocked(app);
4974            } catch (Exception e) {
4975                // If the app died trying to launch the receiver we declare it 'bad'
4976                badApp = true;
4977            }
4978        }
4979
4980        // Check whether the next backup agent is in this process...
4981        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4982            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4983            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4984            try {
4985                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4986                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4987                        mBackupTarget.backupMode);
4988            } catch (Exception e) {
4989                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4990                e.printStackTrace();
4991            }
4992        }
4993
4994        if (badApp) {
4995            // todo: Also need to kill application to deal with all
4996            // kinds of exceptions.
4997            handleAppDiedLocked(app, false, true);
4998            return false;
4999        }
5000
5001        if (!didSomething) {
5002            updateOomAdjLocked();
5003        }
5004
5005        return true;
5006    }
5007
5008    @Override
5009    public final void attachApplication(IApplicationThread thread) {
5010        synchronized (this) {
5011            int callingPid = Binder.getCallingPid();
5012            final long origId = Binder.clearCallingIdentity();
5013            attachApplicationLocked(thread, callingPid);
5014            Binder.restoreCallingIdentity(origId);
5015        }
5016    }
5017
5018    @Override
5019    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5020        final long origId = Binder.clearCallingIdentity();
5021        synchronized (this) {
5022            ActivityStack stack = ActivityRecord.getStackLocked(token);
5023            if (stack != null) {
5024                ActivityRecord r =
5025                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5026                if (stopProfiling) {
5027                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5028                        try {
5029                            mProfileFd.close();
5030                        } catch (IOException e) {
5031                        }
5032                        clearProfilerLocked();
5033                    }
5034                }
5035            }
5036        }
5037        Binder.restoreCallingIdentity(origId);
5038    }
5039
5040    void enableScreenAfterBoot() {
5041        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5042                SystemClock.uptimeMillis());
5043        mWindowManager.enableScreenAfterBoot();
5044
5045        synchronized (this) {
5046            updateEventDispatchingLocked();
5047        }
5048    }
5049
5050    @Override
5051    public void showBootMessage(final CharSequence msg, final boolean always) {
5052        enforceNotIsolatedCaller("showBootMessage");
5053        mWindowManager.showBootMessage(msg, always);
5054    }
5055
5056    @Override
5057    public void dismissKeyguardOnNextActivity() {
5058        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5059        final long token = Binder.clearCallingIdentity();
5060        try {
5061            synchronized (this) {
5062                if (DEBUG_LOCKSCREEN) logLockScreen("");
5063                if (mLockScreenShown) {
5064                    mLockScreenShown = false;
5065                    comeOutOfSleepIfNeededLocked();
5066                }
5067                mStackSupervisor.setDismissKeyguard(true);
5068            }
5069        } finally {
5070            Binder.restoreCallingIdentity(token);
5071        }
5072    }
5073
5074    final void finishBooting() {
5075        IntentFilter pkgFilter = new IntentFilter();
5076        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5077        pkgFilter.addDataScheme("package");
5078        mContext.registerReceiver(new BroadcastReceiver() {
5079            @Override
5080            public void onReceive(Context context, Intent intent) {
5081                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5082                if (pkgs != null) {
5083                    for (String pkg : pkgs) {
5084                        synchronized (ActivityManagerService.this) {
5085                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
5086                                    "finished booting")) {
5087                                setResultCode(Activity.RESULT_OK);
5088                                return;
5089                            }
5090                        }
5091                    }
5092                }
5093            }
5094        }, pkgFilter);
5095
5096        synchronized (this) {
5097            // Ensure that any processes we had put on hold are now started
5098            // up.
5099            final int NP = mProcessesOnHold.size();
5100            if (NP > 0) {
5101                ArrayList<ProcessRecord> procs =
5102                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5103                for (int ip=0; ip<NP; ip++) {
5104                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5105                            + procs.get(ip));
5106                    startProcessLocked(procs.get(ip), "on-hold", null);
5107                }
5108            }
5109
5110            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5111                // Start looking for apps that are abusing wake locks.
5112                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5113                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5114                // Tell anyone interested that we are done booting!
5115                SystemProperties.set("sys.boot_completed", "1");
5116                SystemProperties.set("dev.bootcomplete", "1");
5117                for (int i=0; i<mStartedUsers.size(); i++) {
5118                    UserStartedState uss = mStartedUsers.valueAt(i);
5119                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5120                        uss.mState = UserStartedState.STATE_RUNNING;
5121                        final int userId = mStartedUsers.keyAt(i);
5122                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5123                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5124                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5125                        broadcastIntentLocked(null, null, intent, null,
5126                                new IIntentReceiver.Stub() {
5127                                    @Override
5128                                    public void performReceive(Intent intent, int resultCode,
5129                                            String data, Bundle extras, boolean ordered,
5130                                            boolean sticky, int sendingUser) {
5131                                        synchronized (ActivityManagerService.this) {
5132                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5133                                                    true, false);
5134                                        }
5135                                    }
5136                                },
5137                                0, null, null,
5138                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5139                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5140                                userId);
5141                    }
5142                }
5143            }
5144        }
5145    }
5146
5147    final void ensureBootCompleted() {
5148        boolean booting;
5149        boolean enableScreen;
5150        synchronized (this) {
5151            booting = mBooting;
5152            mBooting = false;
5153            enableScreen = !mBooted;
5154            mBooted = true;
5155        }
5156
5157        if (booting) {
5158            finishBooting();
5159        }
5160
5161        if (enableScreen) {
5162            enableScreenAfterBoot();
5163        }
5164    }
5165
5166    @Override
5167    public final void activityResumed(IBinder token) {
5168        final long origId = Binder.clearCallingIdentity();
5169        synchronized(this) {
5170            ActivityStack stack = ActivityRecord.getStackLocked(token);
5171            if (stack != null) {
5172                ActivityRecord.activityResumedLocked(token);
5173            }
5174        }
5175        Binder.restoreCallingIdentity(origId);
5176    }
5177
5178    @Override
5179    public final void activityPaused(IBinder token) {
5180        final long origId = Binder.clearCallingIdentity();
5181        synchronized(this) {
5182            ActivityStack stack = ActivityRecord.getStackLocked(token);
5183            if (stack != null) {
5184                stack.activityPausedLocked(token, false);
5185            }
5186        }
5187        Binder.restoreCallingIdentity(origId);
5188    }
5189
5190    @Override
5191    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5192            CharSequence description) {
5193        if (localLOGV) Slog.v(
5194            TAG, "Activity stopped: token=" + token);
5195
5196        // Refuse possible leaked file descriptors
5197        if (icicle != null && icicle.hasFileDescriptors()) {
5198            throw new IllegalArgumentException("File descriptors passed in Bundle");
5199        }
5200
5201        ActivityRecord r = null;
5202
5203        final long origId = Binder.clearCallingIdentity();
5204
5205        synchronized (this) {
5206            r = ActivityRecord.isInStackLocked(token);
5207            if (r != null) {
5208                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5209            }
5210        }
5211
5212        if (r != null) {
5213            sendPendingThumbnail(r, null, null, null, false);
5214        }
5215
5216        trimApplications();
5217
5218        Binder.restoreCallingIdentity(origId);
5219    }
5220
5221    @Override
5222    public final void activityDestroyed(IBinder token) {
5223        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5224        synchronized (this) {
5225            ActivityStack stack = ActivityRecord.getStackLocked(token);
5226            if (stack != null) {
5227                stack.activityDestroyedLocked(token);
5228            }
5229        }
5230    }
5231
5232    @Override
5233    public String getCallingPackage(IBinder token) {
5234        synchronized (this) {
5235            ActivityRecord r = getCallingRecordLocked(token);
5236            return r != null ? r.info.packageName : null;
5237        }
5238    }
5239
5240    @Override
5241    public ComponentName getCallingActivity(IBinder token) {
5242        synchronized (this) {
5243            ActivityRecord r = getCallingRecordLocked(token);
5244            return r != null ? r.intent.getComponent() : null;
5245        }
5246    }
5247
5248    private ActivityRecord getCallingRecordLocked(IBinder token) {
5249        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5250        if (r == null) {
5251            return null;
5252        }
5253        return r.resultTo;
5254    }
5255
5256    @Override
5257    public ComponentName getActivityClassForToken(IBinder token) {
5258        synchronized(this) {
5259            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5260            if (r == null) {
5261                return null;
5262            }
5263            return r.intent.getComponent();
5264        }
5265    }
5266
5267    @Override
5268    public String getPackageForToken(IBinder token) {
5269        synchronized(this) {
5270            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5271            if (r == null) {
5272                return null;
5273            }
5274            return r.packageName;
5275        }
5276    }
5277
5278    @Override
5279    public IIntentSender getIntentSender(int type,
5280            String packageName, IBinder token, String resultWho,
5281            int requestCode, Intent[] intents, String[] resolvedTypes,
5282            int flags, Bundle options, int userId) {
5283        enforceNotIsolatedCaller("getIntentSender");
5284        // Refuse possible leaked file descriptors
5285        if (intents != null) {
5286            if (intents.length < 1) {
5287                throw new IllegalArgumentException("Intents array length must be >= 1");
5288            }
5289            for (int i=0; i<intents.length; i++) {
5290                Intent intent = intents[i];
5291                if (intent != null) {
5292                    if (intent.hasFileDescriptors()) {
5293                        throw new IllegalArgumentException("File descriptors passed in Intent");
5294                    }
5295                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5296                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5297                        throw new IllegalArgumentException(
5298                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5299                    }
5300                    intents[i] = new Intent(intent);
5301                }
5302            }
5303            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5304                throw new IllegalArgumentException(
5305                        "Intent array length does not match resolvedTypes length");
5306            }
5307        }
5308        if (options != null) {
5309            if (options.hasFileDescriptors()) {
5310                throw new IllegalArgumentException("File descriptors passed in options");
5311            }
5312        }
5313
5314        synchronized(this) {
5315            int callingUid = Binder.getCallingUid();
5316            int origUserId = userId;
5317            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5318                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5319                    "getIntentSender", null);
5320            if (origUserId == UserHandle.USER_CURRENT) {
5321                // We don't want to evaluate this until the pending intent is
5322                // actually executed.  However, we do want to always do the
5323                // security checking for it above.
5324                userId = UserHandle.USER_CURRENT;
5325            }
5326            try {
5327                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5328                    int uid = AppGlobals.getPackageManager()
5329                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5330                    if (!UserHandle.isSameApp(callingUid, uid)) {
5331                        String msg = "Permission Denial: getIntentSender() from pid="
5332                            + Binder.getCallingPid()
5333                            + ", uid=" + Binder.getCallingUid()
5334                            + ", (need uid=" + uid + ")"
5335                            + " is not allowed to send as package " + packageName;
5336                        Slog.w(TAG, msg);
5337                        throw new SecurityException(msg);
5338                    }
5339                }
5340
5341                return getIntentSenderLocked(type, packageName, callingUid, userId,
5342                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5343
5344            } catch (RemoteException e) {
5345                throw new SecurityException(e);
5346            }
5347        }
5348    }
5349
5350    IIntentSender getIntentSenderLocked(int type, String packageName,
5351            int callingUid, int userId, IBinder token, String resultWho,
5352            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5353            Bundle options) {
5354        if (DEBUG_MU)
5355            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5356        ActivityRecord activity = null;
5357        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5358            activity = ActivityRecord.isInStackLocked(token);
5359            if (activity == null) {
5360                return null;
5361            }
5362            if (activity.finishing) {
5363                return null;
5364            }
5365        }
5366
5367        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5368        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5369        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5370        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5371                |PendingIntent.FLAG_UPDATE_CURRENT);
5372
5373        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5374                type, packageName, activity, resultWho,
5375                requestCode, intents, resolvedTypes, flags, options, userId);
5376        WeakReference<PendingIntentRecord> ref;
5377        ref = mIntentSenderRecords.get(key);
5378        PendingIntentRecord rec = ref != null ? ref.get() : null;
5379        if (rec != null) {
5380            if (!cancelCurrent) {
5381                if (updateCurrent) {
5382                    if (rec.key.requestIntent != null) {
5383                        rec.key.requestIntent.replaceExtras(intents != null ?
5384                                intents[intents.length - 1] : null);
5385                    }
5386                    if (intents != null) {
5387                        intents[intents.length-1] = rec.key.requestIntent;
5388                        rec.key.allIntents = intents;
5389                        rec.key.allResolvedTypes = resolvedTypes;
5390                    } else {
5391                        rec.key.allIntents = null;
5392                        rec.key.allResolvedTypes = null;
5393                    }
5394                }
5395                return rec;
5396            }
5397            rec.canceled = true;
5398            mIntentSenderRecords.remove(key);
5399        }
5400        if (noCreate) {
5401            return rec;
5402        }
5403        rec = new PendingIntentRecord(this, key, callingUid);
5404        mIntentSenderRecords.put(key, rec.ref);
5405        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5406            if (activity.pendingResults == null) {
5407                activity.pendingResults
5408                        = new HashSet<WeakReference<PendingIntentRecord>>();
5409            }
5410            activity.pendingResults.add(rec.ref);
5411        }
5412        return rec;
5413    }
5414
5415    @Override
5416    public void cancelIntentSender(IIntentSender sender) {
5417        if (!(sender instanceof PendingIntentRecord)) {
5418            return;
5419        }
5420        synchronized(this) {
5421            PendingIntentRecord rec = (PendingIntentRecord)sender;
5422            try {
5423                int uid = AppGlobals.getPackageManager()
5424                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5425                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5426                    String msg = "Permission Denial: cancelIntentSender() from pid="
5427                        + Binder.getCallingPid()
5428                        + ", uid=" + Binder.getCallingUid()
5429                        + " is not allowed to cancel packges "
5430                        + rec.key.packageName;
5431                    Slog.w(TAG, msg);
5432                    throw new SecurityException(msg);
5433                }
5434            } catch (RemoteException e) {
5435                throw new SecurityException(e);
5436            }
5437            cancelIntentSenderLocked(rec, true);
5438        }
5439    }
5440
5441    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5442        rec.canceled = true;
5443        mIntentSenderRecords.remove(rec.key);
5444        if (cleanActivity && rec.key.activity != null) {
5445            rec.key.activity.pendingResults.remove(rec.ref);
5446        }
5447    }
5448
5449    @Override
5450    public String getPackageForIntentSender(IIntentSender pendingResult) {
5451        if (!(pendingResult instanceof PendingIntentRecord)) {
5452            return null;
5453        }
5454        try {
5455            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5456            return res.key.packageName;
5457        } catch (ClassCastException e) {
5458        }
5459        return null;
5460    }
5461
5462    @Override
5463    public int getUidForIntentSender(IIntentSender sender) {
5464        if (sender instanceof PendingIntentRecord) {
5465            try {
5466                PendingIntentRecord res = (PendingIntentRecord)sender;
5467                return res.uid;
5468            } catch (ClassCastException e) {
5469            }
5470        }
5471        return -1;
5472    }
5473
5474    @Override
5475    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5476        if (!(pendingResult instanceof PendingIntentRecord)) {
5477            return false;
5478        }
5479        try {
5480            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5481            if (res.key.allIntents == null) {
5482                return false;
5483            }
5484            for (int i=0; i<res.key.allIntents.length; i++) {
5485                Intent intent = res.key.allIntents[i];
5486                if (intent.getPackage() != null && intent.getComponent() != null) {
5487                    return false;
5488                }
5489            }
5490            return true;
5491        } catch (ClassCastException e) {
5492        }
5493        return false;
5494    }
5495
5496    @Override
5497    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5498        if (!(pendingResult instanceof PendingIntentRecord)) {
5499            return false;
5500        }
5501        try {
5502            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5503            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5504                return true;
5505            }
5506            return false;
5507        } catch (ClassCastException e) {
5508        }
5509        return false;
5510    }
5511
5512    @Override
5513    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5514        if (!(pendingResult instanceof PendingIntentRecord)) {
5515            return null;
5516        }
5517        try {
5518            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5519            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5520        } catch (ClassCastException e) {
5521        }
5522        return null;
5523    }
5524
5525    @Override
5526    public void setProcessLimit(int max) {
5527        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5528                "setProcessLimit()");
5529        synchronized (this) {
5530            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5531            mProcessLimitOverride = max;
5532        }
5533        trimApplications();
5534    }
5535
5536    @Override
5537    public int getProcessLimit() {
5538        synchronized (this) {
5539            return mProcessLimitOverride;
5540        }
5541    }
5542
5543    void foregroundTokenDied(ForegroundToken token) {
5544        synchronized (ActivityManagerService.this) {
5545            synchronized (mPidsSelfLocked) {
5546                ForegroundToken cur
5547                    = mForegroundProcesses.get(token.pid);
5548                if (cur != token) {
5549                    return;
5550                }
5551                mForegroundProcesses.remove(token.pid);
5552                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5553                if (pr == null) {
5554                    return;
5555                }
5556                pr.forcingToForeground = null;
5557                pr.foregroundServices = false;
5558            }
5559            updateOomAdjLocked();
5560        }
5561    }
5562
5563    @Override
5564    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5565        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5566                "setProcessForeground()");
5567        synchronized(this) {
5568            boolean changed = false;
5569
5570            synchronized (mPidsSelfLocked) {
5571                ProcessRecord pr = mPidsSelfLocked.get(pid);
5572                if (pr == null && isForeground) {
5573                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5574                    return;
5575                }
5576                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5577                if (oldToken != null) {
5578                    oldToken.token.unlinkToDeath(oldToken, 0);
5579                    mForegroundProcesses.remove(pid);
5580                    if (pr != null) {
5581                        pr.forcingToForeground = null;
5582                    }
5583                    changed = true;
5584                }
5585                if (isForeground && token != null) {
5586                    ForegroundToken newToken = new ForegroundToken() {
5587                        @Override
5588                        public void binderDied() {
5589                            foregroundTokenDied(this);
5590                        }
5591                    };
5592                    newToken.pid = pid;
5593                    newToken.token = token;
5594                    try {
5595                        token.linkToDeath(newToken, 0);
5596                        mForegroundProcesses.put(pid, newToken);
5597                        pr.forcingToForeground = token;
5598                        changed = true;
5599                    } catch (RemoteException e) {
5600                        // If the process died while doing this, we will later
5601                        // do the cleanup with the process death link.
5602                    }
5603                }
5604            }
5605
5606            if (changed) {
5607                updateOomAdjLocked();
5608            }
5609        }
5610    }
5611
5612    // =========================================================
5613    // PERMISSIONS
5614    // =========================================================
5615
5616    static class PermissionController extends IPermissionController.Stub {
5617        ActivityManagerService mActivityManagerService;
5618        PermissionController(ActivityManagerService activityManagerService) {
5619            mActivityManagerService = activityManagerService;
5620        }
5621
5622        @Override
5623        public boolean checkPermission(String permission, int pid, int uid) {
5624            return mActivityManagerService.checkPermission(permission, pid,
5625                    uid) == PackageManager.PERMISSION_GRANTED;
5626        }
5627    }
5628
5629    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5630        @Override
5631        public int checkComponentPermission(String permission, int pid, int uid,
5632                int owningUid, boolean exported) {
5633            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5634                    owningUid, exported);
5635        }
5636
5637        @Override
5638        public Object getAMSLock() {
5639            return ActivityManagerService.this;
5640        }
5641    }
5642
5643    /**
5644     * This can be called with or without the global lock held.
5645     */
5646    int checkComponentPermission(String permission, int pid, int uid,
5647            int owningUid, boolean exported) {
5648        // We might be performing an operation on behalf of an indirect binder
5649        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5650        // client identity accordingly before proceeding.
5651        Identity tlsIdentity = sCallerIdentity.get();
5652        if (tlsIdentity != null) {
5653            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5654                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5655            uid = tlsIdentity.uid;
5656            pid = tlsIdentity.pid;
5657        }
5658
5659        if (pid == MY_PID) {
5660            return PackageManager.PERMISSION_GRANTED;
5661        }
5662
5663        return ActivityManager.checkComponentPermission(permission, uid,
5664                owningUid, exported);
5665    }
5666
5667    /**
5668     * As the only public entry point for permissions checking, this method
5669     * can enforce the semantic that requesting a check on a null global
5670     * permission is automatically denied.  (Internally a null permission
5671     * string is used when calling {@link #checkComponentPermission} in cases
5672     * when only uid-based security is needed.)
5673     *
5674     * This can be called with or without the global lock held.
5675     */
5676    @Override
5677    public int checkPermission(String permission, int pid, int uid) {
5678        if (permission == null) {
5679            return PackageManager.PERMISSION_DENIED;
5680        }
5681        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5682    }
5683
5684    /**
5685     * Binder IPC calls go through the public entry point.
5686     * This can be called with or without the global lock held.
5687     */
5688    int checkCallingPermission(String permission) {
5689        return checkPermission(permission,
5690                Binder.getCallingPid(),
5691                UserHandle.getAppId(Binder.getCallingUid()));
5692    }
5693
5694    /**
5695     * This can be called with or without the global lock held.
5696     */
5697    void enforceCallingPermission(String permission, String func) {
5698        if (checkCallingPermission(permission)
5699                == PackageManager.PERMISSION_GRANTED) {
5700            return;
5701        }
5702
5703        String msg = "Permission Denial: " + func + " from pid="
5704                + Binder.getCallingPid()
5705                + ", uid=" + Binder.getCallingUid()
5706                + " requires " + permission;
5707        Slog.w(TAG, msg);
5708        throw new SecurityException(msg);
5709    }
5710
5711    /**
5712     * Determine if UID is holding permissions required to access {@link Uri} in
5713     * the given {@link ProviderInfo}. Final permission checking is always done
5714     * in {@link ContentProvider}.
5715     */
5716    private final boolean checkHoldingPermissionsLocked(
5717            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5718        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5719                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5720
5721        if (pi.applicationInfo.uid == uid) {
5722            return true;
5723        } else if (!pi.exported) {
5724            return false;
5725        }
5726
5727        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5728        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5729        try {
5730            // check if target holds top-level <provider> permissions
5731            if (!readMet && pi.readPermission != null
5732                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5733                readMet = true;
5734            }
5735            if (!writeMet && pi.writePermission != null
5736                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5737                writeMet = true;
5738            }
5739
5740            // track if unprotected read/write is allowed; any denied
5741            // <path-permission> below removes this ability
5742            boolean allowDefaultRead = pi.readPermission == null;
5743            boolean allowDefaultWrite = pi.writePermission == null;
5744
5745            // check if target holds any <path-permission> that match uri
5746            final PathPermission[] pps = pi.pathPermissions;
5747            if (pps != null) {
5748                final String path = uri.getPath();
5749                int i = pps.length;
5750                while (i > 0 && (!readMet || !writeMet)) {
5751                    i--;
5752                    PathPermission pp = pps[i];
5753                    if (pp.match(path)) {
5754                        if (!readMet) {
5755                            final String pprperm = pp.getReadPermission();
5756                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5757                                    + pprperm + " for " + pp.getPath()
5758                                    + ": match=" + pp.match(path)
5759                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5760                            if (pprperm != null) {
5761                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5762                                    readMet = true;
5763                                } else {
5764                                    allowDefaultRead = false;
5765                                }
5766                            }
5767                        }
5768                        if (!writeMet) {
5769                            final String ppwperm = pp.getWritePermission();
5770                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5771                                    + ppwperm + " for " + pp.getPath()
5772                                    + ": match=" + pp.match(path)
5773                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5774                            if (ppwperm != null) {
5775                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5776                                    writeMet = true;
5777                                } else {
5778                                    allowDefaultWrite = false;
5779                                }
5780                            }
5781                        }
5782                    }
5783                }
5784            }
5785
5786            // grant unprotected <provider> read/write, if not blocked by
5787            // <path-permission> above
5788            if (allowDefaultRead) readMet = true;
5789            if (allowDefaultWrite) writeMet = true;
5790
5791        } catch (RemoteException e) {
5792            return false;
5793        }
5794
5795        return readMet && writeMet;
5796    }
5797
5798    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5799        ProviderInfo pi = null;
5800        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5801        if (cpr != null) {
5802            pi = cpr.info;
5803        } else {
5804            try {
5805                pi = AppGlobals.getPackageManager().resolveContentProvider(
5806                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5807            } catch (RemoteException ex) {
5808            }
5809        }
5810        return pi;
5811    }
5812
5813    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5814        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5815        if (targetUris != null) {
5816            return targetUris.get(uri);
5817        } else {
5818            return null;
5819        }
5820    }
5821
5822    private UriPermission findOrCreateUriPermissionLocked(
5823            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5824        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5825        if (targetUris == null) {
5826            targetUris = Maps.newArrayMap();
5827            mGrantedUriPermissions.put(targetUid, targetUris);
5828        }
5829
5830        UriPermission perm = targetUris.get(uri);
5831        if (perm == null) {
5832            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5833            targetUris.put(uri, perm);
5834        }
5835
5836        return perm;
5837    }
5838
5839    private final boolean checkUriPermissionLocked(
5840            Uri uri, int uid, int modeFlags, int minStrength) {
5841        // Root gets to do everything.
5842        if (uid == 0) {
5843            return true;
5844        }
5845        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5846        if (perms == null) return false;
5847        UriPermission perm = perms.get(uri);
5848        if (perm == null) return false;
5849        return perm.getStrength(modeFlags) >= minStrength;
5850    }
5851
5852    @Override
5853    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5854        enforceNotIsolatedCaller("checkUriPermission");
5855
5856        // Another redirected-binder-call permissions check as in
5857        // {@link checkComponentPermission}.
5858        Identity tlsIdentity = sCallerIdentity.get();
5859        if (tlsIdentity != null) {
5860            uid = tlsIdentity.uid;
5861            pid = tlsIdentity.pid;
5862        }
5863
5864        // Our own process gets to do everything.
5865        if (pid == MY_PID) {
5866            return PackageManager.PERMISSION_GRANTED;
5867        }
5868        synchronized(this) {
5869            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5870                    ? PackageManager.PERMISSION_GRANTED
5871                    : PackageManager.PERMISSION_DENIED;
5872        }
5873    }
5874
5875    /**
5876     * Check if the targetPkg can be granted permission to access uri by
5877     * the callingUid using the given modeFlags.  Throws a security exception
5878     * if callingUid is not allowed to do this.  Returns the uid of the target
5879     * if the URI permission grant should be performed; returns -1 if it is not
5880     * needed (for example targetPkg already has permission to access the URI).
5881     * If you already know the uid of the target, you can supply it in
5882     * lastTargetUid else set that to -1.
5883     */
5884    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5885            Uri uri, int modeFlags, int lastTargetUid) {
5886        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5887        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5888                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5889        if (modeFlags == 0) {
5890            return -1;
5891        }
5892
5893        if (targetPkg != null) {
5894            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5895                    "Checking grant " + targetPkg + " permission to " + uri);
5896        }
5897
5898        final IPackageManager pm = AppGlobals.getPackageManager();
5899
5900        // If this is not a content: uri, we can't do anything with it.
5901        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5902            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5903                    "Can't grant URI permission for non-content URI: " + uri);
5904            return -1;
5905        }
5906
5907        final String authority = uri.getAuthority();
5908        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5909        if (pi == null) {
5910            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5911            return -1;
5912        }
5913
5914        int targetUid = lastTargetUid;
5915        if (targetUid < 0 && targetPkg != null) {
5916            try {
5917                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5918                if (targetUid < 0) {
5919                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5920                            "Can't grant URI permission no uid for: " + targetPkg);
5921                    return -1;
5922                }
5923            } catch (RemoteException ex) {
5924                return -1;
5925            }
5926        }
5927
5928        if (targetUid >= 0) {
5929            // First...  does the target actually need this permission?
5930            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5931                // No need to grant the target this permission.
5932                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5933                        "Target " + targetPkg + " already has full permission to " + uri);
5934                return -1;
5935            }
5936        } else {
5937            // First...  there is no target package, so can anyone access it?
5938            boolean allowed = pi.exported;
5939            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5940                if (pi.readPermission != null) {
5941                    allowed = false;
5942                }
5943            }
5944            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5945                if (pi.writePermission != null) {
5946                    allowed = false;
5947                }
5948            }
5949            if (allowed) {
5950                return -1;
5951            }
5952        }
5953
5954        // Second...  is the provider allowing granting of URI permissions?
5955        if (!pi.grantUriPermissions) {
5956            throw new SecurityException("Provider " + pi.packageName
5957                    + "/" + pi.name
5958                    + " does not allow granting of Uri permissions (uri "
5959                    + uri + ")");
5960        }
5961        if (pi.uriPermissionPatterns != null) {
5962            final int N = pi.uriPermissionPatterns.length;
5963            boolean allowed = false;
5964            for (int i=0; i<N; i++) {
5965                if (pi.uriPermissionPatterns[i] != null
5966                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5967                    allowed = true;
5968                    break;
5969                }
5970            }
5971            if (!allowed) {
5972                throw new SecurityException("Provider " + pi.packageName
5973                        + "/" + pi.name
5974                        + " does not allow granting of permission to path of Uri "
5975                        + uri);
5976            }
5977        }
5978
5979        // Third...  does the caller itself have permission to access
5980        // this uri?
5981        if (callingUid != Process.myUid()) {
5982            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5983                // Require they hold a strong enough Uri permission
5984                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
5985                        : UriPermission.STRENGTH_OWNED;
5986                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
5987                    throw new SecurityException("Uid " + callingUid
5988                            + " does not have permission to uri " + uri);
5989                }
5990            }
5991        }
5992
5993        return targetUid;
5994    }
5995
5996    @Override
5997    public int checkGrantUriPermission(int callingUid, String targetPkg,
5998            Uri uri, int modeFlags) {
5999        enforceNotIsolatedCaller("checkGrantUriPermission");
6000        synchronized(this) {
6001            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6002        }
6003    }
6004
6005    void grantUriPermissionUncheckedLocked(
6006            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6007        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6008        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6009                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6010        if (modeFlags == 0) {
6011            return;
6012        }
6013
6014        // So here we are: the caller has the assumed permission
6015        // to the uri, and the target doesn't.  Let's now give this to
6016        // the target.
6017
6018        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6019                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6020
6021        final String authority = uri.getAuthority();
6022        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6023        if (pi == null) {
6024            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6025            return;
6026        }
6027
6028        final UriPermission perm = findOrCreateUriPermissionLocked(
6029                pi.packageName, targetPkg, targetUid, uri);
6030        perm.grantModes(modeFlags, persistable, owner);
6031    }
6032
6033    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6034            int modeFlags, UriPermissionOwner owner) {
6035        if (targetPkg == null) {
6036            throw new NullPointerException("targetPkg");
6037        }
6038
6039        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6040        if (targetUid < 0) {
6041            return;
6042        }
6043
6044        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6045    }
6046
6047    static class NeededUriGrants extends ArrayList<Uri> {
6048        final String targetPkg;
6049        final int targetUid;
6050        final int flags;
6051
6052        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6053            this.targetPkg = targetPkg;
6054            this.targetUid = targetUid;
6055            this.flags = flags;
6056        }
6057    }
6058
6059    /**
6060     * Like checkGrantUriPermissionLocked, but takes an Intent.
6061     */
6062    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6063            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6064        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6065                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6066                + " clip=" + (intent != null ? intent.getClipData() : null)
6067                + " from " + intent + "; flags=0x"
6068                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6069
6070        if (targetPkg == null) {
6071            throw new NullPointerException("targetPkg");
6072        }
6073
6074        if (intent == null) {
6075            return null;
6076        }
6077        Uri data = intent.getData();
6078        ClipData clip = intent.getClipData();
6079        if (data == null && clip == null) {
6080            return null;
6081        }
6082
6083        if (data != null) {
6084            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6085                mode, needed != null ? needed.targetUid : -1);
6086            if (targetUid > 0) {
6087                if (needed == null) {
6088                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6089                }
6090                needed.add(data);
6091            }
6092        }
6093        if (clip != null) {
6094            for (int i=0; i<clip.getItemCount(); i++) {
6095                Uri uri = clip.getItemAt(i).getUri();
6096                if (uri != null) {
6097                    int targetUid = -1;
6098                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6099                            mode, needed != null ? needed.targetUid : -1);
6100                    if (targetUid > 0) {
6101                        if (needed == null) {
6102                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6103                        }
6104                        needed.add(uri);
6105                    }
6106                } else {
6107                    Intent clipIntent = clip.getItemAt(i).getIntent();
6108                    if (clipIntent != null) {
6109                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6110                                callingUid, targetPkg, clipIntent, mode, needed);
6111                        if (newNeeded != null) {
6112                            needed = newNeeded;
6113                        }
6114                    }
6115                }
6116            }
6117        }
6118
6119        return needed;
6120    }
6121
6122    /**
6123     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6124     */
6125    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6126            UriPermissionOwner owner) {
6127        if (needed != null) {
6128            for (int i=0; i<needed.size(); i++) {
6129                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6130                        needed.get(i), needed.flags, owner);
6131            }
6132        }
6133    }
6134
6135    void grantUriPermissionFromIntentLocked(int callingUid,
6136            String targetPkg, Intent intent, UriPermissionOwner owner) {
6137        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6138                intent, intent != null ? intent.getFlags() : 0, null);
6139        if (needed == null) {
6140            return;
6141        }
6142
6143        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6144    }
6145
6146    @Override
6147    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6148            Uri uri, int modeFlags) {
6149        enforceNotIsolatedCaller("grantUriPermission");
6150        synchronized(this) {
6151            final ProcessRecord r = getRecordForAppLocked(caller);
6152            if (r == null) {
6153                throw new SecurityException("Unable to find app for caller "
6154                        + caller
6155                        + " when granting permission to uri " + uri);
6156            }
6157            if (targetPkg == null) {
6158                throw new IllegalArgumentException("null target");
6159            }
6160            if (uri == null) {
6161                throw new IllegalArgumentException("null uri");
6162            }
6163
6164            // Persistable only supported through Intents
6165            Preconditions.checkFlagsArgument(modeFlags,
6166                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6167
6168            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6169                    null);
6170        }
6171    }
6172
6173    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6174        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6175                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6176            ArrayMap<Uri, UriPermission> perms
6177                    = mGrantedUriPermissions.get(perm.targetUid);
6178            if (perms != null) {
6179                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6180                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6181                perms.remove(perm.uri);
6182                if (perms.size() == 0) {
6183                    mGrantedUriPermissions.remove(perm.targetUid);
6184                }
6185            }
6186        }
6187    }
6188
6189    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6190        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6191
6192        final IPackageManager pm = AppGlobals.getPackageManager();
6193        final String authority = uri.getAuthority();
6194        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6195        if (pi == null) {
6196            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6197            return;
6198        }
6199
6200        // Does the caller have this permission on the URI?
6201        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6202            // Right now, if you are not the original owner of the permission,
6203            // you are not allowed to revoke it.
6204            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6205                throw new SecurityException("Uid " + callingUid
6206                        + " does not have permission to uri " + uri);
6207            //}
6208        }
6209
6210        boolean persistChanged = false;
6211
6212        // Go through all of the permissions and remove any that match.
6213        final List<String> SEGMENTS = uri.getPathSegments();
6214        if (SEGMENTS != null) {
6215            final int NS = SEGMENTS.size();
6216            int N = mGrantedUriPermissions.size();
6217            for (int i=0; i<N; i++) {
6218                ArrayMap<Uri, UriPermission> perms
6219                        = mGrantedUriPermissions.valueAt(i);
6220                Iterator<UriPermission> it = perms.values().iterator();
6221            toploop:
6222                while (it.hasNext()) {
6223                    UriPermission perm = it.next();
6224                    Uri targetUri = perm.uri;
6225                    if (!authority.equals(targetUri.getAuthority())) {
6226                        continue;
6227                    }
6228                    List<String> targetSegments = targetUri.getPathSegments();
6229                    if (targetSegments == null) {
6230                        continue;
6231                    }
6232                    if (targetSegments.size() < NS) {
6233                        continue;
6234                    }
6235                    for (int j=0; j<NS; j++) {
6236                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6237                            continue toploop;
6238                        }
6239                    }
6240                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6241                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6242                    persistChanged |= perm.clearModes(modeFlags, true);
6243                    if (perm.modeFlags == 0) {
6244                        it.remove();
6245                    }
6246                }
6247                if (perms.size() == 0) {
6248                    mGrantedUriPermissions.remove(
6249                            mGrantedUriPermissions.keyAt(i));
6250                    N--;
6251                    i--;
6252                }
6253            }
6254        }
6255
6256        if (persistChanged) {
6257            schedulePersistUriGrants();
6258        }
6259    }
6260
6261    @Override
6262    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6263            int modeFlags) {
6264        enforceNotIsolatedCaller("revokeUriPermission");
6265        synchronized(this) {
6266            final ProcessRecord r = getRecordForAppLocked(caller);
6267            if (r == null) {
6268                throw new SecurityException("Unable to find app for caller "
6269                        + caller
6270                        + " when revoking permission to uri " + uri);
6271            }
6272            if (uri == null) {
6273                Slog.w(TAG, "revokeUriPermission: null uri");
6274                return;
6275            }
6276
6277            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6278                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6279            if (modeFlags == 0) {
6280                return;
6281            }
6282
6283            final IPackageManager pm = AppGlobals.getPackageManager();
6284            final String authority = uri.getAuthority();
6285            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6286            if (pi == null) {
6287                Slog.w(TAG, "No content provider found for permission revoke: "
6288                        + uri.toSafeString());
6289                return;
6290            }
6291
6292            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6293        }
6294    }
6295
6296    /**
6297     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6298     * given package.
6299     *
6300     * @param packageName Package name to match, or {@code null} to apply to all
6301     *            packages.
6302     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6303     *            to all users.
6304     * @param persistable If persistable grants should be removed.
6305     */
6306    private void removeUriPermissionsForPackageLocked(
6307            String packageName, int userHandle, boolean persistable) {
6308        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6309            throw new IllegalArgumentException("Must narrow by either package or user");
6310        }
6311
6312        boolean persistChanged = false;
6313
6314        final int size = mGrantedUriPermissions.size();
6315        for (int i = 0; i < size; i++) {
6316            // Only inspect grants matching user
6317            if (userHandle == UserHandle.USER_ALL
6318                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6319                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6320                        .values().iterator();
6321                while (it.hasNext()) {
6322                    final UriPermission perm = it.next();
6323
6324                    // Only inspect grants matching package
6325                    if (packageName == null || perm.sourcePkg.equals(packageName)
6326                            || perm.targetPkg.equals(packageName)) {
6327                        persistChanged |= perm.clearModes(~0, persistable);
6328
6329                        // Only remove when no modes remain; any persisted grants
6330                        // will keep this alive.
6331                        if (perm.modeFlags == 0) {
6332                            it.remove();
6333                        }
6334                    }
6335                }
6336            }
6337        }
6338
6339        if (persistChanged) {
6340            schedulePersistUriGrants();
6341        }
6342    }
6343
6344    @Override
6345    public IBinder newUriPermissionOwner(String name) {
6346        enforceNotIsolatedCaller("newUriPermissionOwner");
6347        synchronized(this) {
6348            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6349            return owner.getExternalTokenLocked();
6350        }
6351    }
6352
6353    @Override
6354    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6355            Uri uri, int modeFlags) {
6356        synchronized(this) {
6357            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6358            if (owner == null) {
6359                throw new IllegalArgumentException("Unknown owner: " + token);
6360            }
6361            if (fromUid != Binder.getCallingUid()) {
6362                if (Binder.getCallingUid() != Process.myUid()) {
6363                    // Only system code can grant URI permissions on behalf
6364                    // of other users.
6365                    throw new SecurityException("nice try");
6366                }
6367            }
6368            if (targetPkg == null) {
6369                throw new IllegalArgumentException("null target");
6370            }
6371            if (uri == null) {
6372                throw new IllegalArgumentException("null uri");
6373            }
6374
6375            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6376        }
6377    }
6378
6379    @Override
6380    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6381        synchronized(this) {
6382            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6383            if (owner == null) {
6384                throw new IllegalArgumentException("Unknown owner: " + token);
6385            }
6386
6387            if (uri == null) {
6388                owner.removeUriPermissionsLocked(mode);
6389            } else {
6390                owner.removeUriPermissionLocked(uri, mode);
6391            }
6392        }
6393    }
6394
6395    private void schedulePersistUriGrants() {
6396        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6397            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6398                    10 * DateUtils.SECOND_IN_MILLIS);
6399        }
6400    }
6401
6402    private void writeGrantedUriPermissions() {
6403        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6404
6405        // Snapshot permissions so we can persist without lock
6406        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6407        synchronized (this) {
6408            final int size = mGrantedUriPermissions.size();
6409            for (int i = 0 ; i < size; i++) {
6410                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6411                    if (perm.persistedModeFlags != 0) {
6412                        persist.add(perm.snapshot());
6413                    }
6414                }
6415            }
6416        }
6417
6418        FileOutputStream fos = null;
6419        try {
6420            fos = mGrantFile.startWrite();
6421
6422            XmlSerializer out = new FastXmlSerializer();
6423            out.setOutput(fos, "utf-8");
6424            out.startDocument(null, true);
6425            out.startTag(null, TAG_URI_GRANTS);
6426            for (UriPermission.Snapshot perm : persist) {
6427                out.startTag(null, TAG_URI_GRANT);
6428                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6429                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6430                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6431                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6432                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6433                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6434                out.endTag(null, TAG_URI_GRANT);
6435            }
6436            out.endTag(null, TAG_URI_GRANTS);
6437            out.endDocument();
6438
6439            mGrantFile.finishWrite(fos);
6440        } catch (IOException e) {
6441            if (fos != null) {
6442                mGrantFile.failWrite(fos);
6443            }
6444        }
6445    }
6446
6447    private void readGrantedUriPermissionsLocked() {
6448        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6449
6450        final long now = System.currentTimeMillis();
6451
6452        FileInputStream fis = null;
6453        try {
6454            fis = mGrantFile.openRead();
6455            final XmlPullParser in = Xml.newPullParser();
6456            in.setInput(fis, null);
6457
6458            int type;
6459            while ((type = in.next()) != END_DOCUMENT) {
6460                final String tag = in.getName();
6461                if (type == START_TAG) {
6462                    if (TAG_URI_GRANT.equals(tag)) {
6463                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6464                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6465                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6466                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6467                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6468                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6469
6470                        // Sanity check that provider still belongs to source package
6471                        final ProviderInfo pi = getProviderInfoLocked(
6472                                uri.getAuthority(), userHandle);
6473                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6474                            int targetUid = -1;
6475                            try {
6476                                targetUid = AppGlobals.getPackageManager()
6477                                        .getPackageUid(targetPkg, userHandle);
6478                            } catch (RemoteException e) {
6479                            }
6480                            if (targetUid != -1) {
6481                                final UriPermission perm = findOrCreateUriPermissionLocked(
6482                                        sourcePkg, targetPkg, targetUid, uri);
6483                                perm.initPersistedModes(modeFlags, createdTime);
6484                            }
6485                        } else {
6486                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6487                                    + " but instead found " + pi);
6488                        }
6489                    }
6490                }
6491            }
6492        } catch (FileNotFoundException e) {
6493            // Missing grants is okay
6494        } catch (IOException e) {
6495            Log.wtf(TAG, "Failed reading Uri grants", e);
6496        } catch (XmlPullParserException e) {
6497            Log.wtf(TAG, "Failed reading Uri grants", e);
6498        } finally {
6499            IoUtils.closeQuietly(fis);
6500        }
6501    }
6502
6503    @Override
6504    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6505        enforceNotIsolatedCaller("takePersistableUriPermission");
6506
6507        Preconditions.checkFlagsArgument(modeFlags,
6508                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6509
6510        synchronized (this) {
6511            final int callingUid = Binder.getCallingUid();
6512            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6513            if (perm == null) {
6514                throw new SecurityException("No permission grant found for UID " + callingUid
6515                        + " and Uri " + uri.toSafeString());
6516            }
6517
6518            boolean persistChanged = perm.takePersistableModes(modeFlags);
6519            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6520
6521            if (persistChanged) {
6522                schedulePersistUriGrants();
6523            }
6524        }
6525    }
6526
6527    @Override
6528    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6529        enforceNotIsolatedCaller("releasePersistableUriPermission");
6530
6531        Preconditions.checkFlagsArgument(modeFlags,
6532                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6533
6534        synchronized (this) {
6535            final int callingUid = Binder.getCallingUid();
6536
6537            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6538            if (perm == null) {
6539                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6540                        + uri.toSafeString());
6541                return;
6542            }
6543
6544            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6545            removeUriPermissionIfNeededLocked(perm);
6546            if (persistChanged) {
6547                schedulePersistUriGrants();
6548            }
6549        }
6550    }
6551
6552    /**
6553     * Prune any older {@link UriPermission} for the given UID until outstanding
6554     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6555     *
6556     * @return if any mutations occured that require persisting.
6557     */
6558    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6559        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6560        if (perms == null) return false;
6561        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6562
6563        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6564        for (UriPermission perm : perms.values()) {
6565            if (perm.persistedModeFlags != 0) {
6566                persisted.add(perm);
6567            }
6568        }
6569
6570        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6571        if (trimCount <= 0) return false;
6572
6573        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6574        for (int i = 0; i < trimCount; i++) {
6575            final UriPermission perm = persisted.get(i);
6576
6577            if (DEBUG_URI_PERMISSION) {
6578                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6579            }
6580
6581            perm.releasePersistableModes(~0);
6582            removeUriPermissionIfNeededLocked(perm);
6583        }
6584
6585        return true;
6586    }
6587
6588    @Override
6589    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6590            String packageName, boolean incoming) {
6591        enforceNotIsolatedCaller("getPersistedUriPermissions");
6592        Preconditions.checkNotNull(packageName, "packageName");
6593
6594        final int callingUid = Binder.getCallingUid();
6595        final IPackageManager pm = AppGlobals.getPackageManager();
6596        try {
6597            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6598            if (packageUid != callingUid) {
6599                throw new SecurityException(
6600                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6601            }
6602        } catch (RemoteException e) {
6603            throw new SecurityException("Failed to verify package name ownership");
6604        }
6605
6606        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6607        synchronized (this) {
6608            if (incoming) {
6609                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6610                if (perms == null) {
6611                    Slog.w(TAG, "No permission grants found for " + packageName);
6612                } else {
6613                    final int size = perms.size();
6614                    for (int i = 0; i < size; i++) {
6615                        final UriPermission perm = perms.valueAt(i);
6616                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6617                            result.add(perm.buildPersistedPublicApiObject());
6618                        }
6619                    }
6620                }
6621            } else {
6622                final int size = mGrantedUriPermissions.size();
6623                for (int i = 0; i < size; i++) {
6624                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6625                    final int permsSize = perms.size();
6626                    for (int j = 0; j < permsSize; j++) {
6627                        final UriPermission perm = perms.valueAt(j);
6628                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6629                            result.add(perm.buildPersistedPublicApiObject());
6630                        }
6631                    }
6632                }
6633            }
6634        }
6635        return new ParceledListSlice<android.content.UriPermission>(result);
6636    }
6637
6638    @Override
6639    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6640        synchronized (this) {
6641            ProcessRecord app =
6642                who != null ? getRecordForAppLocked(who) : null;
6643            if (app == null) return;
6644
6645            Message msg = Message.obtain();
6646            msg.what = WAIT_FOR_DEBUGGER_MSG;
6647            msg.obj = app;
6648            msg.arg1 = waiting ? 1 : 0;
6649            mHandler.sendMessage(msg);
6650        }
6651    }
6652
6653    @Override
6654    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6655        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6656        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6657        outInfo.availMem = Process.getFreeMemory();
6658        outInfo.totalMem = Process.getTotalMemory();
6659        outInfo.threshold = homeAppMem;
6660        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6661        outInfo.hiddenAppThreshold = cachedAppMem;
6662        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6663                ProcessList.SERVICE_ADJ);
6664        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6665                ProcessList.VISIBLE_APP_ADJ);
6666        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6667                ProcessList.FOREGROUND_APP_ADJ);
6668    }
6669
6670    // =========================================================
6671    // TASK MANAGEMENT
6672    // =========================================================
6673
6674    @Override
6675    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6676                         IThumbnailReceiver receiver) {
6677        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6678
6679        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6680        ActivityRecord topRecord = null;
6681
6682        synchronized(this) {
6683            if (localLOGV) Slog.v(
6684                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6685                + ", receiver=" + receiver);
6686
6687            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6688                    != PackageManager.PERMISSION_GRANTED) {
6689                if (receiver != null) {
6690                    // If the caller wants to wait for pending thumbnails,
6691                    // it ain't gonna get them.
6692                    try {
6693                        receiver.finished();
6694                    } catch (RemoteException ex) {
6695                    }
6696                }
6697                String msg = "Permission Denial: getTasks() from pid="
6698                        + Binder.getCallingPid()
6699                        + ", uid=" + Binder.getCallingUid()
6700                        + " requires " + android.Manifest.permission.GET_TASKS;
6701                Slog.w(TAG, msg);
6702                throw new SecurityException(msg);
6703            }
6704
6705            // TODO: Improve with MRU list from all ActivityStacks.
6706            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6707
6708            if (!pending.pendingRecords.isEmpty()) {
6709                mPendingThumbnails.add(pending);
6710            }
6711        }
6712
6713        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6714
6715        if (topRecord != null) {
6716            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6717            try {
6718                IApplicationThread topThumbnail = topRecord.app.thread;
6719                topThumbnail.requestThumbnail(topRecord.appToken);
6720            } catch (Exception e) {
6721                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6722                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6723            }
6724        }
6725
6726        if (pending == null && receiver != null) {
6727            // In this case all thumbnails were available and the client
6728            // is being asked to be told when the remaining ones come in...
6729            // which is unusually, since the top-most currently running
6730            // activity should never have a canned thumbnail!  Oh well.
6731            try {
6732                receiver.finished();
6733            } catch (RemoteException ex) {
6734            }
6735        }
6736
6737        return list;
6738    }
6739
6740    TaskRecord getMostRecentTask() {
6741        return mRecentTasks.get(0);
6742    }
6743
6744    @Override
6745    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6746            int flags, int userId) {
6747        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6748                false, true, "getRecentTasks", null);
6749
6750        synchronized (this) {
6751            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6752                    "getRecentTasks()");
6753            final boolean detailed = checkCallingPermission(
6754                    android.Manifest.permission.GET_DETAILED_TASKS)
6755                    == PackageManager.PERMISSION_GRANTED;
6756
6757            IPackageManager pm = AppGlobals.getPackageManager();
6758
6759            final int N = mRecentTasks.size();
6760            ArrayList<ActivityManager.RecentTaskInfo> res
6761                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6762                            maxNum < N ? maxNum : N);
6763            for (int i=0; i<N && maxNum > 0; i++) {
6764                TaskRecord tr = mRecentTasks.get(i);
6765                // Only add calling user's recent tasks
6766                if (tr.userId != userId) continue;
6767                // Return the entry if desired by the caller.  We always return
6768                // the first entry, because callers always expect this to be the
6769                // foreground app.  We may filter others if the caller has
6770                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6771                // we should exclude the entry.
6772
6773                if (i == 0
6774                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6775                        || (tr.intent == null)
6776                        || ((tr.intent.getFlags()
6777                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6778                    ActivityManager.RecentTaskInfo rti
6779                            = new ActivityManager.RecentTaskInfo();
6780                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6781                    rti.persistentId = tr.taskId;
6782                    rti.baseIntent = new Intent(
6783                            tr.intent != null ? tr.intent : tr.affinityIntent);
6784                    if (!detailed) {
6785                        rti.baseIntent.replaceExtras((Bundle)null);
6786                    }
6787                    rti.origActivity = tr.origActivity;
6788                    rti.description = tr.lastDescription;
6789                    rti.stackId = tr.stack.mStackId;
6790
6791                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6792                        // Check whether this activity is currently available.
6793                        try {
6794                            if (rti.origActivity != null) {
6795                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6796                                        == null) {
6797                                    continue;
6798                                }
6799                            } else if (rti.baseIntent != null) {
6800                                if (pm.queryIntentActivities(rti.baseIntent,
6801                                        null, 0, userId) == null) {
6802                                    continue;
6803                                }
6804                            }
6805                        } catch (RemoteException e) {
6806                            // Will never happen.
6807                        }
6808                    }
6809
6810                    res.add(rti);
6811                    maxNum--;
6812                }
6813            }
6814            return res;
6815        }
6816    }
6817
6818    private TaskRecord recentTaskForIdLocked(int id) {
6819        final int N = mRecentTasks.size();
6820            for (int i=0; i<N; i++) {
6821                TaskRecord tr = mRecentTasks.get(i);
6822                if (tr.taskId == id) {
6823                    return tr;
6824                }
6825            }
6826            return null;
6827    }
6828
6829    @Override
6830    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6831        synchronized (this) {
6832            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6833                    "getTaskThumbnails()");
6834            TaskRecord tr = recentTaskForIdLocked(id);
6835            if (tr != null) {
6836                return tr.getTaskThumbnailsLocked();
6837            }
6838        }
6839        return null;
6840    }
6841
6842    @Override
6843    public Bitmap getTaskTopThumbnail(int id) {
6844        synchronized (this) {
6845            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6846                    "getTaskTopThumbnail()");
6847            TaskRecord tr = recentTaskForIdLocked(id);
6848            if (tr != null) {
6849                return tr.getTaskTopThumbnailLocked();
6850            }
6851        }
6852        return null;
6853    }
6854
6855    @Override
6856    public boolean removeSubTask(int taskId, int subTaskIndex) {
6857        synchronized (this) {
6858            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6859                    "removeSubTask()");
6860            long ident = Binder.clearCallingIdentity();
6861            try {
6862                TaskRecord tr = recentTaskForIdLocked(taskId);
6863                if (tr != null) {
6864                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6865                }
6866                return false;
6867            } finally {
6868                Binder.restoreCallingIdentity(ident);
6869            }
6870        }
6871    }
6872
6873    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6874        if (!pr.killedByAm) {
6875            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6876            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6877                    pr.processName, pr.setAdj, reason);
6878            pr.killedByAm = true;
6879            Process.killProcessQuiet(pr.pid);
6880        }
6881    }
6882
6883    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6884        tr.disposeThumbnail();
6885        mRecentTasks.remove(tr);
6886        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6887        Intent baseIntent = new Intent(
6888                tr.intent != null ? tr.intent : tr.affinityIntent);
6889        ComponentName component = baseIntent.getComponent();
6890        if (component == null) {
6891            Slog.w(TAG, "Now component for base intent of task: " + tr);
6892            return;
6893        }
6894
6895        // Find any running services associated with this app.
6896        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6897
6898        if (killProcesses) {
6899            // Find any running processes associated with this app.
6900            final String pkg = component.getPackageName();
6901            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6902            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6903            for (int i=0; i<pmap.size(); i++) {
6904                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6905                for (int j=0; j<uids.size(); j++) {
6906                    ProcessRecord proc = uids.valueAt(j);
6907                    if (proc.userId != tr.userId) {
6908                        continue;
6909                    }
6910                    if (!proc.pkgList.containsKey(pkg)) {
6911                        continue;
6912                    }
6913                    procs.add(proc);
6914                }
6915            }
6916
6917            // Kill the running processes.
6918            for (int i=0; i<procs.size(); i++) {
6919                ProcessRecord pr = procs.get(i);
6920                if (pr == mHomeProcess) {
6921                    // Don't kill the home process along with tasks from the same package.
6922                    continue;
6923                }
6924                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6925                    killUnneededProcessLocked(pr, "remove task");
6926                } else {
6927                    pr.waitingToKill = "remove task";
6928                }
6929            }
6930        }
6931    }
6932
6933    @Override
6934    public boolean removeTask(int taskId, int flags) {
6935        synchronized (this) {
6936            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6937                    "removeTask()");
6938            long ident = Binder.clearCallingIdentity();
6939            try {
6940                TaskRecord tr = recentTaskForIdLocked(taskId);
6941                if (tr != null) {
6942                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6943                    if (r != null) {
6944                        cleanUpRemovedTaskLocked(tr, flags);
6945                        return true;
6946                    }
6947                    if (tr.mActivities.size() == 0) {
6948                        // Caller is just removing a recent task that is
6949                        // not actively running.  That is easy!
6950                        cleanUpRemovedTaskLocked(tr, flags);
6951                        return true;
6952                    }
6953                    Slog.w(TAG, "removeTask: task " + taskId
6954                            + " does not have activities to remove, "
6955                            + " but numActivities=" + tr.numActivities
6956                            + ": " + tr);
6957                }
6958            } finally {
6959                Binder.restoreCallingIdentity(ident);
6960            }
6961        }
6962        return false;
6963    }
6964
6965    /**
6966     * TODO: Add mController hook
6967     */
6968    @Override
6969    public void moveTaskToFront(int task, int flags, Bundle options) {
6970        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6971                "moveTaskToFront()");
6972
6973        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
6974        synchronized(this) {
6975            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6976                    Binder.getCallingUid(), "Task to front")) {
6977                ActivityOptions.abort(options);
6978                return;
6979            }
6980            final long origId = Binder.clearCallingIdentity();
6981            try {
6982                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
6983            } finally {
6984                Binder.restoreCallingIdentity(origId);
6985            }
6986            ActivityOptions.abort(options);
6987        }
6988    }
6989
6990    @Override
6991    public void moveTaskToBack(int taskId) {
6992        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6993                "moveTaskToBack()");
6994
6995        synchronized(this) {
6996            TaskRecord tr = recentTaskForIdLocked(taskId);
6997            if (tr != null) {
6998                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
6999                ActivityStack stack = tr.stack;
7000                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7001                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7002                            Binder.getCallingUid(), "Task to back")) {
7003                        return;
7004                    }
7005                }
7006                final long origId = Binder.clearCallingIdentity();
7007                try {
7008                    stack.moveTaskToBackLocked(taskId, null);
7009                } finally {
7010                    Binder.restoreCallingIdentity(origId);
7011                }
7012            }
7013        }
7014    }
7015
7016    /**
7017     * Moves an activity, and all of the other activities within the same task, to the bottom
7018     * of the history stack.  The activity's order within the task is unchanged.
7019     *
7020     * @param token A reference to the activity we wish to move
7021     * @param nonRoot If false then this only works if the activity is the root
7022     *                of a task; if true it will work for any activity in a task.
7023     * @return Returns true if the move completed, false if not.
7024     */
7025    @Override
7026    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7027        enforceNotIsolatedCaller("moveActivityTaskToBack");
7028        synchronized(this) {
7029            final long origId = Binder.clearCallingIdentity();
7030            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7031            if (taskId >= 0) {
7032                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7033            }
7034            Binder.restoreCallingIdentity(origId);
7035        }
7036        return false;
7037    }
7038
7039    @Override
7040    public void moveTaskBackwards(int task) {
7041        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7042                "moveTaskBackwards()");
7043
7044        synchronized(this) {
7045            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7046                    Binder.getCallingUid(), "Task backwards")) {
7047                return;
7048            }
7049            final long origId = Binder.clearCallingIdentity();
7050            moveTaskBackwardsLocked(task);
7051            Binder.restoreCallingIdentity(origId);
7052        }
7053    }
7054
7055    private final void moveTaskBackwardsLocked(int task) {
7056        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7057    }
7058
7059    @Override
7060    public IBinder getHomeActivityToken() throws RemoteException {
7061        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7062                "getHomeActivityToken()");
7063        synchronized (this) {
7064            return mStackSupervisor.getHomeActivityToken();
7065        }
7066    }
7067
7068    @Override
7069    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7070            IActivityContainerCallback callback) throws RemoteException {
7071        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7072                "createActivityContainer()");
7073        synchronized (this) {
7074            if (parentActivityToken == null) {
7075                throw new IllegalArgumentException("parent token must not be null");
7076            }
7077            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7078            if (r == null) {
7079                return null;
7080            }
7081            if (callback == null) {
7082                throw new IllegalArgumentException("callback must not be null");
7083            }
7084            return mStackSupervisor.createActivityContainer(r, callback);
7085        }
7086    }
7087
7088    @Override
7089    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7090        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7091                "deleteActivityContainer()");
7092        synchronized (this) {
7093            mStackSupervisor.deleteActivityContainer(container);
7094        }
7095    }
7096
7097    @Override
7098    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7099            throws RemoteException {
7100        synchronized (this) {
7101            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7102            if (stack != null) {
7103                return stack.mActivityContainer;
7104            }
7105            return null;
7106        }
7107    }
7108
7109    @Override
7110    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7111        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7112                "moveTaskToStack()");
7113        if (stackId == HOME_STACK_ID) {
7114            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7115                    new RuntimeException("here").fillInStackTrace());
7116        }
7117        synchronized (this) {
7118            long ident = Binder.clearCallingIdentity();
7119            try {
7120                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7121                        + stackId + " toTop=" + toTop);
7122                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7123            } finally {
7124                Binder.restoreCallingIdentity(ident);
7125            }
7126        }
7127    }
7128
7129    @Override
7130    public void resizeStack(int stackBoxId, Rect bounds) {
7131        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7132                "resizeStackBox()");
7133        long ident = Binder.clearCallingIdentity();
7134        try {
7135            mWindowManager.resizeStack(stackBoxId, bounds);
7136        } finally {
7137            Binder.restoreCallingIdentity(ident);
7138        }
7139    }
7140
7141    @Override
7142    public List<StackInfo> getAllStackInfos() {
7143        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7144                "getAllStackInfos()");
7145        long ident = Binder.clearCallingIdentity();
7146        try {
7147            synchronized (this) {
7148                return mStackSupervisor.getAllStackInfosLocked();
7149            }
7150        } finally {
7151            Binder.restoreCallingIdentity(ident);
7152        }
7153    }
7154
7155    @Override
7156    public StackInfo getStackInfo(int stackId) {
7157        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7158                "getStackInfo()");
7159        long ident = Binder.clearCallingIdentity();
7160        try {
7161            synchronized (this) {
7162                return mStackSupervisor.getStackInfoLocked(stackId);
7163            }
7164        } finally {
7165            Binder.restoreCallingIdentity(ident);
7166        }
7167    }
7168
7169    @Override
7170    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7171        synchronized(this) {
7172            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7173        }
7174    }
7175
7176    // =========================================================
7177    // THUMBNAILS
7178    // =========================================================
7179
7180    public void reportThumbnail(IBinder token,
7181            Bitmap thumbnail, CharSequence description) {
7182        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7183        final long origId = Binder.clearCallingIdentity();
7184        sendPendingThumbnail(null, token, thumbnail, description, true);
7185        Binder.restoreCallingIdentity(origId);
7186    }
7187
7188    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7189            Bitmap thumbnail, CharSequence description, boolean always) {
7190        TaskRecord task;
7191        ArrayList<PendingThumbnailsRecord> receivers = null;
7192
7193        //System.out.println("Send pending thumbnail: " + r);
7194
7195        synchronized(this) {
7196            if (r == null) {
7197                r = ActivityRecord.isInStackLocked(token);
7198                if (r == null) {
7199                    return;
7200                }
7201            }
7202            if (thumbnail == null && r.thumbHolder != null) {
7203                thumbnail = r.thumbHolder.lastThumbnail;
7204                description = r.thumbHolder.lastDescription;
7205            }
7206            if (thumbnail == null && !always) {
7207                // If there is no thumbnail, and this entry is not actually
7208                // going away, then abort for now and pick up the next
7209                // thumbnail we get.
7210                return;
7211            }
7212            task = r.task;
7213
7214            int N = mPendingThumbnails.size();
7215            int i=0;
7216            while (i<N) {
7217                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7218                //System.out.println("Looking in " + pr.pendingRecords);
7219                if (pr.pendingRecords.remove(r)) {
7220                    if (receivers == null) {
7221                        receivers = new ArrayList<PendingThumbnailsRecord>();
7222                    }
7223                    receivers.add(pr);
7224                    if (pr.pendingRecords.size() == 0) {
7225                        pr.finished = true;
7226                        mPendingThumbnails.remove(i);
7227                        N--;
7228                        continue;
7229                    }
7230                }
7231                i++;
7232            }
7233        }
7234
7235        if (receivers != null) {
7236            final int N = receivers.size();
7237            for (int i=0; i<N; i++) {
7238                try {
7239                    PendingThumbnailsRecord pr = receivers.get(i);
7240                    pr.receiver.newThumbnail(
7241                        task != null ? task.taskId : -1, thumbnail, description);
7242                    if (pr.finished) {
7243                        pr.receiver.finished();
7244                    }
7245                } catch (Exception e) {
7246                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7247                }
7248            }
7249        }
7250    }
7251
7252    // =========================================================
7253    // CONTENT PROVIDERS
7254    // =========================================================
7255
7256    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7257        List<ProviderInfo> providers = null;
7258        try {
7259            providers = AppGlobals.getPackageManager().
7260                queryContentProviders(app.processName, app.uid,
7261                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7262        } catch (RemoteException ex) {
7263        }
7264        if (DEBUG_MU)
7265            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7266        int userId = app.userId;
7267        if (providers != null) {
7268            int N = providers.size();
7269            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7270            for (int i=0; i<N; i++) {
7271                ProviderInfo cpi =
7272                    (ProviderInfo)providers.get(i);
7273                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7274                        cpi.name, cpi.flags);
7275                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7276                    // This is a singleton provider, but a user besides the
7277                    // default user is asking to initialize a process it runs
7278                    // in...  well, no, it doesn't actually run in this process,
7279                    // it runs in the process of the default user.  Get rid of it.
7280                    providers.remove(i);
7281                    N--;
7282                    i--;
7283                    continue;
7284                }
7285
7286                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7287                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7288                if (cpr == null) {
7289                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7290                    mProviderMap.putProviderByClass(comp, cpr);
7291                }
7292                if (DEBUG_MU)
7293                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7294                app.pubProviders.put(cpi.name, cpr);
7295                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7296                    // Don't add this if it is a platform component that is marked
7297                    // to run in multiple processes, because this is actually
7298                    // part of the framework so doesn't make sense to track as a
7299                    // separate apk in the process.
7300                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7301                }
7302                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7303            }
7304        }
7305        return providers;
7306    }
7307
7308    /**
7309     * Check if {@link ProcessRecord} has a possible chance at accessing the
7310     * given {@link ProviderInfo}. Final permission checking is always done
7311     * in {@link ContentProvider}.
7312     */
7313    private final String checkContentProviderPermissionLocked(
7314            ProviderInfo cpi, ProcessRecord r) {
7315        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7316        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7317        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7318                cpi.applicationInfo.uid, cpi.exported)
7319                == PackageManager.PERMISSION_GRANTED) {
7320            return null;
7321        }
7322        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7323                cpi.applicationInfo.uid, cpi.exported)
7324                == PackageManager.PERMISSION_GRANTED) {
7325            return null;
7326        }
7327
7328        PathPermission[] pps = cpi.pathPermissions;
7329        if (pps != null) {
7330            int i = pps.length;
7331            while (i > 0) {
7332                i--;
7333                PathPermission pp = pps[i];
7334                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7335                        cpi.applicationInfo.uid, cpi.exported)
7336                        == PackageManager.PERMISSION_GRANTED) {
7337                    return null;
7338                }
7339                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7340                        cpi.applicationInfo.uid, cpi.exported)
7341                        == PackageManager.PERMISSION_GRANTED) {
7342                    return null;
7343                }
7344            }
7345        }
7346
7347        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7348        if (perms != null) {
7349            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7350                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7351                    return null;
7352                }
7353            }
7354        }
7355
7356        String msg;
7357        if (!cpi.exported) {
7358            msg = "Permission Denial: opening provider " + cpi.name
7359                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7360                    + ", uid=" + callingUid + ") that is not exported from uid "
7361                    + cpi.applicationInfo.uid;
7362        } else {
7363            msg = "Permission Denial: opening provider " + cpi.name
7364                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7365                    + ", uid=" + callingUid + ") requires "
7366                    + cpi.readPermission + " or " + cpi.writePermission;
7367        }
7368        Slog.w(TAG, msg);
7369        return msg;
7370    }
7371
7372    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7373            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7374        if (r != null) {
7375            for (int i=0; i<r.conProviders.size(); i++) {
7376                ContentProviderConnection conn = r.conProviders.get(i);
7377                if (conn.provider == cpr) {
7378                    if (DEBUG_PROVIDER) Slog.v(TAG,
7379                            "Adding provider requested by "
7380                            + r.processName + " from process "
7381                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7382                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7383                    if (stable) {
7384                        conn.stableCount++;
7385                        conn.numStableIncs++;
7386                    } else {
7387                        conn.unstableCount++;
7388                        conn.numUnstableIncs++;
7389                    }
7390                    return conn;
7391                }
7392            }
7393            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7394            if (stable) {
7395                conn.stableCount = 1;
7396                conn.numStableIncs = 1;
7397            } else {
7398                conn.unstableCount = 1;
7399                conn.numUnstableIncs = 1;
7400            }
7401            cpr.connections.add(conn);
7402            r.conProviders.add(conn);
7403            return conn;
7404        }
7405        cpr.addExternalProcessHandleLocked(externalProcessToken);
7406        return null;
7407    }
7408
7409    boolean decProviderCountLocked(ContentProviderConnection conn,
7410            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7411        if (conn != null) {
7412            cpr = conn.provider;
7413            if (DEBUG_PROVIDER) Slog.v(TAG,
7414                    "Removing provider requested by "
7415                    + conn.client.processName + " from process "
7416                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7417                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7418            if (stable) {
7419                conn.stableCount--;
7420            } else {
7421                conn.unstableCount--;
7422            }
7423            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7424                cpr.connections.remove(conn);
7425                conn.client.conProviders.remove(conn);
7426                return true;
7427            }
7428            return false;
7429        }
7430        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7431        return false;
7432    }
7433
7434    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7435            String name, IBinder token, boolean stable, int userId) {
7436        ContentProviderRecord cpr;
7437        ContentProviderConnection conn = null;
7438        ProviderInfo cpi = null;
7439
7440        synchronized(this) {
7441            ProcessRecord r = null;
7442            if (caller != null) {
7443                r = getRecordForAppLocked(caller);
7444                if (r == null) {
7445                    throw new SecurityException(
7446                            "Unable to find app for caller " + caller
7447                          + " (pid=" + Binder.getCallingPid()
7448                          + ") when getting content provider " + name);
7449                }
7450            }
7451
7452            // First check if this content provider has been published...
7453            cpr = mProviderMap.getProviderByName(name, userId);
7454            boolean providerRunning = cpr != null;
7455            if (providerRunning) {
7456                cpi = cpr.info;
7457                String msg;
7458                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7459                    throw new SecurityException(msg);
7460                }
7461
7462                if (r != null && cpr.canRunHere(r)) {
7463                    // This provider has been published or is in the process
7464                    // of being published...  but it is also allowed to run
7465                    // in the caller's process, so don't make a connection
7466                    // and just let the caller instantiate its own instance.
7467                    ContentProviderHolder holder = cpr.newHolder(null);
7468                    // don't give caller the provider object, it needs
7469                    // to make its own.
7470                    holder.provider = null;
7471                    return holder;
7472                }
7473
7474                final long origId = Binder.clearCallingIdentity();
7475
7476                // In this case the provider instance already exists, so we can
7477                // return it right away.
7478                conn = incProviderCountLocked(r, cpr, token, stable);
7479                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7480                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7481                        // If this is a perceptible app accessing the provider,
7482                        // make sure to count it as being accessed and thus
7483                        // back up on the LRU list.  This is good because
7484                        // content providers are often expensive to start.
7485                        updateLruProcessLocked(cpr.proc, false, null);
7486                    }
7487                }
7488
7489                if (cpr.proc != null) {
7490                    if (false) {
7491                        if (cpr.name.flattenToShortString().equals(
7492                                "com.android.providers.calendar/.CalendarProvider2")) {
7493                            Slog.v(TAG, "****************** KILLING "
7494                                + cpr.name.flattenToShortString());
7495                            Process.killProcess(cpr.proc.pid);
7496                        }
7497                    }
7498                    boolean success = updateOomAdjLocked(cpr.proc);
7499                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7500                    // NOTE: there is still a race here where a signal could be
7501                    // pending on the process even though we managed to update its
7502                    // adj level.  Not sure what to do about this, but at least
7503                    // the race is now smaller.
7504                    if (!success) {
7505                        // Uh oh...  it looks like the provider's process
7506                        // has been killed on us.  We need to wait for a new
7507                        // process to be started, and make sure its death
7508                        // doesn't kill our process.
7509                        Slog.i(TAG,
7510                                "Existing provider " + cpr.name.flattenToShortString()
7511                                + " is crashing; detaching " + r);
7512                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7513                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7514                        if (!lastRef) {
7515                            // This wasn't the last ref our process had on
7516                            // the provider...  we have now been killed, bail.
7517                            return null;
7518                        }
7519                        providerRunning = false;
7520                        conn = null;
7521                    }
7522                }
7523
7524                Binder.restoreCallingIdentity(origId);
7525            }
7526
7527            boolean singleton;
7528            if (!providerRunning) {
7529                try {
7530                    cpi = AppGlobals.getPackageManager().
7531                        resolveContentProvider(name,
7532                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7533                } catch (RemoteException ex) {
7534                }
7535                if (cpi == null) {
7536                    return null;
7537                }
7538                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7539                        cpi.name, cpi.flags);
7540                if (singleton) {
7541                    userId = 0;
7542                }
7543                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7544
7545                String msg;
7546                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7547                    throw new SecurityException(msg);
7548                }
7549
7550                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7551                        && !cpi.processName.equals("system")) {
7552                    // If this content provider does not run in the system
7553                    // process, and the system is not yet ready to run other
7554                    // processes, then fail fast instead of hanging.
7555                    throw new IllegalArgumentException(
7556                            "Attempt to launch content provider before system ready");
7557                }
7558
7559                // Make sure that the user who owns this provider is started.  If not,
7560                // we don't want to allow it to run.
7561                if (mStartedUsers.get(userId) == null) {
7562                    Slog.w(TAG, "Unable to launch app "
7563                            + cpi.applicationInfo.packageName + "/"
7564                            + cpi.applicationInfo.uid + " for provider "
7565                            + name + ": user " + userId + " is stopped");
7566                    return null;
7567                }
7568
7569                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7570                cpr = mProviderMap.getProviderByClass(comp, userId);
7571                final boolean firstClass = cpr == null;
7572                if (firstClass) {
7573                    try {
7574                        ApplicationInfo ai =
7575                            AppGlobals.getPackageManager().
7576                                getApplicationInfo(
7577                                        cpi.applicationInfo.packageName,
7578                                        STOCK_PM_FLAGS, userId);
7579                        if (ai == null) {
7580                            Slog.w(TAG, "No package info for content provider "
7581                                    + cpi.name);
7582                            return null;
7583                        }
7584                        ai = getAppInfoForUser(ai, userId);
7585                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7586                    } catch (RemoteException ex) {
7587                        // pm is in same process, this will never happen.
7588                    }
7589                }
7590
7591                if (r != null && cpr.canRunHere(r)) {
7592                    // If this is a multiprocess provider, then just return its
7593                    // info and allow the caller to instantiate it.  Only do
7594                    // this if the provider is the same user as the caller's
7595                    // process, or can run as root (so can be in any process).
7596                    return cpr.newHolder(null);
7597                }
7598
7599                if (DEBUG_PROVIDER) {
7600                    RuntimeException e = new RuntimeException("here");
7601                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7602                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7603                }
7604
7605                // This is single process, and our app is now connecting to it.
7606                // See if we are already in the process of launching this
7607                // provider.
7608                final int N = mLaunchingProviders.size();
7609                int i;
7610                for (i=0; i<N; i++) {
7611                    if (mLaunchingProviders.get(i) == cpr) {
7612                        break;
7613                    }
7614                }
7615
7616                // If the provider is not already being launched, then get it
7617                // started.
7618                if (i >= N) {
7619                    final long origId = Binder.clearCallingIdentity();
7620
7621                    try {
7622                        // Content provider is now in use, its package can't be stopped.
7623                        try {
7624                            AppGlobals.getPackageManager().setPackageStoppedState(
7625                                    cpr.appInfo.packageName, false, userId);
7626                        } catch (RemoteException e) {
7627                        } catch (IllegalArgumentException e) {
7628                            Slog.w(TAG, "Failed trying to unstop package "
7629                                    + cpr.appInfo.packageName + ": " + e);
7630                        }
7631
7632                        // Use existing process if already started
7633                        ProcessRecord proc = getProcessRecordLocked(
7634                                cpi.processName, cpr.appInfo.uid, false);
7635                        if (proc != null && proc.thread != null) {
7636                            if (DEBUG_PROVIDER) {
7637                                Slog.d(TAG, "Installing in existing process " + proc);
7638                            }
7639                            proc.pubProviders.put(cpi.name, cpr);
7640                            try {
7641                                proc.thread.scheduleInstallProvider(cpi);
7642                            } catch (RemoteException e) {
7643                            }
7644                        } else {
7645                            proc = startProcessLocked(cpi.processName,
7646                                    cpr.appInfo, false, 0, "content provider",
7647                                    new ComponentName(cpi.applicationInfo.packageName,
7648                                            cpi.name), false, false, false);
7649                            if (proc == null) {
7650                                Slog.w(TAG, "Unable to launch app "
7651                                        + cpi.applicationInfo.packageName + "/"
7652                                        + cpi.applicationInfo.uid + " for provider "
7653                                        + name + ": process is bad");
7654                                return null;
7655                            }
7656                        }
7657                        cpr.launchingApp = proc;
7658                        mLaunchingProviders.add(cpr);
7659                    } finally {
7660                        Binder.restoreCallingIdentity(origId);
7661                    }
7662                }
7663
7664                // Make sure the provider is published (the same provider class
7665                // may be published under multiple names).
7666                if (firstClass) {
7667                    mProviderMap.putProviderByClass(comp, cpr);
7668                }
7669
7670                mProviderMap.putProviderByName(name, cpr);
7671                conn = incProviderCountLocked(r, cpr, token, stable);
7672                if (conn != null) {
7673                    conn.waiting = true;
7674                }
7675            }
7676        }
7677
7678        // Wait for the provider to be published...
7679        synchronized (cpr) {
7680            while (cpr.provider == null) {
7681                if (cpr.launchingApp == null) {
7682                    Slog.w(TAG, "Unable to launch app "
7683                            + cpi.applicationInfo.packageName + "/"
7684                            + cpi.applicationInfo.uid + " for provider "
7685                            + name + ": launching app became null");
7686                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7687                            UserHandle.getUserId(cpi.applicationInfo.uid),
7688                            cpi.applicationInfo.packageName,
7689                            cpi.applicationInfo.uid, name);
7690                    return null;
7691                }
7692                try {
7693                    if (DEBUG_MU) {
7694                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7695                                + cpr.launchingApp);
7696                    }
7697                    if (conn != null) {
7698                        conn.waiting = true;
7699                    }
7700                    cpr.wait();
7701                } catch (InterruptedException ex) {
7702                } finally {
7703                    if (conn != null) {
7704                        conn.waiting = false;
7705                    }
7706                }
7707            }
7708        }
7709        return cpr != null ? cpr.newHolder(conn) : null;
7710    }
7711
7712    public final ContentProviderHolder getContentProvider(
7713            IApplicationThread caller, String name, int userId, boolean stable) {
7714        enforceNotIsolatedCaller("getContentProvider");
7715        if (caller == null) {
7716            String msg = "null IApplicationThread when getting content provider "
7717                    + name;
7718            Slog.w(TAG, msg);
7719            throw new SecurityException(msg);
7720        }
7721
7722        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7723                false, true, "getContentProvider", null);
7724        return getContentProviderImpl(caller, name, null, stable, userId);
7725    }
7726
7727    public ContentProviderHolder getContentProviderExternal(
7728            String name, int userId, IBinder token) {
7729        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7730            "Do not have permission in call getContentProviderExternal()");
7731        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7732                false, true, "getContentProvider", null);
7733        return getContentProviderExternalUnchecked(name, token, userId);
7734    }
7735
7736    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7737            IBinder token, int userId) {
7738        return getContentProviderImpl(null, name, token, true, userId);
7739    }
7740
7741    /**
7742     * Drop a content provider from a ProcessRecord's bookkeeping
7743     */
7744    public void removeContentProvider(IBinder connection, boolean stable) {
7745        enforceNotIsolatedCaller("removeContentProvider");
7746        synchronized (this) {
7747            ContentProviderConnection conn;
7748            try {
7749                conn = (ContentProviderConnection)connection;
7750            } catch (ClassCastException e) {
7751                String msg ="removeContentProvider: " + connection
7752                        + " not a ContentProviderConnection";
7753                Slog.w(TAG, msg);
7754                throw new IllegalArgumentException(msg);
7755            }
7756            if (conn == null) {
7757                throw new NullPointerException("connection is null");
7758            }
7759            if (decProviderCountLocked(conn, null, null, stable)) {
7760                updateOomAdjLocked();
7761            }
7762        }
7763    }
7764
7765    public void removeContentProviderExternal(String name, IBinder token) {
7766        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7767            "Do not have permission in call removeContentProviderExternal()");
7768        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7769    }
7770
7771    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7772        synchronized (this) {
7773            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7774            if(cpr == null) {
7775                //remove from mProvidersByClass
7776                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7777                return;
7778            }
7779
7780            //update content provider record entry info
7781            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7782            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7783            if (localCpr.hasExternalProcessHandles()) {
7784                if (localCpr.removeExternalProcessHandleLocked(token)) {
7785                    updateOomAdjLocked();
7786                } else {
7787                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7788                            + " with no external reference for token: "
7789                            + token + ".");
7790                }
7791            } else {
7792                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7793                        + " with no external references.");
7794            }
7795        }
7796    }
7797
7798    public final void publishContentProviders(IApplicationThread caller,
7799            List<ContentProviderHolder> providers) {
7800        if (providers == null) {
7801            return;
7802        }
7803
7804        enforceNotIsolatedCaller("publishContentProviders");
7805        synchronized (this) {
7806            final ProcessRecord r = getRecordForAppLocked(caller);
7807            if (DEBUG_MU)
7808                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7809            if (r == null) {
7810                throw new SecurityException(
7811                        "Unable to find app for caller " + caller
7812                      + " (pid=" + Binder.getCallingPid()
7813                      + ") when publishing content providers");
7814            }
7815
7816            final long origId = Binder.clearCallingIdentity();
7817
7818            final int N = providers.size();
7819            for (int i=0; i<N; i++) {
7820                ContentProviderHolder src = providers.get(i);
7821                if (src == null || src.info == null || src.provider == null) {
7822                    continue;
7823                }
7824                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7825                if (DEBUG_MU)
7826                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7827                if (dst != null) {
7828                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7829                    mProviderMap.putProviderByClass(comp, dst);
7830                    String names[] = dst.info.authority.split(";");
7831                    for (int j = 0; j < names.length; j++) {
7832                        mProviderMap.putProviderByName(names[j], dst);
7833                    }
7834
7835                    int NL = mLaunchingProviders.size();
7836                    int j;
7837                    for (j=0; j<NL; j++) {
7838                        if (mLaunchingProviders.get(j) == dst) {
7839                            mLaunchingProviders.remove(j);
7840                            j--;
7841                            NL--;
7842                        }
7843                    }
7844                    synchronized (dst) {
7845                        dst.provider = src.provider;
7846                        dst.proc = r;
7847                        dst.notifyAll();
7848                    }
7849                    updateOomAdjLocked(r);
7850                }
7851            }
7852
7853            Binder.restoreCallingIdentity(origId);
7854        }
7855    }
7856
7857    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7858        ContentProviderConnection conn;
7859        try {
7860            conn = (ContentProviderConnection)connection;
7861        } catch (ClassCastException e) {
7862            String msg ="refContentProvider: " + connection
7863                    + " not a ContentProviderConnection";
7864            Slog.w(TAG, msg);
7865            throw new IllegalArgumentException(msg);
7866        }
7867        if (conn == null) {
7868            throw new NullPointerException("connection is null");
7869        }
7870
7871        synchronized (this) {
7872            if (stable > 0) {
7873                conn.numStableIncs += stable;
7874            }
7875            stable = conn.stableCount + stable;
7876            if (stable < 0) {
7877                throw new IllegalStateException("stableCount < 0: " + stable);
7878            }
7879
7880            if (unstable > 0) {
7881                conn.numUnstableIncs += unstable;
7882            }
7883            unstable = conn.unstableCount + unstable;
7884            if (unstable < 0) {
7885                throw new IllegalStateException("unstableCount < 0: " + unstable);
7886            }
7887
7888            if ((stable+unstable) <= 0) {
7889                throw new IllegalStateException("ref counts can't go to zero here: stable="
7890                        + stable + " unstable=" + unstable);
7891            }
7892            conn.stableCount = stable;
7893            conn.unstableCount = unstable;
7894            return !conn.dead;
7895        }
7896    }
7897
7898    public void unstableProviderDied(IBinder connection) {
7899        ContentProviderConnection conn;
7900        try {
7901            conn = (ContentProviderConnection)connection;
7902        } catch (ClassCastException e) {
7903            String msg ="refContentProvider: " + connection
7904                    + " not a ContentProviderConnection";
7905            Slog.w(TAG, msg);
7906            throw new IllegalArgumentException(msg);
7907        }
7908        if (conn == null) {
7909            throw new NullPointerException("connection is null");
7910        }
7911
7912        // Safely retrieve the content provider associated with the connection.
7913        IContentProvider provider;
7914        synchronized (this) {
7915            provider = conn.provider.provider;
7916        }
7917
7918        if (provider == null) {
7919            // Um, yeah, we're way ahead of you.
7920            return;
7921        }
7922
7923        // Make sure the caller is being honest with us.
7924        if (provider.asBinder().pingBinder()) {
7925            // Er, no, still looks good to us.
7926            synchronized (this) {
7927                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7928                        + " says " + conn + " died, but we don't agree");
7929                return;
7930            }
7931        }
7932
7933        // Well look at that!  It's dead!
7934        synchronized (this) {
7935            if (conn.provider.provider != provider) {
7936                // But something changed...  good enough.
7937                return;
7938            }
7939
7940            ProcessRecord proc = conn.provider.proc;
7941            if (proc == null || proc.thread == null) {
7942                // Seems like the process is already cleaned up.
7943                return;
7944            }
7945
7946            // As far as we're concerned, this is just like receiving a
7947            // death notification...  just a bit prematurely.
7948            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7949                    + ") early provider death");
7950            final long ident = Binder.clearCallingIdentity();
7951            try {
7952                appDiedLocked(proc, proc.pid, proc.thread);
7953            } finally {
7954                Binder.restoreCallingIdentity(ident);
7955            }
7956        }
7957    }
7958
7959    @Override
7960    public void appNotRespondingViaProvider(IBinder connection) {
7961        enforceCallingPermission(
7962                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7963
7964        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7965        if (conn == null) {
7966            Slog.w(TAG, "ContentProviderConnection is null");
7967            return;
7968        }
7969
7970        final ProcessRecord host = conn.provider.proc;
7971        if (host == null) {
7972            Slog.w(TAG, "Failed to find hosting ProcessRecord");
7973            return;
7974        }
7975
7976        final long token = Binder.clearCallingIdentity();
7977        try {
7978            appNotResponding(host, null, null, false, "ContentProvider not responding");
7979        } finally {
7980            Binder.restoreCallingIdentity(token);
7981        }
7982    }
7983
7984    public final void installSystemProviders() {
7985        List<ProviderInfo> providers;
7986        synchronized (this) {
7987            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
7988            providers = generateApplicationProvidersLocked(app);
7989            if (providers != null) {
7990                for (int i=providers.size()-1; i>=0; i--) {
7991                    ProviderInfo pi = (ProviderInfo)providers.get(i);
7992                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7993                        Slog.w(TAG, "Not installing system proc provider " + pi.name
7994                                + ": not system .apk");
7995                        providers.remove(i);
7996                    }
7997                }
7998            }
7999        }
8000        if (providers != null) {
8001            mSystemThread.installSystemProviders(providers);
8002        }
8003
8004        mCoreSettingsObserver = new CoreSettingsObserver(this);
8005
8006        mUsageStatsService.monitorPackages();
8007    }
8008
8009    /**
8010     * Allows app to retrieve the MIME type of a URI without having permission
8011     * to access its content provider.
8012     *
8013     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8014     *
8015     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8016     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8017     */
8018    public String getProviderMimeType(Uri uri, int userId) {
8019        enforceNotIsolatedCaller("getProviderMimeType");
8020        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8021                userId, false, true, "getProviderMimeType", null);
8022        final String name = uri.getAuthority();
8023        final long ident = Binder.clearCallingIdentity();
8024        ContentProviderHolder holder = null;
8025
8026        try {
8027            holder = getContentProviderExternalUnchecked(name, null, userId);
8028            if (holder != null) {
8029                return holder.provider.getType(uri);
8030            }
8031        } catch (RemoteException e) {
8032            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8033            return null;
8034        } finally {
8035            if (holder != null) {
8036                removeContentProviderExternalUnchecked(name, null, userId);
8037            }
8038            Binder.restoreCallingIdentity(ident);
8039        }
8040
8041        return null;
8042    }
8043
8044    // =========================================================
8045    // GLOBAL MANAGEMENT
8046    // =========================================================
8047
8048    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8049            boolean isolated) {
8050        String proc = customProcess != null ? customProcess : info.processName;
8051        BatteryStatsImpl.Uid.Proc ps = null;
8052        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8053        int uid = info.uid;
8054        if (isolated) {
8055            int userId = UserHandle.getUserId(uid);
8056            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8057            while (true) {
8058                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8059                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8060                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8061                }
8062                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8063                mNextIsolatedProcessUid++;
8064                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8065                    // No process for this uid, use it.
8066                    break;
8067                }
8068                stepsLeft--;
8069                if (stepsLeft <= 0) {
8070                    return null;
8071                }
8072            }
8073        }
8074        return new ProcessRecord(stats, info, proc, uid);
8075    }
8076
8077    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8078        ProcessRecord app;
8079        if (!isolated) {
8080            app = getProcessRecordLocked(info.processName, info.uid, true);
8081        } else {
8082            app = null;
8083        }
8084
8085        if (app == null) {
8086            app = newProcessRecordLocked(info, null, isolated);
8087            mProcessNames.put(info.processName, app.uid, app);
8088            if (isolated) {
8089                mIsolatedProcesses.put(app.uid, app);
8090            }
8091            updateLruProcessLocked(app, false, null);
8092            updateOomAdjLocked();
8093        }
8094
8095        // This package really, really can not be stopped.
8096        try {
8097            AppGlobals.getPackageManager().setPackageStoppedState(
8098                    info.packageName, false, UserHandle.getUserId(app.uid));
8099        } catch (RemoteException e) {
8100        } catch (IllegalArgumentException e) {
8101            Slog.w(TAG, "Failed trying to unstop package "
8102                    + info.packageName + ": " + e);
8103        }
8104
8105        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8106                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8107            app.persistent = true;
8108            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8109        }
8110        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8111            mPersistentStartingProcesses.add(app);
8112            startProcessLocked(app, "added application", app.processName);
8113        }
8114
8115        return app;
8116    }
8117
8118    public void unhandledBack() {
8119        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8120                "unhandledBack()");
8121
8122        synchronized(this) {
8123            final long origId = Binder.clearCallingIdentity();
8124            try {
8125                getFocusedStack().unhandledBackLocked();
8126            } finally {
8127                Binder.restoreCallingIdentity(origId);
8128            }
8129        }
8130    }
8131
8132    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8133        enforceNotIsolatedCaller("openContentUri");
8134        final int userId = UserHandle.getCallingUserId();
8135        String name = uri.getAuthority();
8136        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8137        ParcelFileDescriptor pfd = null;
8138        if (cph != null) {
8139            // We record the binder invoker's uid in thread-local storage before
8140            // going to the content provider to open the file.  Later, in the code
8141            // that handles all permissions checks, we look for this uid and use
8142            // that rather than the Activity Manager's own uid.  The effect is that
8143            // we do the check against the caller's permissions even though it looks
8144            // to the content provider like the Activity Manager itself is making
8145            // the request.
8146            sCallerIdentity.set(new Identity(
8147                    Binder.getCallingPid(), Binder.getCallingUid()));
8148            try {
8149                pfd = cph.provider.openFile(null, uri, "r", null);
8150            } catch (FileNotFoundException e) {
8151                // do nothing; pfd will be returned null
8152            } finally {
8153                // Ensure that whatever happens, we clean up the identity state
8154                sCallerIdentity.remove();
8155            }
8156
8157            // We've got the fd now, so we're done with the provider.
8158            removeContentProviderExternalUnchecked(name, null, userId);
8159        } else {
8160            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8161        }
8162        return pfd;
8163    }
8164
8165    // Actually is sleeping or shutting down or whatever else in the future
8166    // is an inactive state.
8167    public boolean isSleepingOrShuttingDown() {
8168        return mSleeping || mShuttingDown;
8169    }
8170
8171    void goingToSleep() {
8172        synchronized(this) {
8173            mWentToSleep = true;
8174            updateEventDispatchingLocked();
8175
8176            if (!mSleeping) {
8177                mSleeping = true;
8178                mStackSupervisor.goingToSleepLocked();
8179
8180                // Initialize the wake times of all processes.
8181                checkExcessivePowerUsageLocked(false);
8182                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8183                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8184                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8185            }
8186        }
8187    }
8188
8189    @Override
8190    public boolean shutdown(int timeout) {
8191        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8192                != PackageManager.PERMISSION_GRANTED) {
8193            throw new SecurityException("Requires permission "
8194                    + android.Manifest.permission.SHUTDOWN);
8195        }
8196
8197        boolean timedout = false;
8198
8199        synchronized(this) {
8200            mShuttingDown = true;
8201            updateEventDispatchingLocked();
8202            timedout = mStackSupervisor.shutdownLocked(timeout);
8203        }
8204
8205        mAppOpsService.shutdown();
8206        mUsageStatsService.shutdown();
8207        mBatteryStatsService.shutdown();
8208        synchronized (this) {
8209            mProcessStats.shutdownLocked();
8210        }
8211
8212        return timedout;
8213    }
8214
8215    public final void activitySlept(IBinder token) {
8216        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8217
8218        final long origId = Binder.clearCallingIdentity();
8219
8220        synchronized (this) {
8221            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8222            if (r != null) {
8223                mStackSupervisor.activitySleptLocked(r);
8224            }
8225        }
8226
8227        Binder.restoreCallingIdentity(origId);
8228    }
8229
8230    void logLockScreen(String msg) {
8231        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8232                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8233                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8234                mStackSupervisor.mDismissKeyguardOnNextActivity);
8235    }
8236
8237    private void comeOutOfSleepIfNeededLocked() {
8238        if (!mWentToSleep && !mLockScreenShown) {
8239            if (mSleeping) {
8240                mSleeping = false;
8241                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8242            }
8243        }
8244    }
8245
8246    void wakingUp() {
8247        synchronized(this) {
8248            mWentToSleep = false;
8249            updateEventDispatchingLocked();
8250            comeOutOfSleepIfNeededLocked();
8251        }
8252    }
8253
8254    private void updateEventDispatchingLocked() {
8255        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8256    }
8257
8258    public void setLockScreenShown(boolean shown) {
8259        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8260                != PackageManager.PERMISSION_GRANTED) {
8261            throw new SecurityException("Requires permission "
8262                    + android.Manifest.permission.DEVICE_POWER);
8263        }
8264
8265        synchronized(this) {
8266            long ident = Binder.clearCallingIdentity();
8267            try {
8268                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8269                mLockScreenShown = shown;
8270                comeOutOfSleepIfNeededLocked();
8271            } finally {
8272                Binder.restoreCallingIdentity(ident);
8273            }
8274        }
8275    }
8276
8277    public void stopAppSwitches() {
8278        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8279                != PackageManager.PERMISSION_GRANTED) {
8280            throw new SecurityException("Requires permission "
8281                    + android.Manifest.permission.STOP_APP_SWITCHES);
8282        }
8283
8284        synchronized(this) {
8285            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8286                    + APP_SWITCH_DELAY_TIME;
8287            mDidAppSwitch = false;
8288            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8289            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8290            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8291        }
8292    }
8293
8294    public void resumeAppSwitches() {
8295        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8296                != PackageManager.PERMISSION_GRANTED) {
8297            throw new SecurityException("Requires permission "
8298                    + android.Manifest.permission.STOP_APP_SWITCHES);
8299        }
8300
8301        synchronized(this) {
8302            // Note that we don't execute any pending app switches... we will
8303            // let those wait until either the timeout, or the next start
8304            // activity request.
8305            mAppSwitchesAllowedTime = 0;
8306        }
8307    }
8308
8309    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8310            String name) {
8311        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8312            return true;
8313        }
8314
8315        final int perm = checkComponentPermission(
8316                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8317                callingUid, -1, true);
8318        if (perm == PackageManager.PERMISSION_GRANTED) {
8319            return true;
8320        }
8321
8322        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8323        return false;
8324    }
8325
8326    public void setDebugApp(String packageName, boolean waitForDebugger,
8327            boolean persistent) {
8328        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8329                "setDebugApp()");
8330
8331        long ident = Binder.clearCallingIdentity();
8332        try {
8333            // Note that this is not really thread safe if there are multiple
8334            // callers into it at the same time, but that's not a situation we
8335            // care about.
8336            if (persistent) {
8337                final ContentResolver resolver = mContext.getContentResolver();
8338                Settings.Global.putString(
8339                    resolver, Settings.Global.DEBUG_APP,
8340                    packageName);
8341                Settings.Global.putInt(
8342                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8343                    waitForDebugger ? 1 : 0);
8344            }
8345
8346            synchronized (this) {
8347                if (!persistent) {
8348                    mOrigDebugApp = mDebugApp;
8349                    mOrigWaitForDebugger = mWaitForDebugger;
8350                }
8351                mDebugApp = packageName;
8352                mWaitForDebugger = waitForDebugger;
8353                mDebugTransient = !persistent;
8354                if (packageName != null) {
8355                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8356                            UserHandle.USER_ALL, "set debug app");
8357                }
8358            }
8359        } finally {
8360            Binder.restoreCallingIdentity(ident);
8361        }
8362    }
8363
8364    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8365        synchronized (this) {
8366            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8367            if (!isDebuggable) {
8368                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8369                    throw new SecurityException("Process not debuggable: " + app.packageName);
8370                }
8371            }
8372
8373            mOpenGlTraceApp = processName;
8374        }
8375    }
8376
8377    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8378            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8379        synchronized (this) {
8380            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8381            if (!isDebuggable) {
8382                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8383                    throw new SecurityException("Process not debuggable: " + app.packageName);
8384                }
8385            }
8386            mProfileApp = processName;
8387            mProfileFile = profileFile;
8388            if (mProfileFd != null) {
8389                try {
8390                    mProfileFd.close();
8391                } catch (IOException e) {
8392                }
8393                mProfileFd = null;
8394            }
8395            mProfileFd = profileFd;
8396            mProfileType = 0;
8397            mAutoStopProfiler = autoStopProfiler;
8398        }
8399    }
8400
8401    @Override
8402    public void setAlwaysFinish(boolean enabled) {
8403        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8404                "setAlwaysFinish()");
8405
8406        Settings.Global.putInt(
8407                mContext.getContentResolver(),
8408                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8409
8410        synchronized (this) {
8411            mAlwaysFinishActivities = enabled;
8412        }
8413    }
8414
8415    @Override
8416    public void setActivityController(IActivityController controller) {
8417        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8418                "setActivityController()");
8419        synchronized (this) {
8420            mController = controller;
8421            Watchdog.getInstance().setActivityController(controller);
8422        }
8423    }
8424
8425    @Override
8426    public void setUserIsMonkey(boolean userIsMonkey) {
8427        synchronized (this) {
8428            synchronized (mPidsSelfLocked) {
8429                final int callingPid = Binder.getCallingPid();
8430                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8431                if (precessRecord == null) {
8432                    throw new SecurityException("Unknown process: " + callingPid);
8433                }
8434                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8435                    throw new SecurityException("Only an instrumentation process "
8436                            + "with a UiAutomation can call setUserIsMonkey");
8437                }
8438            }
8439            mUserIsMonkey = userIsMonkey;
8440        }
8441    }
8442
8443    @Override
8444    public boolean isUserAMonkey() {
8445        synchronized (this) {
8446            // If there is a controller also implies the user is a monkey.
8447            return (mUserIsMonkey || mController != null);
8448        }
8449    }
8450
8451    public void requestBugReport() {
8452        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8453        SystemProperties.set("ctl.start", "bugreport");
8454    }
8455
8456    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8457        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8458    }
8459
8460    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8461        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8462            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8463        }
8464        return KEY_DISPATCHING_TIMEOUT;
8465    }
8466
8467    @Override
8468    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8469        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8470                != PackageManager.PERMISSION_GRANTED) {
8471            throw new SecurityException("Requires permission "
8472                    + android.Manifest.permission.FILTER_EVENTS);
8473        }
8474        ProcessRecord proc;
8475        long timeout;
8476        synchronized (this) {
8477            synchronized (mPidsSelfLocked) {
8478                proc = mPidsSelfLocked.get(pid);
8479            }
8480            timeout = getInputDispatchingTimeoutLocked(proc);
8481        }
8482
8483        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8484            return -1;
8485        }
8486
8487        return timeout;
8488    }
8489
8490    /**
8491     * Handle input dispatching timeouts.
8492     * Returns whether input dispatching should be aborted or not.
8493     */
8494    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8495            final ActivityRecord activity, final ActivityRecord parent,
8496            final boolean aboveSystem, String reason) {
8497        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8498                != PackageManager.PERMISSION_GRANTED) {
8499            throw new SecurityException("Requires permission "
8500                    + android.Manifest.permission.FILTER_EVENTS);
8501        }
8502
8503        final String annotation;
8504        if (reason == null) {
8505            annotation = "Input dispatching timed out";
8506        } else {
8507            annotation = "Input dispatching timed out (" + reason + ")";
8508        }
8509
8510        if (proc != null) {
8511            synchronized (this) {
8512                if (proc.debugging) {
8513                    return false;
8514                }
8515
8516                if (mDidDexOpt) {
8517                    // Give more time since we were dexopting.
8518                    mDidDexOpt = false;
8519                    return false;
8520                }
8521
8522                if (proc.instrumentationClass != null) {
8523                    Bundle info = new Bundle();
8524                    info.putString("shortMsg", "keyDispatchingTimedOut");
8525                    info.putString("longMsg", annotation);
8526                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8527                    return true;
8528                }
8529            }
8530            mHandler.post(new Runnable() {
8531                @Override
8532                public void run() {
8533                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8534                }
8535            });
8536        }
8537
8538        return true;
8539    }
8540
8541    public Bundle getAssistContextExtras(int requestType) {
8542        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8543                "getAssistContextExtras()");
8544        PendingAssistExtras pae;
8545        Bundle extras = new Bundle();
8546        synchronized (this) {
8547            ActivityRecord activity = getFocusedStack().mResumedActivity;
8548            if (activity == null) {
8549                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8550                return null;
8551            }
8552            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8553            if (activity.app == null || activity.app.thread == null) {
8554                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8555                return extras;
8556            }
8557            if (activity.app.pid == Binder.getCallingPid()) {
8558                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8559                return extras;
8560            }
8561            pae = new PendingAssistExtras(activity);
8562            try {
8563                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8564                        requestType);
8565                mPendingAssistExtras.add(pae);
8566                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8567            } catch (RemoteException e) {
8568                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8569                return extras;
8570            }
8571        }
8572        synchronized (pae) {
8573            while (!pae.haveResult) {
8574                try {
8575                    pae.wait();
8576                } catch (InterruptedException e) {
8577                }
8578            }
8579            if (pae.result != null) {
8580                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8581            }
8582        }
8583        synchronized (this) {
8584            mPendingAssistExtras.remove(pae);
8585            mHandler.removeCallbacks(pae);
8586        }
8587        return extras;
8588    }
8589
8590    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8591        PendingAssistExtras pae = (PendingAssistExtras)token;
8592        synchronized (pae) {
8593            pae.result = extras;
8594            pae.haveResult = true;
8595            pae.notifyAll();
8596        }
8597    }
8598
8599    public void registerProcessObserver(IProcessObserver observer) {
8600        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8601                "registerProcessObserver()");
8602        synchronized (this) {
8603            mProcessObservers.register(observer);
8604        }
8605    }
8606
8607    @Override
8608    public void unregisterProcessObserver(IProcessObserver observer) {
8609        synchronized (this) {
8610            mProcessObservers.unregister(observer);
8611        }
8612    }
8613
8614    @Override
8615    public boolean convertFromTranslucent(IBinder token) {
8616        final long origId = Binder.clearCallingIdentity();
8617        try {
8618            synchronized (this) {
8619                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8620                if (r == null) {
8621                    return false;
8622                }
8623                if (r.changeWindowTranslucency(true)) {
8624                    mWindowManager.setAppFullscreen(token, true);
8625                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8626                    return true;
8627                }
8628                return false;
8629            }
8630        } finally {
8631            Binder.restoreCallingIdentity(origId);
8632        }
8633    }
8634
8635    @Override
8636    public boolean convertToTranslucent(IBinder token) {
8637        final long origId = Binder.clearCallingIdentity();
8638        try {
8639            synchronized (this) {
8640                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8641                if (r == null) {
8642                    return false;
8643                }
8644                if (r.changeWindowTranslucency(false)) {
8645                    r.task.stack.convertToTranslucent(r);
8646                    mWindowManager.setAppFullscreen(token, false);
8647                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8648                    return true;
8649                }
8650                return false;
8651            }
8652        } finally {
8653            Binder.restoreCallingIdentity(origId);
8654        }
8655    }
8656
8657    @Override
8658    public void setImmersive(IBinder token, boolean immersive) {
8659        synchronized(this) {
8660            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8661            if (r == null) {
8662                throw new IllegalArgumentException();
8663            }
8664            r.immersive = immersive;
8665
8666            // update associated state if we're frontmost
8667            if (r == mFocusedActivity) {
8668                if (DEBUG_IMMERSIVE) {
8669                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8670                }
8671                applyUpdateLockStateLocked(r);
8672            }
8673        }
8674    }
8675
8676    @Override
8677    public boolean isImmersive(IBinder token) {
8678        synchronized (this) {
8679            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8680            if (r == null) {
8681                throw new IllegalArgumentException();
8682            }
8683            return r.immersive;
8684        }
8685    }
8686
8687    public boolean isTopActivityImmersive() {
8688        enforceNotIsolatedCaller("startActivity");
8689        synchronized (this) {
8690            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8691            return (r != null) ? r.immersive : false;
8692        }
8693    }
8694
8695    public final void enterSafeMode() {
8696        synchronized(this) {
8697            // It only makes sense to do this before the system is ready
8698            // and started launching other packages.
8699            if (!mSystemReady) {
8700                try {
8701                    AppGlobals.getPackageManager().enterSafeMode();
8702                } catch (RemoteException e) {
8703                }
8704            }
8705        }
8706    }
8707
8708    public final void showSafeModeOverlay() {
8709        View v = LayoutInflater.from(mContext).inflate(
8710                com.android.internal.R.layout.safe_mode, null);
8711        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8712        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8713        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8714        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8715        lp.gravity = Gravity.BOTTOM | Gravity.START;
8716        lp.format = v.getBackground().getOpacity();
8717        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8718                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8719        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8720        ((WindowManager)mContext.getSystemService(
8721                Context.WINDOW_SERVICE)).addView(v, lp);
8722    }
8723
8724    public void noteWakeupAlarm(IIntentSender sender) {
8725        if (!(sender instanceof PendingIntentRecord)) {
8726            return;
8727        }
8728        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8729        synchronized (stats) {
8730            if (mBatteryStatsService.isOnBattery()) {
8731                mBatteryStatsService.enforceCallingPermission();
8732                PendingIntentRecord rec = (PendingIntentRecord)sender;
8733                int MY_UID = Binder.getCallingUid();
8734                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8735                BatteryStatsImpl.Uid.Pkg pkg =
8736                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8737                pkg.incWakeupsLocked();
8738            }
8739        }
8740    }
8741
8742    public boolean killPids(int[] pids, String pReason, boolean secure) {
8743        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8744            throw new SecurityException("killPids only available to the system");
8745        }
8746        String reason = (pReason == null) ? "Unknown" : pReason;
8747        // XXX Note: don't acquire main activity lock here, because the window
8748        // manager calls in with its locks held.
8749
8750        boolean killed = false;
8751        synchronized (mPidsSelfLocked) {
8752            int[] types = new int[pids.length];
8753            int worstType = 0;
8754            for (int i=0; i<pids.length; i++) {
8755                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8756                if (proc != null) {
8757                    int type = proc.setAdj;
8758                    types[i] = type;
8759                    if (type > worstType) {
8760                        worstType = type;
8761                    }
8762                }
8763            }
8764
8765            // If the worst oom_adj is somewhere in the cached proc LRU range,
8766            // then constrain it so we will kill all cached procs.
8767            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8768                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8769                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8770            }
8771
8772            // If this is not a secure call, don't let it kill processes that
8773            // are important.
8774            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8775                worstType = ProcessList.SERVICE_ADJ;
8776            }
8777
8778            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8779            for (int i=0; i<pids.length; i++) {
8780                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8781                if (proc == null) {
8782                    continue;
8783                }
8784                int adj = proc.setAdj;
8785                if (adj >= worstType && !proc.killedByAm) {
8786                    killUnneededProcessLocked(proc, reason);
8787                    killed = true;
8788                }
8789            }
8790        }
8791        return killed;
8792    }
8793
8794    @Override
8795    public void killUid(int uid, String reason) {
8796        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8797            throw new SecurityException("killUid only available to the system");
8798        }
8799        synchronized (this) {
8800            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8801                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8802                    reason != null ? reason : "kill uid");
8803        }
8804    }
8805
8806    @Override
8807    public boolean killProcessesBelowForeground(String reason) {
8808        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8809            throw new SecurityException("killProcessesBelowForeground() only available to system");
8810        }
8811
8812        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8813    }
8814
8815    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8816        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8817            throw new SecurityException("killProcessesBelowAdj() only available to system");
8818        }
8819
8820        boolean killed = false;
8821        synchronized (mPidsSelfLocked) {
8822            final int size = mPidsSelfLocked.size();
8823            for (int i = 0; i < size; i++) {
8824                final int pid = mPidsSelfLocked.keyAt(i);
8825                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8826                if (proc == null) continue;
8827
8828                final int adj = proc.setAdj;
8829                if (adj > belowAdj && !proc.killedByAm) {
8830                    killUnneededProcessLocked(proc, reason);
8831                    killed = true;
8832                }
8833            }
8834        }
8835        return killed;
8836    }
8837
8838    @Override
8839    public void hang(final IBinder who, boolean allowRestart) {
8840        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8841                != PackageManager.PERMISSION_GRANTED) {
8842            throw new SecurityException("Requires permission "
8843                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8844        }
8845
8846        final IBinder.DeathRecipient death = new DeathRecipient() {
8847            @Override
8848            public void binderDied() {
8849                synchronized (this) {
8850                    notifyAll();
8851                }
8852            }
8853        };
8854
8855        try {
8856            who.linkToDeath(death, 0);
8857        } catch (RemoteException e) {
8858            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8859            return;
8860        }
8861
8862        synchronized (this) {
8863            Watchdog.getInstance().setAllowRestart(allowRestart);
8864            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8865            synchronized (death) {
8866                while (who.isBinderAlive()) {
8867                    try {
8868                        death.wait();
8869                    } catch (InterruptedException e) {
8870                    }
8871                }
8872            }
8873            Watchdog.getInstance().setAllowRestart(true);
8874        }
8875    }
8876
8877    @Override
8878    public void restart() {
8879        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8880                != PackageManager.PERMISSION_GRANTED) {
8881            throw new SecurityException("Requires permission "
8882                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8883        }
8884
8885        Log.i(TAG, "Sending shutdown broadcast...");
8886
8887        BroadcastReceiver br = new BroadcastReceiver() {
8888            @Override public void onReceive(Context context, Intent intent) {
8889                // Now the broadcast is done, finish up the low-level shutdown.
8890                Log.i(TAG, "Shutting down activity manager...");
8891                shutdown(10000);
8892                Log.i(TAG, "Shutdown complete, restarting!");
8893                Process.killProcess(Process.myPid());
8894                System.exit(10);
8895            }
8896        };
8897
8898        // First send the high-level shut down broadcast.
8899        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8900        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8901        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8902        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8903        mContext.sendOrderedBroadcastAsUser(intent,
8904                UserHandle.ALL, null, br, mHandler, 0, null, null);
8905        */
8906        br.onReceive(mContext, intent);
8907    }
8908
8909    private long getLowRamTimeSinceIdle(long now) {
8910        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8911    }
8912
8913    @Override
8914    public void performIdleMaintenance() {
8915        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8916                != PackageManager.PERMISSION_GRANTED) {
8917            throw new SecurityException("Requires permission "
8918                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8919        }
8920
8921        synchronized (this) {
8922            final long now = SystemClock.uptimeMillis();
8923            final long timeSinceLastIdle = now - mLastIdleTime;
8924            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8925            mLastIdleTime = now;
8926            mLowRamTimeSinceLastIdle = 0;
8927            if (mLowRamStartTime != 0) {
8928                mLowRamStartTime = now;
8929            }
8930
8931            StringBuilder sb = new StringBuilder(128);
8932            sb.append("Idle maintenance over ");
8933            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8934            sb.append(" low RAM for ");
8935            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8936            Slog.i(TAG, sb.toString());
8937
8938            // If at least 1/3 of our time since the last idle period has been spent
8939            // with RAM low, then we want to kill processes.
8940            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8941
8942            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8943                ProcessRecord proc = mLruProcesses.get(i);
8944                if (proc.notCachedSinceIdle) {
8945                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8946                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8947                        if (doKilling && proc.initialIdlePss != 0
8948                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8949                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8950                                    + " from " + proc.initialIdlePss + ")");
8951                        }
8952                    }
8953                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8954                    proc.notCachedSinceIdle = true;
8955                    proc.initialIdlePss = 0;
8956                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8957                            mSleeping, now);
8958                }
8959            }
8960
8961            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8962            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8963        }
8964    }
8965
8966    private void retrieveSettings() {
8967        final ContentResolver resolver = mContext.getContentResolver();
8968        String debugApp = Settings.Global.getString(
8969            resolver, Settings.Global.DEBUG_APP);
8970        boolean waitForDebugger = Settings.Global.getInt(
8971            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
8972        boolean alwaysFinishActivities = Settings.Global.getInt(
8973            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
8974        boolean forceRtl = Settings.Global.getInt(
8975                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
8976        // Transfer any global setting for forcing RTL layout, into a System Property
8977        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
8978
8979        Configuration configuration = new Configuration();
8980        Settings.System.getConfiguration(resolver, configuration);
8981        if (forceRtl) {
8982            // This will take care of setting the correct layout direction flags
8983            configuration.setLayoutDirection(configuration.locale);
8984        }
8985
8986        synchronized (this) {
8987            mDebugApp = mOrigDebugApp = debugApp;
8988            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
8989            mAlwaysFinishActivities = alwaysFinishActivities;
8990            // This happens before any activities are started, so we can
8991            // change mConfiguration in-place.
8992            updateConfigurationLocked(configuration, null, false, true);
8993            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
8994        }
8995    }
8996
8997    public boolean testIsSystemReady() {
8998        // no need to synchronize(this) just to read & return the value
8999        return mSystemReady;
9000    }
9001
9002    private static File getCalledPreBootReceiversFile() {
9003        File dataDir = Environment.getDataDirectory();
9004        File systemDir = new File(dataDir, "system");
9005        File fname = new File(systemDir, "called_pre_boots.dat");
9006        return fname;
9007    }
9008
9009    static final int LAST_DONE_VERSION = 10000;
9010
9011    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9012        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9013        File file = getCalledPreBootReceiversFile();
9014        FileInputStream fis = null;
9015        try {
9016            fis = new FileInputStream(file);
9017            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9018            int fvers = dis.readInt();
9019            if (fvers == LAST_DONE_VERSION) {
9020                String vers = dis.readUTF();
9021                String codename = dis.readUTF();
9022                String build = dis.readUTF();
9023                if (android.os.Build.VERSION.RELEASE.equals(vers)
9024                        && android.os.Build.VERSION.CODENAME.equals(codename)
9025                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9026                    int num = dis.readInt();
9027                    while (num > 0) {
9028                        num--;
9029                        String pkg = dis.readUTF();
9030                        String cls = dis.readUTF();
9031                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9032                    }
9033                }
9034            }
9035        } catch (FileNotFoundException e) {
9036        } catch (IOException e) {
9037            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9038        } finally {
9039            if (fis != null) {
9040                try {
9041                    fis.close();
9042                } catch (IOException e) {
9043                }
9044            }
9045        }
9046        return lastDoneReceivers;
9047    }
9048
9049    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9050        File file = getCalledPreBootReceiversFile();
9051        FileOutputStream fos = null;
9052        DataOutputStream dos = null;
9053        try {
9054            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9055            fos = new FileOutputStream(file);
9056            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9057            dos.writeInt(LAST_DONE_VERSION);
9058            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9059            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9060            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9061            dos.writeInt(list.size());
9062            for (int i=0; i<list.size(); i++) {
9063                dos.writeUTF(list.get(i).getPackageName());
9064                dos.writeUTF(list.get(i).getClassName());
9065            }
9066        } catch (IOException e) {
9067            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9068            file.delete();
9069        } finally {
9070            FileUtils.sync(fos);
9071            if (dos != null) {
9072                try {
9073                    dos.close();
9074                } catch (IOException e) {
9075                    // TODO Auto-generated catch block
9076                    e.printStackTrace();
9077                }
9078            }
9079        }
9080    }
9081
9082    public void systemReady(final Runnable goingCallback) {
9083        synchronized(this) {
9084            if (mSystemReady) {
9085                if (goingCallback != null) goingCallback.run();
9086                return;
9087            }
9088
9089            // Check to see if there are any update receivers to run.
9090            if (!mDidUpdate) {
9091                if (mWaitingUpdate) {
9092                    return;
9093                }
9094                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9095                List<ResolveInfo> ris = null;
9096                try {
9097                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9098                            intent, null, 0, 0);
9099                } catch (RemoteException e) {
9100                }
9101                if (ris != null) {
9102                    for (int i=ris.size()-1; i>=0; i--) {
9103                        if ((ris.get(i).activityInfo.applicationInfo.flags
9104                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9105                            ris.remove(i);
9106                        }
9107                    }
9108                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9109
9110                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9111
9112                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9113                    for (int i=0; i<ris.size(); i++) {
9114                        ActivityInfo ai = ris.get(i).activityInfo;
9115                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9116                        if (lastDoneReceivers.contains(comp)) {
9117                            // We already did the pre boot receiver for this app with the current
9118                            // platform version, so don't do it again...
9119                            ris.remove(i);
9120                            i--;
9121                            // ...however, do keep it as one that has been done, so we don't
9122                            // forget about it when rewriting the file of last done receivers.
9123                            doneReceivers.add(comp);
9124                        }
9125                    }
9126
9127                    final int[] users = getUsersLocked();
9128                    for (int i=0; i<ris.size(); i++) {
9129                        ActivityInfo ai = ris.get(i).activityInfo;
9130                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9131                        doneReceivers.add(comp);
9132                        intent.setComponent(comp);
9133                        for (int j=0; j<users.length; j++) {
9134                            IIntentReceiver finisher = null;
9135                            if (i == ris.size()-1 && j == users.length-1) {
9136                                finisher = new IIntentReceiver.Stub() {
9137                                    public void performReceive(Intent intent, int resultCode,
9138                                            String data, Bundle extras, boolean ordered,
9139                                            boolean sticky, int sendingUser) {
9140                                        // The raw IIntentReceiver interface is called
9141                                        // with the AM lock held, so redispatch to
9142                                        // execute our code without the lock.
9143                                        mHandler.post(new Runnable() {
9144                                            public void run() {
9145                                                synchronized (ActivityManagerService.this) {
9146                                                    mDidUpdate = true;
9147                                                }
9148                                                writeLastDonePreBootReceivers(doneReceivers);
9149                                                showBootMessage(mContext.getText(
9150                                                        R.string.android_upgrading_complete),
9151                                                        false);
9152                                                systemReady(goingCallback);
9153                                            }
9154                                        });
9155                                    }
9156                                };
9157                            }
9158                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9159                                    + " for user " + users[j]);
9160                            broadcastIntentLocked(null, null, intent, null, finisher,
9161                                    0, null, null, null, AppOpsManager.OP_NONE,
9162                                    true, false, MY_PID, Process.SYSTEM_UID,
9163                                    users[j]);
9164                            if (finisher != null) {
9165                                mWaitingUpdate = true;
9166                            }
9167                        }
9168                    }
9169                }
9170                if (mWaitingUpdate) {
9171                    return;
9172                }
9173                mDidUpdate = true;
9174            }
9175
9176            mAppOpsService.systemReady();
9177            mSystemReady = true;
9178        }
9179
9180        ArrayList<ProcessRecord> procsToKill = null;
9181        synchronized(mPidsSelfLocked) {
9182            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9183                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9184                if (!isAllowedWhileBooting(proc.info)){
9185                    if (procsToKill == null) {
9186                        procsToKill = new ArrayList<ProcessRecord>();
9187                    }
9188                    procsToKill.add(proc);
9189                }
9190            }
9191        }
9192
9193        synchronized(this) {
9194            if (procsToKill != null) {
9195                for (int i=procsToKill.size()-1; i>=0; i--) {
9196                    ProcessRecord proc = procsToKill.get(i);
9197                    Slog.i(TAG, "Removing system update proc: " + proc);
9198                    removeProcessLocked(proc, true, false, "system update done");
9199                }
9200            }
9201
9202            // Now that we have cleaned up any update processes, we
9203            // are ready to start launching real processes and know that
9204            // we won't trample on them any more.
9205            mProcessesReady = true;
9206        }
9207
9208        Slog.i(TAG, "System now ready");
9209        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9210            SystemClock.uptimeMillis());
9211
9212        synchronized(this) {
9213            // Make sure we have no pre-ready processes sitting around.
9214
9215            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9216                ResolveInfo ri = mContext.getPackageManager()
9217                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9218                                STOCK_PM_FLAGS);
9219                CharSequence errorMsg = null;
9220                if (ri != null) {
9221                    ActivityInfo ai = ri.activityInfo;
9222                    ApplicationInfo app = ai.applicationInfo;
9223                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9224                        mTopAction = Intent.ACTION_FACTORY_TEST;
9225                        mTopData = null;
9226                        mTopComponent = new ComponentName(app.packageName,
9227                                ai.name);
9228                    } else {
9229                        errorMsg = mContext.getResources().getText(
9230                                com.android.internal.R.string.factorytest_not_system);
9231                    }
9232                } else {
9233                    errorMsg = mContext.getResources().getText(
9234                            com.android.internal.R.string.factorytest_no_action);
9235                }
9236                if (errorMsg != null) {
9237                    mTopAction = null;
9238                    mTopData = null;
9239                    mTopComponent = null;
9240                    Message msg = Message.obtain();
9241                    msg.what = SHOW_FACTORY_ERROR_MSG;
9242                    msg.getData().putCharSequence("msg", errorMsg);
9243                    mHandler.sendMessage(msg);
9244                }
9245            }
9246        }
9247
9248        retrieveSettings();
9249
9250        synchronized (this) {
9251            readGrantedUriPermissionsLocked();
9252        }
9253
9254        if (goingCallback != null) goingCallback.run();
9255
9256        synchronized (this) {
9257            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9258                try {
9259                    List apps = AppGlobals.getPackageManager().
9260                        getPersistentApplications(STOCK_PM_FLAGS);
9261                    if (apps != null) {
9262                        int N = apps.size();
9263                        int i;
9264                        for (i=0; i<N; i++) {
9265                            ApplicationInfo info
9266                                = (ApplicationInfo)apps.get(i);
9267                            if (info != null &&
9268                                    !info.packageName.equals("android")) {
9269                                addAppLocked(info, false);
9270                            }
9271                        }
9272                    }
9273                } catch (RemoteException ex) {
9274                    // pm is in same process, this will never happen.
9275                }
9276            }
9277
9278            // Start up initial activity.
9279            mBooting = true;
9280
9281            try {
9282                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9283                    Message msg = Message.obtain();
9284                    msg.what = SHOW_UID_ERROR_MSG;
9285                    mHandler.sendMessage(msg);
9286                }
9287            } catch (RemoteException e) {
9288            }
9289
9290            long ident = Binder.clearCallingIdentity();
9291            try {
9292                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9293                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9294                        | Intent.FLAG_RECEIVER_FOREGROUND);
9295                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9296                broadcastIntentLocked(null, null, intent,
9297                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9298                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9299                intent = new Intent(Intent.ACTION_USER_STARTING);
9300                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9301                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9302                broadcastIntentLocked(null, null, intent,
9303                        null, new IIntentReceiver.Stub() {
9304                            @Override
9305                            public void performReceive(Intent intent, int resultCode, String data,
9306                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9307                                    throws RemoteException {
9308                            }
9309                        }, 0, null, null,
9310                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9311                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9312            } finally {
9313                Binder.restoreCallingIdentity(ident);
9314            }
9315            mStackSupervisor.resumeTopActivitiesLocked();
9316            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9317        }
9318    }
9319
9320    private boolean makeAppCrashingLocked(ProcessRecord app,
9321            String shortMsg, String longMsg, String stackTrace) {
9322        app.crashing = true;
9323        app.crashingReport = generateProcessError(app,
9324                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9325        startAppProblemLocked(app);
9326        app.stopFreezingAllLocked();
9327        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9328    }
9329
9330    private void makeAppNotRespondingLocked(ProcessRecord app,
9331            String activity, String shortMsg, String longMsg) {
9332        app.notResponding = true;
9333        app.notRespondingReport = generateProcessError(app,
9334                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9335                activity, shortMsg, longMsg, null);
9336        startAppProblemLocked(app);
9337        app.stopFreezingAllLocked();
9338    }
9339
9340    /**
9341     * Generate a process error record, suitable for attachment to a ProcessRecord.
9342     *
9343     * @param app The ProcessRecord in which the error occurred.
9344     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9345     *                      ActivityManager.AppErrorStateInfo
9346     * @param activity The activity associated with the crash, if known.
9347     * @param shortMsg Short message describing the crash.
9348     * @param longMsg Long message describing the crash.
9349     * @param stackTrace Full crash stack trace, may be null.
9350     *
9351     * @return Returns a fully-formed AppErrorStateInfo record.
9352     */
9353    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9354            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9355        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9356
9357        report.condition = condition;
9358        report.processName = app.processName;
9359        report.pid = app.pid;
9360        report.uid = app.info.uid;
9361        report.tag = activity;
9362        report.shortMsg = shortMsg;
9363        report.longMsg = longMsg;
9364        report.stackTrace = stackTrace;
9365
9366        return report;
9367    }
9368
9369    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9370        synchronized (this) {
9371            app.crashing = false;
9372            app.crashingReport = null;
9373            app.notResponding = false;
9374            app.notRespondingReport = null;
9375            if (app.anrDialog == fromDialog) {
9376                app.anrDialog = null;
9377            }
9378            if (app.waitDialog == fromDialog) {
9379                app.waitDialog = null;
9380            }
9381            if (app.pid > 0 && app.pid != MY_PID) {
9382                handleAppCrashLocked(app, null, null, null);
9383                killUnneededProcessLocked(app, "user request after error");
9384            }
9385        }
9386    }
9387
9388    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9389            String stackTrace) {
9390        long now = SystemClock.uptimeMillis();
9391
9392        Long crashTime;
9393        if (!app.isolated) {
9394            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9395        } else {
9396            crashTime = null;
9397        }
9398        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9399            // This process loses!
9400            Slog.w(TAG, "Process " + app.info.processName
9401                    + " has crashed too many times: killing!");
9402            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9403                    app.userId, app.info.processName, app.uid);
9404            mStackSupervisor.handleAppCrashLocked(app);
9405            if (!app.persistent) {
9406                // We don't want to start this process again until the user
9407                // explicitly does so...  but for persistent process, we really
9408                // need to keep it running.  If a persistent process is actually
9409                // repeatedly crashing, then badness for everyone.
9410                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9411                        app.info.processName);
9412                if (!app.isolated) {
9413                    // XXX We don't have a way to mark isolated processes
9414                    // as bad, since they don't have a peristent identity.
9415                    mBadProcesses.put(app.info.processName, app.uid,
9416                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9417                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9418                }
9419                app.bad = true;
9420                app.removed = true;
9421                // Don't let services in this process be restarted and potentially
9422                // annoy the user repeatedly.  Unless it is persistent, since those
9423                // processes run critical code.
9424                removeProcessLocked(app, false, false, "crash");
9425                mStackSupervisor.resumeTopActivitiesLocked();
9426                return false;
9427            }
9428            mStackSupervisor.resumeTopActivitiesLocked();
9429        } else {
9430            mStackSupervisor.finishTopRunningActivityLocked(app);
9431        }
9432
9433        // Bump up the crash count of any services currently running in the proc.
9434        for (int i=app.services.size()-1; i>=0; i--) {
9435            // Any services running in the application need to be placed
9436            // back in the pending list.
9437            ServiceRecord sr = app.services.valueAt(i);
9438            sr.crashCount++;
9439        }
9440
9441        // If the crashing process is what we consider to be the "home process" and it has been
9442        // replaced by a third-party app, clear the package preferred activities from packages
9443        // with a home activity running in the process to prevent a repeatedly crashing app
9444        // from blocking the user to manually clear the list.
9445        final ArrayList<ActivityRecord> activities = app.activities;
9446        if (app == mHomeProcess && activities.size() > 0
9447                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9448            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9449                final ActivityRecord r = activities.get(activityNdx);
9450                if (r.isHomeActivity()) {
9451                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9452                    try {
9453                        ActivityThread.getPackageManager()
9454                                .clearPackagePreferredActivities(r.packageName);
9455                    } catch (RemoteException c) {
9456                        // pm is in same process, this will never happen.
9457                    }
9458                }
9459            }
9460        }
9461
9462        if (!app.isolated) {
9463            // XXX Can't keep track of crash times for isolated processes,
9464            // because they don't have a perisistent identity.
9465            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9466        }
9467
9468        return true;
9469    }
9470
9471    void startAppProblemLocked(ProcessRecord app) {
9472        if (app.userId == mCurrentUserId) {
9473            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9474                    mContext, app.info.packageName, app.info.flags);
9475        } else {
9476            // If this app is not running under the current user, then we
9477            // can't give it a report button because that would require
9478            // launching the report UI under a different user.
9479            app.errorReportReceiver = null;
9480        }
9481        skipCurrentReceiverLocked(app);
9482    }
9483
9484    void skipCurrentReceiverLocked(ProcessRecord app) {
9485        for (BroadcastQueue queue : mBroadcastQueues) {
9486            queue.skipCurrentReceiverLocked(app);
9487        }
9488    }
9489
9490    /**
9491     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9492     * The application process will exit immediately after this call returns.
9493     * @param app object of the crashing app, null for the system server
9494     * @param crashInfo describing the exception
9495     */
9496    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9497        ProcessRecord r = findAppProcess(app, "Crash");
9498        final String processName = app == null ? "system_server"
9499                : (r == null ? "unknown" : r.processName);
9500
9501        handleApplicationCrashInner("crash", r, processName, crashInfo);
9502    }
9503
9504    /* Native crash reporting uses this inner version because it needs to be somewhat
9505     * decoupled from the AM-managed cleanup lifecycle
9506     */
9507    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9508            ApplicationErrorReport.CrashInfo crashInfo) {
9509        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9510                UserHandle.getUserId(Binder.getCallingUid()), processName,
9511                r == null ? -1 : r.info.flags,
9512                crashInfo.exceptionClassName,
9513                crashInfo.exceptionMessage,
9514                crashInfo.throwFileName,
9515                crashInfo.throwLineNumber);
9516
9517        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9518
9519        crashApplication(r, crashInfo);
9520    }
9521
9522    public void handleApplicationStrictModeViolation(
9523            IBinder app,
9524            int violationMask,
9525            StrictMode.ViolationInfo info) {
9526        ProcessRecord r = findAppProcess(app, "StrictMode");
9527        if (r == null) {
9528            return;
9529        }
9530
9531        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9532            Integer stackFingerprint = info.hashCode();
9533            boolean logIt = true;
9534            synchronized (mAlreadyLoggedViolatedStacks) {
9535                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9536                    logIt = false;
9537                    // TODO: sub-sample into EventLog for these, with
9538                    // the info.durationMillis?  Then we'd get
9539                    // the relative pain numbers, without logging all
9540                    // the stack traces repeatedly.  We'd want to do
9541                    // likewise in the client code, which also does
9542                    // dup suppression, before the Binder call.
9543                } else {
9544                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9545                        mAlreadyLoggedViolatedStacks.clear();
9546                    }
9547                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9548                }
9549            }
9550            if (logIt) {
9551                logStrictModeViolationToDropBox(r, info);
9552            }
9553        }
9554
9555        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9556            AppErrorResult result = new AppErrorResult();
9557            synchronized (this) {
9558                final long origId = Binder.clearCallingIdentity();
9559
9560                Message msg = Message.obtain();
9561                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9562                HashMap<String, Object> data = new HashMap<String, Object>();
9563                data.put("result", result);
9564                data.put("app", r);
9565                data.put("violationMask", violationMask);
9566                data.put("info", info);
9567                msg.obj = data;
9568                mHandler.sendMessage(msg);
9569
9570                Binder.restoreCallingIdentity(origId);
9571            }
9572            int res = result.get();
9573            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9574        }
9575    }
9576
9577    // Depending on the policy in effect, there could be a bunch of
9578    // these in quick succession so we try to batch these together to
9579    // minimize disk writes, number of dropbox entries, and maximize
9580    // compression, by having more fewer, larger records.
9581    private void logStrictModeViolationToDropBox(
9582            ProcessRecord process,
9583            StrictMode.ViolationInfo info) {
9584        if (info == null) {
9585            return;
9586        }
9587        final boolean isSystemApp = process == null ||
9588                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9589                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9590        final String processName = process == null ? "unknown" : process.processName;
9591        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9592        final DropBoxManager dbox = (DropBoxManager)
9593                mContext.getSystemService(Context.DROPBOX_SERVICE);
9594
9595        // Exit early if the dropbox isn't configured to accept this report type.
9596        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9597
9598        boolean bufferWasEmpty;
9599        boolean needsFlush;
9600        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9601        synchronized (sb) {
9602            bufferWasEmpty = sb.length() == 0;
9603            appendDropBoxProcessHeaders(process, processName, sb);
9604            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9605            sb.append("System-App: ").append(isSystemApp).append("\n");
9606            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9607            if (info.violationNumThisLoop != 0) {
9608                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9609            }
9610            if (info.numAnimationsRunning != 0) {
9611                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9612            }
9613            if (info.broadcastIntentAction != null) {
9614                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9615            }
9616            if (info.durationMillis != -1) {
9617                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9618            }
9619            if (info.numInstances != -1) {
9620                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9621            }
9622            if (info.tags != null) {
9623                for (String tag : info.tags) {
9624                    sb.append("Span-Tag: ").append(tag).append("\n");
9625                }
9626            }
9627            sb.append("\n");
9628            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9629                sb.append(info.crashInfo.stackTrace);
9630            }
9631            sb.append("\n");
9632
9633            // Only buffer up to ~64k.  Various logging bits truncate
9634            // things at 128k.
9635            needsFlush = (sb.length() > 64 * 1024);
9636        }
9637
9638        // Flush immediately if the buffer's grown too large, or this
9639        // is a non-system app.  Non-system apps are isolated with a
9640        // different tag & policy and not batched.
9641        //
9642        // Batching is useful during internal testing with
9643        // StrictMode settings turned up high.  Without batching,
9644        // thousands of separate files could be created on boot.
9645        if (!isSystemApp || needsFlush) {
9646            new Thread("Error dump: " + dropboxTag) {
9647                @Override
9648                public void run() {
9649                    String report;
9650                    synchronized (sb) {
9651                        report = sb.toString();
9652                        sb.delete(0, sb.length());
9653                        sb.trimToSize();
9654                    }
9655                    if (report.length() != 0) {
9656                        dbox.addText(dropboxTag, report);
9657                    }
9658                }
9659            }.start();
9660            return;
9661        }
9662
9663        // System app batching:
9664        if (!bufferWasEmpty) {
9665            // An existing dropbox-writing thread is outstanding, so
9666            // we don't need to start it up.  The existing thread will
9667            // catch the buffer appends we just did.
9668            return;
9669        }
9670
9671        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9672        // (After this point, we shouldn't access AMS internal data structures.)
9673        new Thread("Error dump: " + dropboxTag) {
9674            @Override
9675            public void run() {
9676                // 5 second sleep to let stacks arrive and be batched together
9677                try {
9678                    Thread.sleep(5000);  // 5 seconds
9679                } catch (InterruptedException e) {}
9680
9681                String errorReport;
9682                synchronized (mStrictModeBuffer) {
9683                    errorReport = mStrictModeBuffer.toString();
9684                    if (errorReport.length() == 0) {
9685                        return;
9686                    }
9687                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9688                    mStrictModeBuffer.trimToSize();
9689                }
9690                dbox.addText(dropboxTag, errorReport);
9691            }
9692        }.start();
9693    }
9694
9695    /**
9696     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9697     * @param app object of the crashing app, null for the system server
9698     * @param tag reported by the caller
9699     * @param crashInfo describing the context of the error
9700     * @return true if the process should exit immediately (WTF is fatal)
9701     */
9702    public boolean handleApplicationWtf(IBinder app, String tag,
9703            ApplicationErrorReport.CrashInfo crashInfo) {
9704        ProcessRecord r = findAppProcess(app, "WTF");
9705        final String processName = app == null ? "system_server"
9706                : (r == null ? "unknown" : r.processName);
9707
9708        EventLog.writeEvent(EventLogTags.AM_WTF,
9709                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9710                processName,
9711                r == null ? -1 : r.info.flags,
9712                tag, crashInfo.exceptionMessage);
9713
9714        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9715
9716        if (r != null && r.pid != Process.myPid() &&
9717                Settings.Global.getInt(mContext.getContentResolver(),
9718                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9719            crashApplication(r, crashInfo);
9720            return true;
9721        } else {
9722            return false;
9723        }
9724    }
9725
9726    /**
9727     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9728     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9729     */
9730    private ProcessRecord findAppProcess(IBinder app, String reason) {
9731        if (app == null) {
9732            return null;
9733        }
9734
9735        synchronized (this) {
9736            final int NP = mProcessNames.getMap().size();
9737            for (int ip=0; ip<NP; ip++) {
9738                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9739                final int NA = apps.size();
9740                for (int ia=0; ia<NA; ia++) {
9741                    ProcessRecord p = apps.valueAt(ia);
9742                    if (p.thread != null && p.thread.asBinder() == app) {
9743                        return p;
9744                    }
9745                }
9746            }
9747
9748            Slog.w(TAG, "Can't find mystery application for " + reason
9749                    + " from pid=" + Binder.getCallingPid()
9750                    + " uid=" + Binder.getCallingUid() + ": " + app);
9751            return null;
9752        }
9753    }
9754
9755    /**
9756     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9757     * to append various headers to the dropbox log text.
9758     */
9759    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9760            StringBuilder sb) {
9761        // Watchdog thread ends up invoking this function (with
9762        // a null ProcessRecord) to add the stack file to dropbox.
9763        // Do not acquire a lock on this (am) in such cases, as it
9764        // could cause a potential deadlock, if and when watchdog
9765        // is invoked due to unavailability of lock on am and it
9766        // would prevent watchdog from killing system_server.
9767        if (process == null) {
9768            sb.append("Process: ").append(processName).append("\n");
9769            return;
9770        }
9771        // Note: ProcessRecord 'process' is guarded by the service
9772        // instance.  (notably process.pkgList, which could otherwise change
9773        // concurrently during execution of this method)
9774        synchronized (this) {
9775            sb.append("Process: ").append(processName).append("\n");
9776            int flags = process.info.flags;
9777            IPackageManager pm = AppGlobals.getPackageManager();
9778            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9779            for (int ip=0; ip<process.pkgList.size(); ip++) {
9780                String pkg = process.pkgList.keyAt(ip);
9781                sb.append("Package: ").append(pkg);
9782                try {
9783                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9784                    if (pi != null) {
9785                        sb.append(" v").append(pi.versionCode);
9786                        if (pi.versionName != null) {
9787                            sb.append(" (").append(pi.versionName).append(")");
9788                        }
9789                    }
9790                } catch (RemoteException e) {
9791                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9792                }
9793                sb.append("\n");
9794            }
9795        }
9796    }
9797
9798    private static String processClass(ProcessRecord process) {
9799        if (process == null || process.pid == MY_PID) {
9800            return "system_server";
9801        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9802            return "system_app";
9803        } else {
9804            return "data_app";
9805        }
9806    }
9807
9808    /**
9809     * Write a description of an error (crash, WTF, ANR) to the drop box.
9810     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9811     * @param process which caused the error, null means the system server
9812     * @param activity which triggered the error, null if unknown
9813     * @param parent activity related to the error, null if unknown
9814     * @param subject line related to the error, null if absent
9815     * @param report in long form describing the error, null if absent
9816     * @param logFile to include in the report, null if none
9817     * @param crashInfo giving an application stack trace, null if absent
9818     */
9819    public void addErrorToDropBox(String eventType,
9820            ProcessRecord process, String processName, ActivityRecord activity,
9821            ActivityRecord parent, String subject,
9822            final String report, final File logFile,
9823            final ApplicationErrorReport.CrashInfo crashInfo) {
9824        // NOTE -- this must never acquire the ActivityManagerService lock,
9825        // otherwise the watchdog may be prevented from resetting the system.
9826
9827        final String dropboxTag = processClass(process) + "_" + eventType;
9828        final DropBoxManager dbox = (DropBoxManager)
9829                mContext.getSystemService(Context.DROPBOX_SERVICE);
9830
9831        // Exit early if the dropbox isn't configured to accept this report type.
9832        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9833
9834        final StringBuilder sb = new StringBuilder(1024);
9835        appendDropBoxProcessHeaders(process, processName, sb);
9836        if (activity != null) {
9837            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9838        }
9839        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9840            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9841        }
9842        if (parent != null && parent != activity) {
9843            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9844        }
9845        if (subject != null) {
9846            sb.append("Subject: ").append(subject).append("\n");
9847        }
9848        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9849        if (Debug.isDebuggerConnected()) {
9850            sb.append("Debugger: Connected\n");
9851        }
9852        sb.append("\n");
9853
9854        // Do the rest in a worker thread to avoid blocking the caller on I/O
9855        // (After this point, we shouldn't access AMS internal data structures.)
9856        Thread worker = new Thread("Error dump: " + dropboxTag) {
9857            @Override
9858            public void run() {
9859                if (report != null) {
9860                    sb.append(report);
9861                }
9862                if (logFile != null) {
9863                    try {
9864                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9865                                    "\n\n[[TRUNCATED]]"));
9866                    } catch (IOException e) {
9867                        Slog.e(TAG, "Error reading " + logFile, e);
9868                    }
9869                }
9870                if (crashInfo != null && crashInfo.stackTrace != null) {
9871                    sb.append(crashInfo.stackTrace);
9872                }
9873
9874                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9875                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9876                if (lines > 0) {
9877                    sb.append("\n");
9878
9879                    // Merge several logcat streams, and take the last N lines
9880                    InputStreamReader input = null;
9881                    try {
9882                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9883                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9884                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9885
9886                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9887                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9888                        input = new InputStreamReader(logcat.getInputStream());
9889
9890                        int num;
9891                        char[] buf = new char[8192];
9892                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9893                    } catch (IOException e) {
9894                        Slog.e(TAG, "Error running logcat", e);
9895                    } finally {
9896                        if (input != null) try { input.close(); } catch (IOException e) {}
9897                    }
9898                }
9899
9900                dbox.addText(dropboxTag, sb.toString());
9901            }
9902        };
9903
9904        if (process == null) {
9905            // If process is null, we are being called from some internal code
9906            // and may be about to die -- run this synchronously.
9907            worker.run();
9908        } else {
9909            worker.start();
9910        }
9911    }
9912
9913    /**
9914     * Bring up the "unexpected error" dialog box for a crashing app.
9915     * Deal with edge cases (intercepts from instrumented applications,
9916     * ActivityController, error intent receivers, that sort of thing).
9917     * @param r the application crashing
9918     * @param crashInfo describing the failure
9919     */
9920    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9921        long timeMillis = System.currentTimeMillis();
9922        String shortMsg = crashInfo.exceptionClassName;
9923        String longMsg = crashInfo.exceptionMessage;
9924        String stackTrace = crashInfo.stackTrace;
9925        if (shortMsg != null && longMsg != null) {
9926            longMsg = shortMsg + ": " + longMsg;
9927        } else if (shortMsg != null) {
9928            longMsg = shortMsg;
9929        }
9930
9931        AppErrorResult result = new AppErrorResult();
9932        synchronized (this) {
9933            if (mController != null) {
9934                try {
9935                    String name = r != null ? r.processName : null;
9936                    int pid = r != null ? r.pid : Binder.getCallingPid();
9937                    if (!mController.appCrashed(name, pid,
9938                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9939                        Slog.w(TAG, "Force-killing crashed app " + name
9940                                + " at watcher's request");
9941                        Process.killProcess(pid);
9942                        return;
9943                    }
9944                } catch (RemoteException e) {
9945                    mController = null;
9946                    Watchdog.getInstance().setActivityController(null);
9947                }
9948            }
9949
9950            final long origId = Binder.clearCallingIdentity();
9951
9952            // If this process is running instrumentation, finish it.
9953            if (r != null && r.instrumentationClass != null) {
9954                Slog.w(TAG, "Error in app " + r.processName
9955                      + " running instrumentation " + r.instrumentationClass + ":");
9956                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
9957                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
9958                Bundle info = new Bundle();
9959                info.putString("shortMsg", shortMsg);
9960                info.putString("longMsg", longMsg);
9961                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
9962                Binder.restoreCallingIdentity(origId);
9963                return;
9964            }
9965
9966            // If we can't identify the process or it's already exceeded its crash quota,
9967            // quit right away without showing a crash dialog.
9968            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
9969                Binder.restoreCallingIdentity(origId);
9970                return;
9971            }
9972
9973            Message msg = Message.obtain();
9974            msg.what = SHOW_ERROR_MSG;
9975            HashMap data = new HashMap();
9976            data.put("result", result);
9977            data.put("app", r);
9978            msg.obj = data;
9979            mHandler.sendMessage(msg);
9980
9981            Binder.restoreCallingIdentity(origId);
9982        }
9983
9984        int res = result.get();
9985
9986        Intent appErrorIntent = null;
9987        synchronized (this) {
9988            if (r != null && !r.isolated) {
9989                // XXX Can't keep track of crash time for isolated processes,
9990                // since they don't have a persistent identity.
9991                mProcessCrashTimes.put(r.info.processName, r.uid,
9992                        SystemClock.uptimeMillis());
9993            }
9994            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
9995                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
9996            }
9997        }
9998
9999        if (appErrorIntent != null) {
10000            try {
10001                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10002            } catch (ActivityNotFoundException e) {
10003                Slog.w(TAG, "bug report receiver dissappeared", e);
10004            }
10005        }
10006    }
10007
10008    Intent createAppErrorIntentLocked(ProcessRecord r,
10009            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10010        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10011        if (report == null) {
10012            return null;
10013        }
10014        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10015        result.setComponent(r.errorReportReceiver);
10016        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10017        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10018        return result;
10019    }
10020
10021    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10022            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10023        if (r.errorReportReceiver == null) {
10024            return null;
10025        }
10026
10027        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10028            return null;
10029        }
10030
10031        ApplicationErrorReport report = new ApplicationErrorReport();
10032        report.packageName = r.info.packageName;
10033        report.installerPackageName = r.errorReportReceiver.getPackageName();
10034        report.processName = r.processName;
10035        report.time = timeMillis;
10036        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10037
10038        if (r.crashing || r.forceCrashReport) {
10039            report.type = ApplicationErrorReport.TYPE_CRASH;
10040            report.crashInfo = crashInfo;
10041        } else if (r.notResponding) {
10042            report.type = ApplicationErrorReport.TYPE_ANR;
10043            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10044
10045            report.anrInfo.activity = r.notRespondingReport.tag;
10046            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10047            report.anrInfo.info = r.notRespondingReport.longMsg;
10048        }
10049
10050        return report;
10051    }
10052
10053    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10054        enforceNotIsolatedCaller("getProcessesInErrorState");
10055        // assume our apps are happy - lazy create the list
10056        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10057
10058        final boolean allUsers = ActivityManager.checkUidPermission(
10059                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10060                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10061        int userId = UserHandle.getUserId(Binder.getCallingUid());
10062
10063        synchronized (this) {
10064
10065            // iterate across all processes
10066            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10067                ProcessRecord app = mLruProcesses.get(i);
10068                if (!allUsers && app.userId != userId) {
10069                    continue;
10070                }
10071                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10072                    // This one's in trouble, so we'll generate a report for it
10073                    // crashes are higher priority (in case there's a crash *and* an anr)
10074                    ActivityManager.ProcessErrorStateInfo report = null;
10075                    if (app.crashing) {
10076                        report = app.crashingReport;
10077                    } else if (app.notResponding) {
10078                        report = app.notRespondingReport;
10079                    }
10080
10081                    if (report != null) {
10082                        if (errList == null) {
10083                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10084                        }
10085                        errList.add(report);
10086                    } else {
10087                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10088                                " crashing = " + app.crashing +
10089                                " notResponding = " + app.notResponding);
10090                    }
10091                }
10092            }
10093        }
10094
10095        return errList;
10096    }
10097
10098    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10099        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10100            if (currApp != null) {
10101                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10102            }
10103            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10104        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10105            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10106        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10107            if (currApp != null) {
10108                currApp.lru = 0;
10109            }
10110            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10111        } else if (adj >= ProcessList.SERVICE_ADJ) {
10112            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10113        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10114            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10115        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10116            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10117        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10118            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10119        } else {
10120            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10121        }
10122    }
10123
10124    private void fillInProcMemInfo(ProcessRecord app,
10125            ActivityManager.RunningAppProcessInfo outInfo) {
10126        outInfo.pid = app.pid;
10127        outInfo.uid = app.info.uid;
10128        if (mHeavyWeightProcess == app) {
10129            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10130        }
10131        if (app.persistent) {
10132            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10133        }
10134        if (app.activities.size() > 0) {
10135            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10136        }
10137        outInfo.lastTrimLevel = app.trimMemoryLevel;
10138        int adj = app.curAdj;
10139        outInfo.importance = oomAdjToImportance(adj, outInfo);
10140        outInfo.importanceReasonCode = app.adjTypeCode;
10141    }
10142
10143    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10144        enforceNotIsolatedCaller("getRunningAppProcesses");
10145        // Lazy instantiation of list
10146        List<ActivityManager.RunningAppProcessInfo> runList = null;
10147        final boolean allUsers = ActivityManager.checkUidPermission(
10148                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10149                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10150        int userId = UserHandle.getUserId(Binder.getCallingUid());
10151        synchronized (this) {
10152            // Iterate across all processes
10153            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10154                ProcessRecord app = mLruProcesses.get(i);
10155                if (!allUsers && app.userId != userId) {
10156                    continue;
10157                }
10158                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10159                    // Generate process state info for running application
10160                    ActivityManager.RunningAppProcessInfo currApp =
10161                        new ActivityManager.RunningAppProcessInfo(app.processName,
10162                                app.pid, app.getPackageList());
10163                    fillInProcMemInfo(app, currApp);
10164                    if (app.adjSource instanceof ProcessRecord) {
10165                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10166                        currApp.importanceReasonImportance = oomAdjToImportance(
10167                                app.adjSourceOom, null);
10168                    } else if (app.adjSource instanceof ActivityRecord) {
10169                        ActivityRecord r = (ActivityRecord)app.adjSource;
10170                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10171                    }
10172                    if (app.adjTarget instanceof ComponentName) {
10173                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10174                    }
10175                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10176                    //        + " lru=" + currApp.lru);
10177                    if (runList == null) {
10178                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10179                    }
10180                    runList.add(currApp);
10181                }
10182            }
10183        }
10184        return runList;
10185    }
10186
10187    public List<ApplicationInfo> getRunningExternalApplications() {
10188        enforceNotIsolatedCaller("getRunningExternalApplications");
10189        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10190        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10191        if (runningApps != null && runningApps.size() > 0) {
10192            Set<String> extList = new HashSet<String>();
10193            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10194                if (app.pkgList != null) {
10195                    for (String pkg : app.pkgList) {
10196                        extList.add(pkg);
10197                    }
10198                }
10199            }
10200            IPackageManager pm = AppGlobals.getPackageManager();
10201            for (String pkg : extList) {
10202                try {
10203                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10204                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10205                        retList.add(info);
10206                    }
10207                } catch (RemoteException e) {
10208                }
10209            }
10210        }
10211        return retList;
10212    }
10213
10214    @Override
10215    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10216        enforceNotIsolatedCaller("getMyMemoryState");
10217        synchronized (this) {
10218            ProcessRecord proc;
10219            synchronized (mPidsSelfLocked) {
10220                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10221            }
10222            fillInProcMemInfo(proc, outInfo);
10223        }
10224    }
10225
10226    @Override
10227    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10228        if (checkCallingPermission(android.Manifest.permission.DUMP)
10229                != PackageManager.PERMISSION_GRANTED) {
10230            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10231                    + Binder.getCallingPid()
10232                    + ", uid=" + Binder.getCallingUid()
10233                    + " without permission "
10234                    + android.Manifest.permission.DUMP);
10235            return;
10236        }
10237
10238        boolean dumpAll = false;
10239        boolean dumpClient = false;
10240        String dumpPackage = null;
10241
10242        int opti = 0;
10243        while (opti < args.length) {
10244            String opt = args[opti];
10245            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10246                break;
10247            }
10248            opti++;
10249            if ("-a".equals(opt)) {
10250                dumpAll = true;
10251            } else if ("-c".equals(opt)) {
10252                dumpClient = true;
10253            } else if ("-h".equals(opt)) {
10254                pw.println("Activity manager dump options:");
10255                pw.println("  [-a] [-c] [-h] [cmd] ...");
10256                pw.println("  cmd may be one of:");
10257                pw.println("    a[ctivities]: activity stack state");
10258                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10259                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10260                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10261                pw.println("    o[om]: out of memory management");
10262                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10263                pw.println("    provider [COMP_SPEC]: provider client-side state");
10264                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10265                pw.println("    service [COMP_SPEC]: service client-side state");
10266                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10267                pw.println("    all: dump all activities");
10268                pw.println("    top: dump the top activity");
10269                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10270                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10271                pw.println("    a partial substring in a component name, a");
10272                pw.println("    hex object identifier.");
10273                pw.println("  -a: include all available server state.");
10274                pw.println("  -c: include client state.");
10275                return;
10276            } else {
10277                pw.println("Unknown argument: " + opt + "; use -h for help");
10278            }
10279        }
10280
10281        long origId = Binder.clearCallingIdentity();
10282        boolean more = false;
10283        // Is the caller requesting to dump a particular piece of data?
10284        if (opti < args.length) {
10285            String cmd = args[opti];
10286            opti++;
10287            if ("activities".equals(cmd) || "a".equals(cmd)) {
10288                synchronized (this) {
10289                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10290                }
10291            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10292                String[] newArgs;
10293                String name;
10294                if (opti >= args.length) {
10295                    name = null;
10296                    newArgs = EMPTY_STRING_ARRAY;
10297                } else {
10298                    name = args[opti];
10299                    opti++;
10300                    newArgs = new String[args.length - opti];
10301                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10302                            args.length - opti);
10303                }
10304                synchronized (this) {
10305                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10306                }
10307            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10308                String[] newArgs;
10309                String name;
10310                if (opti >= args.length) {
10311                    name = null;
10312                    newArgs = EMPTY_STRING_ARRAY;
10313                } else {
10314                    name = args[opti];
10315                    opti++;
10316                    newArgs = new String[args.length - opti];
10317                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10318                            args.length - opti);
10319                }
10320                synchronized (this) {
10321                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10322                }
10323            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10324                String[] newArgs;
10325                String name;
10326                if (opti >= args.length) {
10327                    name = null;
10328                    newArgs = EMPTY_STRING_ARRAY;
10329                } else {
10330                    name = args[opti];
10331                    opti++;
10332                    newArgs = new String[args.length - opti];
10333                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10334                            args.length - opti);
10335                }
10336                synchronized (this) {
10337                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10338                }
10339            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10340                synchronized (this) {
10341                    dumpOomLocked(fd, pw, args, opti, true);
10342                }
10343            } else if ("provider".equals(cmd)) {
10344                String[] newArgs;
10345                String name;
10346                if (opti >= args.length) {
10347                    name = null;
10348                    newArgs = EMPTY_STRING_ARRAY;
10349                } else {
10350                    name = args[opti];
10351                    opti++;
10352                    newArgs = new String[args.length - opti];
10353                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10354                }
10355                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10356                    pw.println("No providers match: " + name);
10357                    pw.println("Use -h for help.");
10358                }
10359            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10360                synchronized (this) {
10361                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10362                }
10363            } else if ("service".equals(cmd)) {
10364                String[] newArgs;
10365                String name;
10366                if (opti >= args.length) {
10367                    name = null;
10368                    newArgs = EMPTY_STRING_ARRAY;
10369                } else {
10370                    name = args[opti];
10371                    opti++;
10372                    newArgs = new String[args.length - opti];
10373                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10374                            args.length - opti);
10375                }
10376                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10377                    pw.println("No services match: " + name);
10378                    pw.println("Use -h for help.");
10379                }
10380            } else if ("package".equals(cmd)) {
10381                String[] newArgs;
10382                if (opti >= args.length) {
10383                    pw.println("package: no package name specified");
10384                    pw.println("Use -h for help.");
10385                } else {
10386                    dumpPackage = args[opti];
10387                    opti++;
10388                    newArgs = new String[args.length - opti];
10389                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10390                            args.length - opti);
10391                    args = newArgs;
10392                    opti = 0;
10393                    more = true;
10394                }
10395            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10396                synchronized (this) {
10397                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10398                }
10399            } else {
10400                // Dumping a single activity?
10401                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10402                    pw.println("Bad activity command, or no activities match: " + cmd);
10403                    pw.println("Use -h for help.");
10404                }
10405            }
10406            if (!more) {
10407                Binder.restoreCallingIdentity(origId);
10408                return;
10409            }
10410        }
10411
10412        // No piece of data specified, dump everything.
10413        synchronized (this) {
10414            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10415            pw.println();
10416            if (dumpAll) {
10417                pw.println("-------------------------------------------------------------------------------");
10418            }
10419            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10420            pw.println();
10421            if (dumpAll) {
10422                pw.println("-------------------------------------------------------------------------------");
10423            }
10424            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10425            pw.println();
10426            if (dumpAll) {
10427                pw.println("-------------------------------------------------------------------------------");
10428            }
10429            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10430            pw.println();
10431            if (dumpAll) {
10432                pw.println("-------------------------------------------------------------------------------");
10433            }
10434            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10435            pw.println();
10436            if (dumpAll) {
10437                pw.println("-------------------------------------------------------------------------------");
10438            }
10439            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10440        }
10441        Binder.restoreCallingIdentity(origId);
10442    }
10443
10444    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10445            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10446        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10447
10448        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10449                dumpPackage);
10450        boolean needSep = printedAnything;
10451
10452        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10453                dumpPackage, needSep, "  mFocusedActivity: ");
10454        if (printed) {
10455            printedAnything = true;
10456            needSep = false;
10457        }
10458
10459        if (dumpPackage == null) {
10460            if (needSep) {
10461                pw.println();
10462            }
10463            needSep = true;
10464            printedAnything = true;
10465            mStackSupervisor.dump(pw, "  ");
10466        }
10467
10468        if (mRecentTasks.size() > 0) {
10469            boolean printedHeader = false;
10470
10471            final int N = mRecentTasks.size();
10472            for (int i=0; i<N; i++) {
10473                TaskRecord tr = mRecentTasks.get(i);
10474                if (dumpPackage != null) {
10475                    if (tr.realActivity == null ||
10476                            !dumpPackage.equals(tr.realActivity)) {
10477                        continue;
10478                    }
10479                }
10480                if (!printedHeader) {
10481                    if (needSep) {
10482                        pw.println();
10483                    }
10484                    pw.println("  Recent tasks:");
10485                    printedHeader = true;
10486                    printedAnything = true;
10487                }
10488                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10489                        pw.println(tr);
10490                if (dumpAll) {
10491                    mRecentTasks.get(i).dump(pw, "    ");
10492                }
10493            }
10494        }
10495
10496        if (!printedAnything) {
10497            pw.println("  (nothing)");
10498        }
10499    }
10500
10501    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10502            int opti, boolean dumpAll, String dumpPackage) {
10503        boolean needSep = false;
10504        boolean printedAnything = false;
10505        int numPers = 0;
10506
10507        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10508
10509        if (dumpAll) {
10510            final int NP = mProcessNames.getMap().size();
10511            for (int ip=0; ip<NP; ip++) {
10512                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10513                final int NA = procs.size();
10514                for (int ia=0; ia<NA; ia++) {
10515                    ProcessRecord r = procs.valueAt(ia);
10516                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10517                        continue;
10518                    }
10519                    if (!needSep) {
10520                        pw.println("  All known processes:");
10521                        needSep = true;
10522                        printedAnything = true;
10523                    }
10524                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10525                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10526                        pw.print(" "); pw.println(r);
10527                    r.dump(pw, "    ");
10528                    if (r.persistent) {
10529                        numPers++;
10530                    }
10531                }
10532            }
10533        }
10534
10535        if (mIsolatedProcesses.size() > 0) {
10536            boolean printed = false;
10537            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10538                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10539                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10540                    continue;
10541                }
10542                if (!printed) {
10543                    if (needSep) {
10544                        pw.println();
10545                    }
10546                    pw.println("  Isolated process list (sorted by uid):");
10547                    printedAnything = true;
10548                    printed = true;
10549                    needSep = true;
10550                }
10551                pw.println(String.format("%sIsolated #%2d: %s",
10552                        "    ", i, r.toString()));
10553            }
10554        }
10555
10556        if (mLruProcesses.size() > 0) {
10557            if (needSep) {
10558                pw.println();
10559            }
10560            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10561                    pw.print(" total, non-act at ");
10562                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10563                    pw.print(", non-svc at ");
10564                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10565                    pw.println("):");
10566            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10567            needSep = true;
10568            printedAnything = true;
10569        }
10570
10571        if (dumpAll || dumpPackage != null) {
10572            synchronized (mPidsSelfLocked) {
10573                boolean printed = false;
10574                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10575                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10576                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10577                        continue;
10578                    }
10579                    if (!printed) {
10580                        if (needSep) pw.println();
10581                        needSep = true;
10582                        pw.println("  PID mappings:");
10583                        printed = true;
10584                        printedAnything = true;
10585                    }
10586                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10587                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10588                }
10589            }
10590        }
10591
10592        if (mForegroundProcesses.size() > 0) {
10593            synchronized (mPidsSelfLocked) {
10594                boolean printed = false;
10595                for (int i=0; i<mForegroundProcesses.size(); i++) {
10596                    ProcessRecord r = mPidsSelfLocked.get(
10597                            mForegroundProcesses.valueAt(i).pid);
10598                    if (dumpPackage != null && (r == null
10599                            || !r.pkgList.containsKey(dumpPackage))) {
10600                        continue;
10601                    }
10602                    if (!printed) {
10603                        if (needSep) pw.println();
10604                        needSep = true;
10605                        pw.println("  Foreground Processes:");
10606                        printed = true;
10607                        printedAnything = true;
10608                    }
10609                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10610                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10611                }
10612            }
10613        }
10614
10615        if (mPersistentStartingProcesses.size() > 0) {
10616            if (needSep) pw.println();
10617            needSep = true;
10618            printedAnything = true;
10619            pw.println("  Persisent processes that are starting:");
10620            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10621                    "Starting Norm", "Restarting PERS", dumpPackage);
10622        }
10623
10624        if (mRemovedProcesses.size() > 0) {
10625            if (needSep) pw.println();
10626            needSep = true;
10627            printedAnything = true;
10628            pw.println("  Processes that are being removed:");
10629            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10630                    "Removed Norm", "Removed PERS", dumpPackage);
10631        }
10632
10633        if (mProcessesOnHold.size() > 0) {
10634            if (needSep) pw.println();
10635            needSep = true;
10636            printedAnything = true;
10637            pw.println("  Processes that are on old until the system is ready:");
10638            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10639                    "OnHold Norm", "OnHold PERS", dumpPackage);
10640        }
10641
10642        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10643
10644        if (mProcessCrashTimes.getMap().size() > 0) {
10645            boolean printed = false;
10646            long now = SystemClock.uptimeMillis();
10647            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10648            final int NP = pmap.size();
10649            for (int ip=0; ip<NP; ip++) {
10650                String pname = pmap.keyAt(ip);
10651                SparseArray<Long> uids = pmap.valueAt(ip);
10652                final int N = uids.size();
10653                for (int i=0; i<N; i++) {
10654                    int puid = uids.keyAt(i);
10655                    ProcessRecord r = mProcessNames.get(pname, puid);
10656                    if (dumpPackage != null && (r == null
10657                            || !r.pkgList.containsKey(dumpPackage))) {
10658                        continue;
10659                    }
10660                    if (!printed) {
10661                        if (needSep) pw.println();
10662                        needSep = true;
10663                        pw.println("  Time since processes crashed:");
10664                        printed = true;
10665                        printedAnything = true;
10666                    }
10667                    pw.print("    Process "); pw.print(pname);
10668                            pw.print(" uid "); pw.print(puid);
10669                            pw.print(": last crashed ");
10670                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10671                            pw.println(" ago");
10672                }
10673            }
10674        }
10675
10676        if (mBadProcesses.getMap().size() > 0) {
10677            boolean printed = false;
10678            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10679            final int NP = pmap.size();
10680            for (int ip=0; ip<NP; ip++) {
10681                String pname = pmap.keyAt(ip);
10682                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10683                final int N = uids.size();
10684                for (int i=0; i<N; i++) {
10685                    int puid = uids.keyAt(i);
10686                    ProcessRecord r = mProcessNames.get(pname, puid);
10687                    if (dumpPackage != null && (r == null
10688                            || !r.pkgList.containsKey(dumpPackage))) {
10689                        continue;
10690                    }
10691                    if (!printed) {
10692                        if (needSep) pw.println();
10693                        needSep = true;
10694                        pw.println("  Bad processes:");
10695                        printedAnything = true;
10696                    }
10697                    BadProcessInfo info = uids.valueAt(i);
10698                    pw.print("    Bad process "); pw.print(pname);
10699                            pw.print(" uid "); pw.print(puid);
10700                            pw.print(": crashed at time "); pw.println(info.time);
10701                    if (info.shortMsg != null) {
10702                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10703                    }
10704                    if (info.longMsg != null) {
10705                        pw.print("      Long msg: "); pw.println(info.longMsg);
10706                    }
10707                    if (info.stack != null) {
10708                        pw.println("      Stack:");
10709                        int lastPos = 0;
10710                        for (int pos=0; pos<info.stack.length(); pos++) {
10711                            if (info.stack.charAt(pos) == '\n') {
10712                                pw.print("        ");
10713                                pw.write(info.stack, lastPos, pos-lastPos);
10714                                pw.println();
10715                                lastPos = pos+1;
10716                            }
10717                        }
10718                        if (lastPos < info.stack.length()) {
10719                            pw.print("        ");
10720                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10721                            pw.println();
10722                        }
10723                    }
10724                }
10725            }
10726        }
10727
10728        if (dumpPackage == null) {
10729            pw.println();
10730            needSep = false;
10731            pw.println("  mStartedUsers:");
10732            for (int i=0; i<mStartedUsers.size(); i++) {
10733                UserStartedState uss = mStartedUsers.valueAt(i);
10734                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10735                        pw.print(": "); uss.dump("", pw);
10736            }
10737            pw.print("  mStartedUserArray: [");
10738            for (int i=0; i<mStartedUserArray.length; i++) {
10739                if (i > 0) pw.print(", ");
10740                pw.print(mStartedUserArray[i]);
10741            }
10742            pw.println("]");
10743            pw.print("  mUserLru: [");
10744            for (int i=0; i<mUserLru.size(); i++) {
10745                if (i > 0) pw.print(", ");
10746                pw.print(mUserLru.get(i));
10747            }
10748            pw.println("]");
10749            if (dumpAll) {
10750                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10751            }
10752        }
10753        if (mHomeProcess != null && (dumpPackage == null
10754                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10755            if (needSep) {
10756                pw.println();
10757                needSep = false;
10758            }
10759            pw.println("  mHomeProcess: " + mHomeProcess);
10760        }
10761        if (mPreviousProcess != null && (dumpPackage == null
10762                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10763            if (needSep) {
10764                pw.println();
10765                needSep = false;
10766            }
10767            pw.println("  mPreviousProcess: " + mPreviousProcess);
10768        }
10769        if (dumpAll) {
10770            StringBuilder sb = new StringBuilder(128);
10771            sb.append("  mPreviousProcessVisibleTime: ");
10772            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10773            pw.println(sb);
10774        }
10775        if (mHeavyWeightProcess != null && (dumpPackage == null
10776                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10777            if (needSep) {
10778                pw.println();
10779                needSep = false;
10780            }
10781            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10782        }
10783        if (dumpPackage == null) {
10784            pw.println("  mConfiguration: " + mConfiguration);
10785        }
10786        if (dumpAll) {
10787            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10788            if (mCompatModePackages.getPackages().size() > 0) {
10789                boolean printed = false;
10790                for (Map.Entry<String, Integer> entry
10791                        : mCompatModePackages.getPackages().entrySet()) {
10792                    String pkg = entry.getKey();
10793                    int mode = entry.getValue();
10794                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10795                        continue;
10796                    }
10797                    if (!printed) {
10798                        pw.println("  mScreenCompatPackages:");
10799                        printed = true;
10800                    }
10801                    pw.print("    "); pw.print(pkg); pw.print(": ");
10802                            pw.print(mode); pw.println();
10803                }
10804            }
10805        }
10806        if (dumpPackage == null) {
10807            if (mSleeping || mWentToSleep || mLockScreenShown) {
10808                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10809                        + " mLockScreenShown " + mLockScreenShown);
10810            }
10811            if (mShuttingDown) {
10812                pw.println("  mShuttingDown=" + mShuttingDown);
10813            }
10814        }
10815        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10816                || mOrigWaitForDebugger) {
10817            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10818                    || dumpPackage.equals(mOrigDebugApp)) {
10819                if (needSep) {
10820                    pw.println();
10821                    needSep = false;
10822                }
10823                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10824                        + " mDebugTransient=" + mDebugTransient
10825                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10826            }
10827        }
10828        if (mOpenGlTraceApp != null) {
10829            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10830                if (needSep) {
10831                    pw.println();
10832                    needSep = false;
10833                }
10834                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10835            }
10836        }
10837        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10838                || mProfileFd != null) {
10839            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10840                if (needSep) {
10841                    pw.println();
10842                    needSep = false;
10843                }
10844                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10845                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10846                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10847                        + mAutoStopProfiler);
10848            }
10849        }
10850        if (dumpPackage == null) {
10851            if (mAlwaysFinishActivities || mController != null) {
10852                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10853                        + " mController=" + mController);
10854            }
10855            if (dumpAll) {
10856                pw.println("  Total persistent processes: " + numPers);
10857                pw.println("  mProcessesReady=" + mProcessesReady
10858                        + " mSystemReady=" + mSystemReady);
10859                pw.println("  mBooting=" + mBooting
10860                        + " mBooted=" + mBooted
10861                        + " mFactoryTest=" + mFactoryTest);
10862                pw.print("  mLastPowerCheckRealtime=");
10863                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10864                        pw.println("");
10865                pw.print("  mLastPowerCheckUptime=");
10866                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10867                        pw.println("");
10868                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10869                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10870                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10871                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10872                        + " (" + mLruProcesses.size() + " total)"
10873                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10874                        + " mNumServiceProcs=" + mNumServiceProcs
10875                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10876                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10877                        + " mLastMemoryLevel" + mLastMemoryLevel
10878                        + " mLastNumProcesses" + mLastNumProcesses);
10879                long now = SystemClock.uptimeMillis();
10880                pw.print("  mLastIdleTime=");
10881                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10882                        pw.print(" mLowRamSinceLastIdle=");
10883                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10884                        pw.println();
10885            }
10886        }
10887
10888        if (!printedAnything) {
10889            pw.println("  (nothing)");
10890        }
10891    }
10892
10893    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10894            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10895        if (mProcessesToGc.size() > 0) {
10896            boolean printed = false;
10897            long now = SystemClock.uptimeMillis();
10898            for (int i=0; i<mProcessesToGc.size(); i++) {
10899                ProcessRecord proc = mProcessesToGc.get(i);
10900                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10901                    continue;
10902                }
10903                if (!printed) {
10904                    if (needSep) pw.println();
10905                    needSep = true;
10906                    pw.println("  Processes that are waiting to GC:");
10907                    printed = true;
10908                }
10909                pw.print("    Process "); pw.println(proc);
10910                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10911                        pw.print(", last gced=");
10912                        pw.print(now-proc.lastRequestedGc);
10913                        pw.print(" ms ago, last lowMem=");
10914                        pw.print(now-proc.lastLowMemory);
10915                        pw.println(" ms ago");
10916
10917            }
10918        }
10919        return needSep;
10920    }
10921
10922    void printOomLevel(PrintWriter pw, String name, int adj) {
10923        pw.print("    ");
10924        if (adj >= 0) {
10925            pw.print(' ');
10926            if (adj < 10) pw.print(' ');
10927        } else {
10928            if (adj > -10) pw.print(' ');
10929        }
10930        pw.print(adj);
10931        pw.print(": ");
10932        pw.print(name);
10933        pw.print(" (");
10934        pw.print(mProcessList.getMemLevel(adj)/1024);
10935        pw.println(" kB)");
10936    }
10937
10938    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10939            int opti, boolean dumpAll) {
10940        boolean needSep = false;
10941
10942        if (mLruProcesses.size() > 0) {
10943            if (needSep) pw.println();
10944            needSep = true;
10945            pw.println("  OOM levels:");
10946            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10947            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10948            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10949            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10950            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10951            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10952            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10953            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10954            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
10955            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
10956            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
10957            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
10958            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
10959
10960            if (needSep) pw.println();
10961            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
10962                    pw.print(" total, non-act at ");
10963                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10964                    pw.print(", non-svc at ");
10965                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10966                    pw.println("):");
10967            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
10968            needSep = true;
10969        }
10970
10971        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
10972
10973        pw.println();
10974        pw.println("  mHomeProcess: " + mHomeProcess);
10975        pw.println("  mPreviousProcess: " + mPreviousProcess);
10976        if (mHeavyWeightProcess != null) {
10977            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10978        }
10979
10980        return true;
10981    }
10982
10983    /**
10984     * There are three ways to call this:
10985     *  - no provider specified: dump all the providers
10986     *  - a flattened component name that matched an existing provider was specified as the
10987     *    first arg: dump that one provider
10988     *  - the first arg isn't the flattened component name of an existing provider:
10989     *    dump all providers whose component contains the first arg as a substring
10990     */
10991    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
10992            int opti, boolean dumpAll) {
10993        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
10994    }
10995
10996    static class ItemMatcher {
10997        ArrayList<ComponentName> components;
10998        ArrayList<String> strings;
10999        ArrayList<Integer> objects;
11000        boolean all;
11001
11002        ItemMatcher() {
11003            all = true;
11004        }
11005
11006        void build(String name) {
11007            ComponentName componentName = ComponentName.unflattenFromString(name);
11008            if (componentName != null) {
11009                if (components == null) {
11010                    components = new ArrayList<ComponentName>();
11011                }
11012                components.add(componentName);
11013                all = false;
11014            } else {
11015                int objectId = 0;
11016                // Not a '/' separated full component name; maybe an object ID?
11017                try {
11018                    objectId = Integer.parseInt(name, 16);
11019                    if (objects == null) {
11020                        objects = new ArrayList<Integer>();
11021                    }
11022                    objects.add(objectId);
11023                    all = false;
11024                } catch (RuntimeException e) {
11025                    // Not an integer; just do string match.
11026                    if (strings == null) {
11027                        strings = new ArrayList<String>();
11028                    }
11029                    strings.add(name);
11030                    all = false;
11031                }
11032            }
11033        }
11034
11035        int build(String[] args, int opti) {
11036            for (; opti<args.length; opti++) {
11037                String name = args[opti];
11038                if ("--".equals(name)) {
11039                    return opti+1;
11040                }
11041                build(name);
11042            }
11043            return opti;
11044        }
11045
11046        boolean match(Object object, ComponentName comp) {
11047            if (all) {
11048                return true;
11049            }
11050            if (components != null) {
11051                for (int i=0; i<components.size(); i++) {
11052                    if (components.get(i).equals(comp)) {
11053                        return true;
11054                    }
11055                }
11056            }
11057            if (objects != null) {
11058                for (int i=0; i<objects.size(); i++) {
11059                    if (System.identityHashCode(object) == objects.get(i)) {
11060                        return true;
11061                    }
11062                }
11063            }
11064            if (strings != null) {
11065                String flat = comp.flattenToString();
11066                for (int i=0; i<strings.size(); i++) {
11067                    if (flat.contains(strings.get(i))) {
11068                        return true;
11069                    }
11070                }
11071            }
11072            return false;
11073        }
11074    }
11075
11076    /**
11077     * There are three things that cmd can be:
11078     *  - a flattened component name that matches an existing activity
11079     *  - the cmd arg isn't the flattened component name of an existing activity:
11080     *    dump all activity whose component contains the cmd as a substring
11081     *  - A hex number of the ActivityRecord object instance.
11082     */
11083    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11084            int opti, boolean dumpAll) {
11085        ArrayList<ActivityRecord> activities;
11086
11087        synchronized (this) {
11088            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11089        }
11090
11091        if (activities.size() <= 0) {
11092            return false;
11093        }
11094
11095        String[] newArgs = new String[args.length - opti];
11096        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11097
11098        TaskRecord lastTask = null;
11099        boolean needSep = false;
11100        for (int i=activities.size()-1; i>=0; i--) {
11101            ActivityRecord r = activities.get(i);
11102            if (needSep) {
11103                pw.println();
11104            }
11105            needSep = true;
11106            synchronized (this) {
11107                if (lastTask != r.task) {
11108                    lastTask = r.task;
11109                    pw.print("TASK "); pw.print(lastTask.affinity);
11110                            pw.print(" id="); pw.println(lastTask.taskId);
11111                    if (dumpAll) {
11112                        lastTask.dump(pw, "  ");
11113                    }
11114                }
11115            }
11116            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11117        }
11118        return true;
11119    }
11120
11121    /**
11122     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11123     * there is a thread associated with the activity.
11124     */
11125    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11126            final ActivityRecord r, String[] args, boolean dumpAll) {
11127        String innerPrefix = prefix + "  ";
11128        synchronized (this) {
11129            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11130                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11131                    pw.print(" pid=");
11132                    if (r.app != null) pw.println(r.app.pid);
11133                    else pw.println("(not running)");
11134            if (dumpAll) {
11135                r.dump(pw, innerPrefix);
11136            }
11137        }
11138        if (r.app != null && r.app.thread != null) {
11139            // flush anything that is already in the PrintWriter since the thread is going
11140            // to write to the file descriptor directly
11141            pw.flush();
11142            try {
11143                TransferPipe tp = new TransferPipe();
11144                try {
11145                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11146                            r.appToken, innerPrefix, args);
11147                    tp.go(fd);
11148                } finally {
11149                    tp.kill();
11150                }
11151            } catch (IOException e) {
11152                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11153            } catch (RemoteException e) {
11154                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11155            }
11156        }
11157    }
11158
11159    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11160            int opti, boolean dumpAll, String dumpPackage) {
11161        boolean needSep = false;
11162        boolean onlyHistory = false;
11163        boolean printedAnything = false;
11164
11165        if ("history".equals(dumpPackage)) {
11166            if (opti < args.length && "-s".equals(args[opti])) {
11167                dumpAll = false;
11168            }
11169            onlyHistory = true;
11170            dumpPackage = null;
11171        }
11172
11173        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11174        if (!onlyHistory && dumpAll) {
11175            if (mRegisteredReceivers.size() > 0) {
11176                boolean printed = false;
11177                Iterator it = mRegisteredReceivers.values().iterator();
11178                while (it.hasNext()) {
11179                    ReceiverList r = (ReceiverList)it.next();
11180                    if (dumpPackage != null && (r.app == null ||
11181                            !dumpPackage.equals(r.app.info.packageName))) {
11182                        continue;
11183                    }
11184                    if (!printed) {
11185                        pw.println("  Registered Receivers:");
11186                        needSep = true;
11187                        printed = true;
11188                        printedAnything = true;
11189                    }
11190                    pw.print("  * "); pw.println(r);
11191                    r.dump(pw, "    ");
11192                }
11193            }
11194
11195            if (mReceiverResolver.dump(pw, needSep ?
11196                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11197                    "    ", dumpPackage, false)) {
11198                needSep = true;
11199                printedAnything = true;
11200            }
11201        }
11202
11203        for (BroadcastQueue q : mBroadcastQueues) {
11204            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11205            printedAnything |= needSep;
11206        }
11207
11208        needSep = true;
11209
11210        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11211            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11212                if (needSep) {
11213                    pw.println();
11214                }
11215                needSep = true;
11216                printedAnything = true;
11217                pw.print("  Sticky broadcasts for user ");
11218                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11219                StringBuilder sb = new StringBuilder(128);
11220                for (Map.Entry<String, ArrayList<Intent>> ent
11221                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11222                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11223                    if (dumpAll) {
11224                        pw.println(":");
11225                        ArrayList<Intent> intents = ent.getValue();
11226                        final int N = intents.size();
11227                        for (int i=0; i<N; i++) {
11228                            sb.setLength(0);
11229                            sb.append("    Intent: ");
11230                            intents.get(i).toShortString(sb, false, true, false, false);
11231                            pw.println(sb.toString());
11232                            Bundle bundle = intents.get(i).getExtras();
11233                            if (bundle != null) {
11234                                pw.print("      ");
11235                                pw.println(bundle.toString());
11236                            }
11237                        }
11238                    } else {
11239                        pw.println("");
11240                    }
11241                }
11242            }
11243        }
11244
11245        if (!onlyHistory && dumpAll) {
11246            pw.println();
11247            for (BroadcastQueue queue : mBroadcastQueues) {
11248                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11249                        + queue.mBroadcastsScheduled);
11250            }
11251            pw.println("  mHandler:");
11252            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11253            needSep = true;
11254            printedAnything = true;
11255        }
11256
11257        if (!printedAnything) {
11258            pw.println("  (nothing)");
11259        }
11260    }
11261
11262    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11263            int opti, boolean dumpAll, String dumpPackage) {
11264        boolean needSep;
11265        boolean printedAnything = false;
11266
11267        ItemMatcher matcher = new ItemMatcher();
11268        matcher.build(args, opti);
11269
11270        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11271
11272        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11273        printedAnything |= needSep;
11274
11275        if (mLaunchingProviders.size() > 0) {
11276            boolean printed = false;
11277            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11278                ContentProviderRecord r = mLaunchingProviders.get(i);
11279                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11280                    continue;
11281                }
11282                if (!printed) {
11283                    if (needSep) pw.println();
11284                    needSep = true;
11285                    pw.println("  Launching content providers:");
11286                    printed = true;
11287                    printedAnything = true;
11288                }
11289                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11290                        pw.println(r);
11291            }
11292        }
11293
11294        if (mGrantedUriPermissions.size() > 0) {
11295            boolean printed = false;
11296            int dumpUid = -2;
11297            if (dumpPackage != null) {
11298                try {
11299                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11300                } catch (NameNotFoundException e) {
11301                    dumpUid = -1;
11302                }
11303            }
11304            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11305                int uid = mGrantedUriPermissions.keyAt(i);
11306                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11307                    continue;
11308                }
11309                ArrayMap<Uri, UriPermission> perms
11310                        = mGrantedUriPermissions.valueAt(i);
11311                if (!printed) {
11312                    if (needSep) pw.println();
11313                    needSep = true;
11314                    pw.println("  Granted Uri Permissions:");
11315                    printed = true;
11316                    printedAnything = true;
11317                }
11318                pw.print("  * UID "); pw.print(uid);
11319                        pw.println(" holds:");
11320                for (UriPermission perm : perms.values()) {
11321                    pw.print("    "); pw.println(perm);
11322                    if (dumpAll) {
11323                        perm.dump(pw, "      ");
11324                    }
11325                }
11326            }
11327        }
11328
11329        if (!printedAnything) {
11330            pw.println("  (nothing)");
11331        }
11332    }
11333
11334    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11335            int opti, boolean dumpAll, String dumpPackage) {
11336        boolean printed = false;
11337
11338        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11339
11340        if (mIntentSenderRecords.size() > 0) {
11341            Iterator<WeakReference<PendingIntentRecord>> it
11342                    = mIntentSenderRecords.values().iterator();
11343            while (it.hasNext()) {
11344                WeakReference<PendingIntentRecord> ref = it.next();
11345                PendingIntentRecord rec = ref != null ? ref.get(): null;
11346                if (dumpPackage != null && (rec == null
11347                        || !dumpPackage.equals(rec.key.packageName))) {
11348                    continue;
11349                }
11350                printed = true;
11351                if (rec != null) {
11352                    pw.print("  * "); pw.println(rec);
11353                    if (dumpAll) {
11354                        rec.dump(pw, "    ");
11355                    }
11356                } else {
11357                    pw.print("  * "); pw.println(ref);
11358                }
11359            }
11360        }
11361
11362        if (!printed) {
11363            pw.println("  (nothing)");
11364        }
11365    }
11366
11367    private static final int dumpProcessList(PrintWriter pw,
11368            ActivityManagerService service, List list,
11369            String prefix, String normalLabel, String persistentLabel,
11370            String dumpPackage) {
11371        int numPers = 0;
11372        final int N = list.size()-1;
11373        for (int i=N; i>=0; i--) {
11374            ProcessRecord r = (ProcessRecord)list.get(i);
11375            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11376                continue;
11377            }
11378            pw.println(String.format("%s%s #%2d: %s",
11379                    prefix, (r.persistent ? persistentLabel : normalLabel),
11380                    i, r.toString()));
11381            if (r.persistent) {
11382                numPers++;
11383            }
11384        }
11385        return numPers;
11386    }
11387
11388    private static final boolean dumpProcessOomList(PrintWriter pw,
11389            ActivityManagerService service, List<ProcessRecord> origList,
11390            String prefix, String normalLabel, String persistentLabel,
11391            boolean inclDetails, String dumpPackage) {
11392
11393        ArrayList<Pair<ProcessRecord, Integer>> list
11394                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11395        for (int i=0; i<origList.size(); i++) {
11396            ProcessRecord r = origList.get(i);
11397            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11398                continue;
11399            }
11400            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11401        }
11402
11403        if (list.size() <= 0) {
11404            return false;
11405        }
11406
11407        Comparator<Pair<ProcessRecord, Integer>> comparator
11408                = new Comparator<Pair<ProcessRecord, Integer>>() {
11409            @Override
11410            public int compare(Pair<ProcessRecord, Integer> object1,
11411                    Pair<ProcessRecord, Integer> object2) {
11412                if (object1.first.setAdj != object2.first.setAdj) {
11413                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11414                }
11415                if (object1.second.intValue() != object2.second.intValue()) {
11416                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11417                }
11418                return 0;
11419            }
11420        };
11421
11422        Collections.sort(list, comparator);
11423
11424        final long curRealtime = SystemClock.elapsedRealtime();
11425        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11426        final long curUptime = SystemClock.uptimeMillis();
11427        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11428
11429        for (int i=list.size()-1; i>=0; i--) {
11430            ProcessRecord r = list.get(i).first;
11431            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11432            char schedGroup;
11433            switch (r.setSchedGroup) {
11434                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11435                    schedGroup = 'B';
11436                    break;
11437                case Process.THREAD_GROUP_DEFAULT:
11438                    schedGroup = 'F';
11439                    break;
11440                default:
11441                    schedGroup = '?';
11442                    break;
11443            }
11444            char foreground;
11445            if (r.foregroundActivities) {
11446                foreground = 'A';
11447            } else if (r.foregroundServices) {
11448                foreground = 'S';
11449            } else {
11450                foreground = ' ';
11451            }
11452            String procState = ProcessList.makeProcStateString(r.curProcState);
11453            pw.print(prefix);
11454            pw.print(r.persistent ? persistentLabel : normalLabel);
11455            pw.print(" #");
11456            int num = (origList.size()-1)-list.get(i).second;
11457            if (num < 10) pw.print(' ');
11458            pw.print(num);
11459            pw.print(": ");
11460            pw.print(oomAdj);
11461            pw.print(' ');
11462            pw.print(schedGroup);
11463            pw.print('/');
11464            pw.print(foreground);
11465            pw.print('/');
11466            pw.print(procState);
11467            pw.print(" trm:");
11468            if (r.trimMemoryLevel < 10) pw.print(' ');
11469            pw.print(r.trimMemoryLevel);
11470            pw.print(' ');
11471            pw.print(r.toShortString());
11472            pw.print(" (");
11473            pw.print(r.adjType);
11474            pw.println(')');
11475            if (r.adjSource != null || r.adjTarget != null) {
11476                pw.print(prefix);
11477                pw.print("    ");
11478                if (r.adjTarget instanceof ComponentName) {
11479                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11480                } else if (r.adjTarget != null) {
11481                    pw.print(r.adjTarget.toString());
11482                } else {
11483                    pw.print("{null}");
11484                }
11485                pw.print("<=");
11486                if (r.adjSource instanceof ProcessRecord) {
11487                    pw.print("Proc{");
11488                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11489                    pw.println("}");
11490                } else if (r.adjSource != null) {
11491                    pw.println(r.adjSource.toString());
11492                } else {
11493                    pw.println("{null}");
11494                }
11495            }
11496            if (inclDetails) {
11497                pw.print(prefix);
11498                pw.print("    ");
11499                pw.print("oom: max="); pw.print(r.maxAdj);
11500                pw.print(" curRaw="); pw.print(r.curRawAdj);
11501                pw.print(" setRaw="); pw.print(r.setRawAdj);
11502                pw.print(" cur="); pw.print(r.curAdj);
11503                pw.print(" set="); pw.println(r.setAdj);
11504                pw.print(prefix);
11505                pw.print("    ");
11506                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11507                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11508                pw.print(" lastPss="); pw.print(r.lastPss);
11509                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11510                pw.print(prefix);
11511                pw.print("    ");
11512                pw.print("keeping="); pw.print(r.keeping);
11513                pw.print(" cached="); pw.print(r.cached);
11514                pw.print(" empty="); pw.print(r.empty);
11515                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11516
11517                if (!r.keeping) {
11518                    if (r.lastWakeTime != 0) {
11519                        long wtime;
11520                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11521                        synchronized (stats) {
11522                            wtime = stats.getProcessWakeTime(r.info.uid,
11523                                    r.pid, curRealtime);
11524                        }
11525                        long timeUsed = wtime - r.lastWakeTime;
11526                        pw.print(prefix);
11527                        pw.print("    ");
11528                        pw.print("keep awake over ");
11529                        TimeUtils.formatDuration(realtimeSince, pw);
11530                        pw.print(" used ");
11531                        TimeUtils.formatDuration(timeUsed, pw);
11532                        pw.print(" (");
11533                        pw.print((timeUsed*100)/realtimeSince);
11534                        pw.println("%)");
11535                    }
11536                    if (r.lastCpuTime != 0) {
11537                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11538                        pw.print(prefix);
11539                        pw.print("    ");
11540                        pw.print("run cpu over ");
11541                        TimeUtils.formatDuration(uptimeSince, pw);
11542                        pw.print(" used ");
11543                        TimeUtils.formatDuration(timeUsed, pw);
11544                        pw.print(" (");
11545                        pw.print((timeUsed*100)/uptimeSince);
11546                        pw.println("%)");
11547                    }
11548                }
11549            }
11550        }
11551        return true;
11552    }
11553
11554    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11555        ArrayList<ProcessRecord> procs;
11556        synchronized (this) {
11557            if (args != null && args.length > start
11558                    && args[start].charAt(0) != '-') {
11559                procs = new ArrayList<ProcessRecord>();
11560                int pid = -1;
11561                try {
11562                    pid = Integer.parseInt(args[start]);
11563                } catch (NumberFormatException e) {
11564                }
11565                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11566                    ProcessRecord proc = mLruProcesses.get(i);
11567                    if (proc.pid == pid) {
11568                        procs.add(proc);
11569                    } else if (proc.processName.equals(args[start])) {
11570                        procs.add(proc);
11571                    }
11572                }
11573                if (procs.size() <= 0) {
11574                    return null;
11575                }
11576            } else {
11577                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11578            }
11579        }
11580        return procs;
11581    }
11582
11583    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11584            PrintWriter pw, String[] args) {
11585        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11586        if (procs == null) {
11587            pw.println("No process found for: " + args[0]);
11588            return;
11589        }
11590
11591        long uptime = SystemClock.uptimeMillis();
11592        long realtime = SystemClock.elapsedRealtime();
11593        pw.println("Applications Graphics Acceleration Info:");
11594        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11595
11596        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11597            ProcessRecord r = procs.get(i);
11598            if (r.thread != null) {
11599                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11600                pw.flush();
11601                try {
11602                    TransferPipe tp = new TransferPipe();
11603                    try {
11604                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11605                        tp.go(fd);
11606                    } finally {
11607                        tp.kill();
11608                    }
11609                } catch (IOException e) {
11610                    pw.println("Failure while dumping the app: " + r);
11611                    pw.flush();
11612                } catch (RemoteException e) {
11613                    pw.println("Got a RemoteException while dumping the app " + r);
11614                    pw.flush();
11615                }
11616            }
11617        }
11618    }
11619
11620    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11621        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11622        if (procs == null) {
11623            pw.println("No process found for: " + args[0]);
11624            return;
11625        }
11626
11627        pw.println("Applications Database Info:");
11628
11629        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11630            ProcessRecord r = procs.get(i);
11631            if (r.thread != null) {
11632                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11633                pw.flush();
11634                try {
11635                    TransferPipe tp = new TransferPipe();
11636                    try {
11637                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11638                        tp.go(fd);
11639                    } finally {
11640                        tp.kill();
11641                    }
11642                } catch (IOException e) {
11643                    pw.println("Failure while dumping the app: " + r);
11644                    pw.flush();
11645                } catch (RemoteException e) {
11646                    pw.println("Got a RemoteException while dumping the app " + r);
11647                    pw.flush();
11648                }
11649            }
11650        }
11651    }
11652
11653    final static class MemItem {
11654        final boolean isProc;
11655        final String label;
11656        final String shortLabel;
11657        final long pss;
11658        final int id;
11659        final boolean hasActivities;
11660        ArrayList<MemItem> subitems;
11661
11662        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11663                boolean _hasActivities) {
11664            isProc = true;
11665            label = _label;
11666            shortLabel = _shortLabel;
11667            pss = _pss;
11668            id = _id;
11669            hasActivities = _hasActivities;
11670        }
11671
11672        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11673            isProc = false;
11674            label = _label;
11675            shortLabel = _shortLabel;
11676            pss = _pss;
11677            id = _id;
11678            hasActivities = false;
11679        }
11680    }
11681
11682    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11683            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11684        if (sort && !isCompact) {
11685            Collections.sort(items, new Comparator<MemItem>() {
11686                @Override
11687                public int compare(MemItem lhs, MemItem rhs) {
11688                    if (lhs.pss < rhs.pss) {
11689                        return 1;
11690                    } else if (lhs.pss > rhs.pss) {
11691                        return -1;
11692                    }
11693                    return 0;
11694                }
11695            });
11696        }
11697
11698        for (int i=0; i<items.size(); i++) {
11699            MemItem mi = items.get(i);
11700            if (!isCompact) {
11701                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11702            } else if (mi.isProc) {
11703                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11704                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11705                pw.println(mi.hasActivities ? ",a" : ",e");
11706            } else {
11707                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11708                pw.println(mi.pss);
11709            }
11710            if (mi.subitems != null) {
11711                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11712                        true, isCompact);
11713            }
11714        }
11715    }
11716
11717    // These are in KB.
11718    static final long[] DUMP_MEM_BUCKETS = new long[] {
11719        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11720        120*1024, 160*1024, 200*1024,
11721        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11722        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11723    };
11724
11725    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11726            boolean stackLike) {
11727        int start = label.lastIndexOf('.');
11728        if (start >= 0) start++;
11729        else start = 0;
11730        int end = label.length();
11731        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11732            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11733                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11734                out.append(bucket);
11735                out.append(stackLike ? "MB." : "MB ");
11736                out.append(label, start, end);
11737                return;
11738            }
11739        }
11740        out.append(memKB/1024);
11741        out.append(stackLike ? "MB." : "MB ");
11742        out.append(label, start, end);
11743    }
11744
11745    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11746            ProcessList.NATIVE_ADJ,
11747            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11748            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11749            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11750            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11751            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11752    };
11753    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11754            "Native",
11755            "System", "Persistent", "Foreground",
11756            "Visible", "Perceptible",
11757            "Heavy Weight", "Backup",
11758            "A Services", "Home",
11759            "Previous", "B Services", "Cached"
11760    };
11761    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11762            "native",
11763            "sys", "pers", "fore",
11764            "vis", "percept",
11765            "heavy", "backup",
11766            "servicea", "home",
11767            "prev", "serviceb", "cached"
11768    };
11769
11770    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11771            long realtime, boolean isCheckinRequest, boolean isCompact) {
11772        if (isCheckinRequest || isCompact) {
11773            // short checkin version
11774            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11775        } else {
11776            pw.println("Applications Memory Usage (kB):");
11777            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11778        }
11779    }
11780
11781    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11782            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11783        boolean dumpDetails = false;
11784        boolean dumpFullDetails = false;
11785        boolean dumpDalvik = false;
11786        boolean oomOnly = false;
11787        boolean isCompact = false;
11788        boolean localOnly = false;
11789
11790        int opti = 0;
11791        while (opti < args.length) {
11792            String opt = args[opti];
11793            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11794                break;
11795            }
11796            opti++;
11797            if ("-a".equals(opt)) {
11798                dumpDetails = true;
11799                dumpFullDetails = true;
11800                dumpDalvik = true;
11801            } else if ("-d".equals(opt)) {
11802                dumpDalvik = true;
11803            } else if ("-c".equals(opt)) {
11804                isCompact = true;
11805            } else if ("--oom".equals(opt)) {
11806                oomOnly = true;
11807            } else if ("--local".equals(opt)) {
11808                localOnly = true;
11809            } else if ("-h".equals(opt)) {
11810                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11811                pw.println("  -a: include all available information for each process.");
11812                pw.println("  -d: include dalvik details when dumping process details.");
11813                pw.println("  -c: dump in a compact machine-parseable representation.");
11814                pw.println("  --oom: only show processes organized by oom adj.");
11815                pw.println("  --local: only collect details locally, don't call process.");
11816                pw.println("If [process] is specified it can be the name or ");
11817                pw.println("pid of a specific process to dump.");
11818                return;
11819            } else {
11820                pw.println("Unknown argument: " + opt + "; use -h for help");
11821            }
11822        }
11823
11824        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11825        long uptime = SystemClock.uptimeMillis();
11826        long realtime = SystemClock.elapsedRealtime();
11827        final long[] tmpLong = new long[1];
11828
11829        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11830        if (procs == null) {
11831            // No Java processes.  Maybe they want to print a native process.
11832            if (args != null && args.length > opti
11833                    && args[opti].charAt(0) != '-') {
11834                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11835                        = new ArrayList<ProcessCpuTracker.Stats>();
11836                updateCpuStatsNow();
11837                int findPid = -1;
11838                try {
11839                    findPid = Integer.parseInt(args[opti]);
11840                } catch (NumberFormatException e) {
11841                }
11842                synchronized (mProcessCpuThread) {
11843                    final int N = mProcessCpuTracker.countStats();
11844                    for (int i=0; i<N; i++) {
11845                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11846                        if (st.pid == findPid || (st.baseName != null
11847                                && st.baseName.equals(args[opti]))) {
11848                            nativeProcs.add(st);
11849                        }
11850                    }
11851                }
11852                if (nativeProcs.size() > 0) {
11853                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11854                            isCompact);
11855                    Debug.MemoryInfo mi = null;
11856                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11857                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11858                        final int pid = r.pid;
11859                        if (!isCheckinRequest && dumpDetails) {
11860                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11861                        }
11862                        if (mi == null) {
11863                            mi = new Debug.MemoryInfo();
11864                        }
11865                        if (dumpDetails || (!brief && !oomOnly)) {
11866                            Debug.getMemoryInfo(pid, mi);
11867                        } else {
11868                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11869                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11870                        }
11871                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11872                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11873                        if (isCheckinRequest) {
11874                            pw.println();
11875                        }
11876                    }
11877                    return;
11878                }
11879            }
11880            pw.println("No process found for: " + args[opti]);
11881            return;
11882        }
11883
11884        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11885            dumpDetails = true;
11886        }
11887
11888        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11889
11890        String[] innerArgs = new String[args.length-opti];
11891        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11892
11893        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11894        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11895        long nativePss=0, dalvikPss=0, otherPss=0;
11896        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11897
11898        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11899        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11900                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11901
11902        long totalPss = 0;
11903        long cachedPss = 0;
11904
11905        Debug.MemoryInfo mi = null;
11906        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11907            final ProcessRecord r = procs.get(i);
11908            final IApplicationThread thread;
11909            final int pid;
11910            final int oomAdj;
11911            final boolean hasActivities;
11912            synchronized (this) {
11913                thread = r.thread;
11914                pid = r.pid;
11915                oomAdj = r.getSetAdjWithServices();
11916                hasActivities = r.activities.size() > 0;
11917            }
11918            if (thread != null) {
11919                if (!isCheckinRequest && dumpDetails) {
11920                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11921                }
11922                if (mi == null) {
11923                    mi = new Debug.MemoryInfo();
11924                }
11925                if (dumpDetails || (!brief && !oomOnly)) {
11926                    Debug.getMemoryInfo(pid, mi);
11927                } else {
11928                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11929                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11930                }
11931                if (dumpDetails) {
11932                    if (localOnly) {
11933                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11934                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11935                        if (isCheckinRequest) {
11936                            pw.println();
11937                        }
11938                    } else {
11939                        try {
11940                            pw.flush();
11941                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11942                                    dumpDalvik, innerArgs);
11943                        } catch (RemoteException e) {
11944                            if (!isCheckinRequest) {
11945                                pw.println("Got RemoteException!");
11946                                pw.flush();
11947                            }
11948                        }
11949                    }
11950                }
11951
11952                final long myTotalPss = mi.getTotalPss();
11953                final long myTotalUss = mi.getTotalUss();
11954
11955                synchronized (this) {
11956                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
11957                        // Record this for posterity if the process has been stable.
11958                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
11959                    }
11960                }
11961
11962                if (!isCheckinRequest && mi != null) {
11963                    totalPss += myTotalPss;
11964                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
11965                            (hasActivities ? " / activities)" : ")"),
11966                            r.processName, myTotalPss, pid, hasActivities);
11967                    procMems.add(pssItem);
11968                    procMemsMap.put(pid, pssItem);
11969
11970                    nativePss += mi.nativePss;
11971                    dalvikPss += mi.dalvikPss;
11972                    otherPss += mi.otherPss;
11973                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
11974                        long mem = mi.getOtherPss(j);
11975                        miscPss[j] += mem;
11976                        otherPss -= mem;
11977                    }
11978
11979                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
11980                        cachedPss += myTotalPss;
11981                    }
11982
11983                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
11984                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
11985                                || oomIndex == (oomPss.length-1)) {
11986                            oomPss[oomIndex] += myTotalPss;
11987                            if (oomProcs[oomIndex] == null) {
11988                                oomProcs[oomIndex] = new ArrayList<MemItem>();
11989                            }
11990                            oomProcs[oomIndex].add(pssItem);
11991                            break;
11992                        }
11993                    }
11994                }
11995            }
11996        }
11997
11998        if (!isCheckinRequest && procs.size() > 1) {
11999            // If we are showing aggregations, also look for native processes to
12000            // include so that our aggregations are more accurate.
12001            updateCpuStatsNow();
12002            synchronized (mProcessCpuThread) {
12003                final int N = mProcessCpuTracker.countStats();
12004                for (int i=0; i<N; i++) {
12005                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12006                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12007                        if (mi == null) {
12008                            mi = new Debug.MemoryInfo();
12009                        }
12010                        if (!brief && !oomOnly) {
12011                            Debug.getMemoryInfo(st.pid, mi);
12012                        } else {
12013                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12014                            mi.nativePrivateDirty = (int)tmpLong[0];
12015                        }
12016
12017                        final long myTotalPss = mi.getTotalPss();
12018                        totalPss += myTotalPss;
12019
12020                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12021                                st.name, myTotalPss, st.pid, false);
12022                        procMems.add(pssItem);
12023
12024                        nativePss += mi.nativePss;
12025                        dalvikPss += mi.dalvikPss;
12026                        otherPss += mi.otherPss;
12027                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12028                            long mem = mi.getOtherPss(j);
12029                            miscPss[j] += mem;
12030                            otherPss -= mem;
12031                        }
12032                        oomPss[0] += myTotalPss;
12033                        if (oomProcs[0] == null) {
12034                            oomProcs[0] = new ArrayList<MemItem>();
12035                        }
12036                        oomProcs[0].add(pssItem);
12037                    }
12038                }
12039            }
12040
12041            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12042
12043            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12044            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12045            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12046            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12047                String label = Debug.MemoryInfo.getOtherLabel(j);
12048                catMems.add(new MemItem(label, label, miscPss[j], j));
12049            }
12050
12051            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12052            for (int j=0; j<oomPss.length; j++) {
12053                if (oomPss[j] != 0) {
12054                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12055                            : DUMP_MEM_OOM_LABEL[j];
12056                    MemItem item = new MemItem(label, label, oomPss[j],
12057                            DUMP_MEM_OOM_ADJ[j]);
12058                    item.subitems = oomProcs[j];
12059                    oomMems.add(item);
12060                }
12061            }
12062
12063            if (!brief && !oomOnly && !isCompact) {
12064                pw.println();
12065                pw.println("Total PSS by process:");
12066                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12067                pw.println();
12068            }
12069            if (!isCompact) {
12070                pw.println("Total PSS by OOM adjustment:");
12071            }
12072            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12073            if (!brief && !oomOnly) {
12074                PrintWriter out = categoryPw != null ? categoryPw : pw;
12075                if (!isCompact) {
12076                    out.println();
12077                    out.println("Total PSS by category:");
12078                }
12079                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12080            }
12081            if (!isCompact) {
12082                pw.println();
12083            }
12084            MemInfoReader memInfo = new MemInfoReader();
12085            memInfo.readMemInfo();
12086            if (!brief) {
12087                if (!isCompact) {
12088                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12089                    pw.println(" kB");
12090                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12091                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12092                            pw.print(cachedPss); pw.print(" cached pss + ");
12093                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12094                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12095                } else {
12096                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12097                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12098                            + memInfo.getFreeSizeKb()); pw.print(",");
12099                    pw.println(totalPss - cachedPss);
12100                }
12101            }
12102            if (!isCompact) {
12103                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12104                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12105                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12106                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12107                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12108                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12109                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12110                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12111                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12112                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12113                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12114            }
12115            if (!brief) {
12116                if (memInfo.getZramTotalSizeKb() != 0) {
12117                    if (!isCompact) {
12118                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12119                                pw.print(" kB physical used for ");
12120                                pw.print(memInfo.getSwapTotalSizeKb()
12121                                        - memInfo.getSwapFreeSizeKb());
12122                                pw.print(" kB in swap (");
12123                                pw.print(memInfo.getSwapTotalSizeKb());
12124                                pw.println(" kB total swap)");
12125                    } else {
12126                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12127                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12128                                pw.println(memInfo.getSwapFreeSizeKb());
12129                    }
12130                }
12131                final int[] SINGLE_LONG_FORMAT = new int[] {
12132                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12133                };
12134                long[] longOut = new long[1];
12135                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12136                        SINGLE_LONG_FORMAT, null, longOut, null);
12137                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12138                longOut[0] = 0;
12139                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12140                        SINGLE_LONG_FORMAT, null, longOut, null);
12141                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12142                longOut[0] = 0;
12143                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12144                        SINGLE_LONG_FORMAT, null, longOut, null);
12145                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12146                longOut[0] = 0;
12147                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12148                        SINGLE_LONG_FORMAT, null, longOut, null);
12149                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12150                if (!isCompact) {
12151                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12152                        pw.print("      KSM: "); pw.print(sharing);
12153                                pw.print(" kB saved from shared ");
12154                                pw.print(shared); pw.println(" kB");
12155                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12156                                pw.print(voltile); pw.println(" kB volatile");
12157                    }
12158                    pw.print("   Tuning: ");
12159                    pw.print(ActivityManager.staticGetMemoryClass());
12160                    pw.print(" (large ");
12161                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12162                    pw.print("), oom ");
12163                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12164                    pw.print(" kB");
12165                    pw.print(", restore limit ");
12166                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12167                    pw.print(" kB");
12168                    if (ActivityManager.isLowRamDeviceStatic()) {
12169                        pw.print(" (low-ram)");
12170                    }
12171                    if (ActivityManager.isHighEndGfx()) {
12172                        pw.print(" (high-end-gfx)");
12173                    }
12174                    pw.println();
12175                } else {
12176                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12177                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12178                    pw.println(voltile);
12179                    pw.print("tuning,");
12180                    pw.print(ActivityManager.staticGetMemoryClass());
12181                    pw.print(',');
12182                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12183                    pw.print(',');
12184                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12185                    if (ActivityManager.isLowRamDeviceStatic()) {
12186                        pw.print(",low-ram");
12187                    }
12188                    if (ActivityManager.isHighEndGfx()) {
12189                        pw.print(",high-end-gfx");
12190                    }
12191                    pw.println();
12192                }
12193            }
12194        }
12195    }
12196
12197    /**
12198     * Searches array of arguments for the specified string
12199     * @param args array of argument strings
12200     * @param value value to search for
12201     * @return true if the value is contained in the array
12202     */
12203    private static boolean scanArgs(String[] args, String value) {
12204        if (args != null) {
12205            for (String arg : args) {
12206                if (value.equals(arg)) {
12207                    return true;
12208                }
12209            }
12210        }
12211        return false;
12212    }
12213
12214    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12215            ContentProviderRecord cpr, boolean always) {
12216        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12217
12218        if (!inLaunching || always) {
12219            synchronized (cpr) {
12220                cpr.launchingApp = null;
12221                cpr.notifyAll();
12222            }
12223            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12224            String names[] = cpr.info.authority.split(";");
12225            for (int j = 0; j < names.length; j++) {
12226                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12227            }
12228        }
12229
12230        for (int i=0; i<cpr.connections.size(); i++) {
12231            ContentProviderConnection conn = cpr.connections.get(i);
12232            if (conn.waiting) {
12233                // If this connection is waiting for the provider, then we don't
12234                // need to mess with its process unless we are always removing
12235                // or for some reason the provider is not currently launching.
12236                if (inLaunching && !always) {
12237                    continue;
12238                }
12239            }
12240            ProcessRecord capp = conn.client;
12241            conn.dead = true;
12242            if (conn.stableCount > 0) {
12243                if (!capp.persistent && capp.thread != null
12244                        && capp.pid != 0
12245                        && capp.pid != MY_PID) {
12246                    killUnneededProcessLocked(capp, "depends on provider "
12247                            + cpr.name.flattenToShortString()
12248                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12249                }
12250            } else if (capp.thread != null && conn.provider.provider != null) {
12251                try {
12252                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12253                } catch (RemoteException e) {
12254                }
12255                // In the protocol here, we don't expect the client to correctly
12256                // clean up this connection, we'll just remove it.
12257                cpr.connections.remove(i);
12258                conn.client.conProviders.remove(conn);
12259            }
12260        }
12261
12262        if (inLaunching && always) {
12263            mLaunchingProviders.remove(cpr);
12264        }
12265        return inLaunching;
12266    }
12267
12268    /**
12269     * Main code for cleaning up a process when it has gone away.  This is
12270     * called both as a result of the process dying, or directly when stopping
12271     * a process when running in single process mode.
12272     */
12273    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12274            boolean restarting, boolean allowRestart, int index) {
12275        if (index >= 0) {
12276            removeLruProcessLocked(app);
12277            ProcessList.remove(app.pid);
12278        }
12279
12280        mProcessesToGc.remove(app);
12281        mPendingPssProcesses.remove(app);
12282
12283        // Dismiss any open dialogs.
12284        if (app.crashDialog != null && !app.forceCrashReport) {
12285            app.crashDialog.dismiss();
12286            app.crashDialog = null;
12287        }
12288        if (app.anrDialog != null) {
12289            app.anrDialog.dismiss();
12290            app.anrDialog = null;
12291        }
12292        if (app.waitDialog != null) {
12293            app.waitDialog.dismiss();
12294            app.waitDialog = null;
12295        }
12296
12297        app.crashing = false;
12298        app.notResponding = false;
12299
12300        app.resetPackageList(mProcessStats);
12301        app.unlinkDeathRecipient();
12302        app.makeInactive(mProcessStats);
12303        app.forcingToForeground = null;
12304        app.foregroundServices = false;
12305        app.foregroundActivities = false;
12306        app.hasShownUi = false;
12307        app.hasAboveClient = false;
12308
12309        mServices.killServicesLocked(app, allowRestart);
12310
12311        boolean restart = false;
12312
12313        // Remove published content providers.
12314        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12315            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12316            final boolean always = app.bad || !allowRestart;
12317            if (removeDyingProviderLocked(app, cpr, always) || always) {
12318                // We left the provider in the launching list, need to
12319                // restart it.
12320                restart = true;
12321            }
12322
12323            cpr.provider = null;
12324            cpr.proc = null;
12325        }
12326        app.pubProviders.clear();
12327
12328        // Take care of any launching providers waiting for this process.
12329        if (checkAppInLaunchingProvidersLocked(app, false)) {
12330            restart = true;
12331        }
12332
12333        // Unregister from connected content providers.
12334        if (!app.conProviders.isEmpty()) {
12335            for (int i=0; i<app.conProviders.size(); i++) {
12336                ContentProviderConnection conn = app.conProviders.get(i);
12337                conn.provider.connections.remove(conn);
12338            }
12339            app.conProviders.clear();
12340        }
12341
12342        // At this point there may be remaining entries in mLaunchingProviders
12343        // where we were the only one waiting, so they are no longer of use.
12344        // Look for these and clean up if found.
12345        // XXX Commented out for now.  Trying to figure out a way to reproduce
12346        // the actual situation to identify what is actually going on.
12347        if (false) {
12348            for (int i=0; i<mLaunchingProviders.size(); i++) {
12349                ContentProviderRecord cpr = (ContentProviderRecord)
12350                        mLaunchingProviders.get(i);
12351                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12352                    synchronized (cpr) {
12353                        cpr.launchingApp = null;
12354                        cpr.notifyAll();
12355                    }
12356                }
12357            }
12358        }
12359
12360        skipCurrentReceiverLocked(app);
12361
12362        // Unregister any receivers.
12363        for (int i=app.receivers.size()-1; i>=0; i--) {
12364            removeReceiverLocked(app.receivers.valueAt(i));
12365        }
12366        app.receivers.clear();
12367
12368        // If the app is undergoing backup, tell the backup manager about it
12369        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12370            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12371                    + mBackupTarget.appInfo + " died during backup");
12372            try {
12373                IBackupManager bm = IBackupManager.Stub.asInterface(
12374                        ServiceManager.getService(Context.BACKUP_SERVICE));
12375                bm.agentDisconnected(app.info.packageName);
12376            } catch (RemoteException e) {
12377                // can't happen; backup manager is local
12378            }
12379        }
12380
12381        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12382            ProcessChangeItem item = mPendingProcessChanges.get(i);
12383            if (item.pid == app.pid) {
12384                mPendingProcessChanges.remove(i);
12385                mAvailProcessChanges.add(item);
12386            }
12387        }
12388        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12389
12390        // If the caller is restarting this app, then leave it in its
12391        // current lists and let the caller take care of it.
12392        if (restarting) {
12393            return;
12394        }
12395
12396        if (!app.persistent || app.isolated) {
12397            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12398                    "Removing non-persistent process during cleanup: " + app);
12399            mProcessNames.remove(app.processName, app.uid);
12400            mIsolatedProcesses.remove(app.uid);
12401            if (mHeavyWeightProcess == app) {
12402                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12403                        mHeavyWeightProcess.userId, 0));
12404                mHeavyWeightProcess = null;
12405            }
12406        } else if (!app.removed) {
12407            // This app is persistent, so we need to keep its record around.
12408            // If it is not already on the pending app list, add it there
12409            // and start a new process for it.
12410            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12411                mPersistentStartingProcesses.add(app);
12412                restart = true;
12413            }
12414        }
12415        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12416                "Clean-up removing on hold: " + app);
12417        mProcessesOnHold.remove(app);
12418
12419        if (app == mHomeProcess) {
12420            mHomeProcess = null;
12421        }
12422        if (app == mPreviousProcess) {
12423            mPreviousProcess = null;
12424        }
12425
12426        if (restart && !app.isolated) {
12427            // We have components that still need to be running in the
12428            // process, so re-launch it.
12429            mProcessNames.put(app.processName, app.uid, app);
12430            startProcessLocked(app, "restart", app.processName);
12431        } else if (app.pid > 0 && app.pid != MY_PID) {
12432            // Goodbye!
12433            synchronized (mPidsSelfLocked) {
12434                mPidsSelfLocked.remove(app.pid);
12435                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12436            }
12437            app.setPid(0);
12438        }
12439    }
12440
12441    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12442        // Look through the content providers we are waiting to have launched,
12443        // and if any run in this process then either schedule a restart of
12444        // the process or kill the client waiting for it if this process has
12445        // gone bad.
12446        int NL = mLaunchingProviders.size();
12447        boolean restart = false;
12448        for (int i=0; i<NL; i++) {
12449            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12450            if (cpr.launchingApp == app) {
12451                if (!alwaysBad && !app.bad) {
12452                    restart = true;
12453                } else {
12454                    removeDyingProviderLocked(app, cpr, true);
12455                    // cpr should have been removed from mLaunchingProviders
12456                    NL = mLaunchingProviders.size();
12457                    i--;
12458                }
12459            }
12460        }
12461        return restart;
12462    }
12463
12464    // =========================================================
12465    // SERVICES
12466    // =========================================================
12467
12468    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12469            int flags) {
12470        enforceNotIsolatedCaller("getServices");
12471        synchronized (this) {
12472            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12473        }
12474    }
12475
12476    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12477        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12478        synchronized (this) {
12479            return mServices.getRunningServiceControlPanelLocked(name);
12480        }
12481    }
12482
12483    public ComponentName startService(IApplicationThread caller, Intent service,
12484            String resolvedType, int userId) {
12485        enforceNotIsolatedCaller("startService");
12486        // Refuse possible leaked file descriptors
12487        if (service != null && service.hasFileDescriptors() == true) {
12488            throw new IllegalArgumentException("File descriptors passed in Intent");
12489        }
12490
12491        if (DEBUG_SERVICE)
12492            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12493        synchronized(this) {
12494            final int callingPid = Binder.getCallingPid();
12495            final int callingUid = Binder.getCallingUid();
12496            final long origId = Binder.clearCallingIdentity();
12497            ComponentName res = mServices.startServiceLocked(caller, service,
12498                    resolvedType, callingPid, callingUid, userId);
12499            Binder.restoreCallingIdentity(origId);
12500            return res;
12501        }
12502    }
12503
12504    ComponentName startServiceInPackage(int uid,
12505            Intent service, String resolvedType, int userId) {
12506        synchronized(this) {
12507            if (DEBUG_SERVICE)
12508                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12509            final long origId = Binder.clearCallingIdentity();
12510            ComponentName res = mServices.startServiceLocked(null, service,
12511                    resolvedType, -1, uid, userId);
12512            Binder.restoreCallingIdentity(origId);
12513            return res;
12514        }
12515    }
12516
12517    public int stopService(IApplicationThread caller, Intent service,
12518            String resolvedType, int userId) {
12519        enforceNotIsolatedCaller("stopService");
12520        // Refuse possible leaked file descriptors
12521        if (service != null && service.hasFileDescriptors() == true) {
12522            throw new IllegalArgumentException("File descriptors passed in Intent");
12523        }
12524
12525        synchronized(this) {
12526            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12527        }
12528    }
12529
12530    public IBinder peekService(Intent service, String resolvedType) {
12531        enforceNotIsolatedCaller("peekService");
12532        // Refuse possible leaked file descriptors
12533        if (service != null && service.hasFileDescriptors() == true) {
12534            throw new IllegalArgumentException("File descriptors passed in Intent");
12535        }
12536        synchronized(this) {
12537            return mServices.peekServiceLocked(service, resolvedType);
12538        }
12539    }
12540
12541    public boolean stopServiceToken(ComponentName className, IBinder token,
12542            int startId) {
12543        synchronized(this) {
12544            return mServices.stopServiceTokenLocked(className, token, startId);
12545        }
12546    }
12547
12548    public void setServiceForeground(ComponentName className, IBinder token,
12549            int id, Notification notification, boolean removeNotification) {
12550        synchronized(this) {
12551            mServices.setServiceForegroundLocked(className, token, id, notification,
12552                    removeNotification);
12553        }
12554    }
12555
12556    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12557            boolean requireFull, String name, String callerPackage) {
12558        final int callingUserId = UserHandle.getUserId(callingUid);
12559        if (callingUserId != userId) {
12560            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12561                if ((requireFull || checkComponentPermission(
12562                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12563                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12564                        && checkComponentPermission(
12565                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12566                                callingPid, callingUid, -1, true)
12567                                != PackageManager.PERMISSION_GRANTED) {
12568                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12569                        // In this case, they would like to just execute as their
12570                        // owner user instead of failing.
12571                        userId = callingUserId;
12572                    } else {
12573                        StringBuilder builder = new StringBuilder(128);
12574                        builder.append("Permission Denial: ");
12575                        builder.append(name);
12576                        if (callerPackage != null) {
12577                            builder.append(" from ");
12578                            builder.append(callerPackage);
12579                        }
12580                        builder.append(" asks to run as user ");
12581                        builder.append(userId);
12582                        builder.append(" but is calling from user ");
12583                        builder.append(UserHandle.getUserId(callingUid));
12584                        builder.append("; this requires ");
12585                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12586                        if (!requireFull) {
12587                            builder.append(" or ");
12588                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12589                        }
12590                        String msg = builder.toString();
12591                        Slog.w(TAG, msg);
12592                        throw new SecurityException(msg);
12593                    }
12594                }
12595            }
12596            if (userId == UserHandle.USER_CURRENT
12597                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12598                // Note that we may be accessing this outside of a lock...
12599                // shouldn't be a big deal, if this is being called outside
12600                // of a locked context there is intrinsically a race with
12601                // the value the caller will receive and someone else changing it.
12602                userId = mCurrentUserId;
12603            }
12604            if (!allowAll && userId < 0) {
12605                throw new IllegalArgumentException(
12606                        "Call does not support special user #" + userId);
12607            }
12608        }
12609        return userId;
12610    }
12611
12612    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12613            String className, int flags) {
12614        boolean result = false;
12615        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12616            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12617                if (ActivityManager.checkUidPermission(
12618                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12619                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12620                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12621                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12622                            + " requests FLAG_SINGLE_USER, but app does not hold "
12623                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12624                    Slog.w(TAG, msg);
12625                    throw new SecurityException(msg);
12626                }
12627                result = true;
12628            }
12629        } else if (componentProcessName == aInfo.packageName) {
12630            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12631        } else if ("system".equals(componentProcessName)) {
12632            result = true;
12633        }
12634        if (DEBUG_MU) {
12635            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12636                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12637        }
12638        return result;
12639    }
12640
12641    public int bindService(IApplicationThread caller, IBinder token,
12642            Intent service, String resolvedType,
12643            IServiceConnection connection, int flags, int userId) {
12644        enforceNotIsolatedCaller("bindService");
12645        // Refuse possible leaked file descriptors
12646        if (service != null && service.hasFileDescriptors() == true) {
12647            throw new IllegalArgumentException("File descriptors passed in Intent");
12648        }
12649
12650        synchronized(this) {
12651            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12652                    connection, flags, userId);
12653        }
12654    }
12655
12656    public boolean unbindService(IServiceConnection connection) {
12657        synchronized (this) {
12658            return mServices.unbindServiceLocked(connection);
12659        }
12660    }
12661
12662    public void publishService(IBinder token, Intent intent, IBinder service) {
12663        // Refuse possible leaked file descriptors
12664        if (intent != null && intent.hasFileDescriptors() == true) {
12665            throw new IllegalArgumentException("File descriptors passed in Intent");
12666        }
12667
12668        synchronized(this) {
12669            if (!(token instanceof ServiceRecord)) {
12670                throw new IllegalArgumentException("Invalid service token");
12671            }
12672            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12673        }
12674    }
12675
12676    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12677        // Refuse possible leaked file descriptors
12678        if (intent != null && intent.hasFileDescriptors() == true) {
12679            throw new IllegalArgumentException("File descriptors passed in Intent");
12680        }
12681
12682        synchronized(this) {
12683            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12684        }
12685    }
12686
12687    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12688        synchronized(this) {
12689            if (!(token instanceof ServiceRecord)) {
12690                throw new IllegalArgumentException("Invalid service token");
12691            }
12692            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12693        }
12694    }
12695
12696    // =========================================================
12697    // BACKUP AND RESTORE
12698    // =========================================================
12699
12700    // Cause the target app to be launched if necessary and its backup agent
12701    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12702    // activity manager to announce its creation.
12703    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12704        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12705        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12706
12707        synchronized(this) {
12708            // !!! TODO: currently no check here that we're already bound
12709            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12710            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12711            synchronized (stats) {
12712                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12713            }
12714
12715            // Backup agent is now in use, its package can't be stopped.
12716            try {
12717                AppGlobals.getPackageManager().setPackageStoppedState(
12718                        app.packageName, false, UserHandle.getUserId(app.uid));
12719            } catch (RemoteException e) {
12720            } catch (IllegalArgumentException e) {
12721                Slog.w(TAG, "Failed trying to unstop package "
12722                        + app.packageName + ": " + e);
12723            }
12724
12725            BackupRecord r = new BackupRecord(ss, app, backupMode);
12726            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12727                    ? new ComponentName(app.packageName, app.backupAgentName)
12728                    : new ComponentName("android", "FullBackupAgent");
12729            // startProcessLocked() returns existing proc's record if it's already running
12730            ProcessRecord proc = startProcessLocked(app.processName, app,
12731                    false, 0, "backup", hostingName, false, false, false);
12732            if (proc == null) {
12733                Slog.e(TAG, "Unable to start backup agent process " + r);
12734                return false;
12735            }
12736
12737            r.app = proc;
12738            mBackupTarget = r;
12739            mBackupAppName = app.packageName;
12740
12741            // Try not to kill the process during backup
12742            updateOomAdjLocked(proc);
12743
12744            // If the process is already attached, schedule the creation of the backup agent now.
12745            // If it is not yet live, this will be done when it attaches to the framework.
12746            if (proc.thread != null) {
12747                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12748                try {
12749                    proc.thread.scheduleCreateBackupAgent(app,
12750                            compatibilityInfoForPackageLocked(app), backupMode);
12751                } catch (RemoteException e) {
12752                    // Will time out on the backup manager side
12753                }
12754            } else {
12755                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12756            }
12757            // Invariants: at this point, the target app process exists and the application
12758            // is either already running or in the process of coming up.  mBackupTarget and
12759            // mBackupAppName describe the app, so that when it binds back to the AM we
12760            // know that it's scheduled for a backup-agent operation.
12761        }
12762
12763        return true;
12764    }
12765
12766    @Override
12767    public void clearPendingBackup() {
12768        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12769        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12770
12771        synchronized (this) {
12772            mBackupTarget = null;
12773            mBackupAppName = null;
12774        }
12775    }
12776
12777    // A backup agent has just come up
12778    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12779        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12780                + " = " + agent);
12781
12782        synchronized(this) {
12783            if (!agentPackageName.equals(mBackupAppName)) {
12784                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12785                return;
12786            }
12787        }
12788
12789        long oldIdent = Binder.clearCallingIdentity();
12790        try {
12791            IBackupManager bm = IBackupManager.Stub.asInterface(
12792                    ServiceManager.getService(Context.BACKUP_SERVICE));
12793            bm.agentConnected(agentPackageName, agent);
12794        } catch (RemoteException e) {
12795            // can't happen; the backup manager service is local
12796        } catch (Exception e) {
12797            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12798            e.printStackTrace();
12799        } finally {
12800            Binder.restoreCallingIdentity(oldIdent);
12801        }
12802    }
12803
12804    // done with this agent
12805    public void unbindBackupAgent(ApplicationInfo appInfo) {
12806        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12807        if (appInfo == null) {
12808            Slog.w(TAG, "unbind backup agent for null app");
12809            return;
12810        }
12811
12812        synchronized(this) {
12813            try {
12814                if (mBackupAppName == null) {
12815                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12816                    return;
12817                }
12818
12819                if (!mBackupAppName.equals(appInfo.packageName)) {
12820                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12821                    return;
12822                }
12823
12824                // Not backing this app up any more; reset its OOM adjustment
12825                final ProcessRecord proc = mBackupTarget.app;
12826                updateOomAdjLocked(proc);
12827
12828                // If the app crashed during backup, 'thread' will be null here
12829                if (proc.thread != null) {
12830                    try {
12831                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12832                                compatibilityInfoForPackageLocked(appInfo));
12833                    } catch (Exception e) {
12834                        Slog.e(TAG, "Exception when unbinding backup agent:");
12835                        e.printStackTrace();
12836                    }
12837                }
12838            } finally {
12839                mBackupTarget = null;
12840                mBackupAppName = null;
12841            }
12842        }
12843    }
12844    // =========================================================
12845    // BROADCASTS
12846    // =========================================================
12847
12848    private final List getStickiesLocked(String action, IntentFilter filter,
12849            List cur, int userId) {
12850        final ContentResolver resolver = mContext.getContentResolver();
12851        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12852        if (stickies == null) {
12853            return cur;
12854        }
12855        final ArrayList<Intent> list = stickies.get(action);
12856        if (list == null) {
12857            return cur;
12858        }
12859        int N = list.size();
12860        for (int i=0; i<N; i++) {
12861            Intent intent = list.get(i);
12862            if (filter.match(resolver, intent, true, TAG) >= 0) {
12863                if (cur == null) {
12864                    cur = new ArrayList<Intent>();
12865                }
12866                cur.add(intent);
12867            }
12868        }
12869        return cur;
12870    }
12871
12872    boolean isPendingBroadcastProcessLocked(int pid) {
12873        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12874                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12875    }
12876
12877    void skipPendingBroadcastLocked(int pid) {
12878            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12879            for (BroadcastQueue queue : mBroadcastQueues) {
12880                queue.skipPendingBroadcastLocked(pid);
12881            }
12882    }
12883
12884    // The app just attached; send any pending broadcasts that it should receive
12885    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12886        boolean didSomething = false;
12887        for (BroadcastQueue queue : mBroadcastQueues) {
12888            didSomething |= queue.sendPendingBroadcastsLocked(app);
12889        }
12890        return didSomething;
12891    }
12892
12893    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12894            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12895        enforceNotIsolatedCaller("registerReceiver");
12896        int callingUid;
12897        int callingPid;
12898        synchronized(this) {
12899            ProcessRecord callerApp = null;
12900            if (caller != null) {
12901                callerApp = getRecordForAppLocked(caller);
12902                if (callerApp == null) {
12903                    throw new SecurityException(
12904                            "Unable to find app for caller " + caller
12905                            + " (pid=" + Binder.getCallingPid()
12906                            + ") when registering receiver " + receiver);
12907                }
12908                if (callerApp.info.uid != Process.SYSTEM_UID &&
12909                        !callerApp.pkgList.containsKey(callerPackage) &&
12910                        !"android".equals(callerPackage)) {
12911                    throw new SecurityException("Given caller package " + callerPackage
12912                            + " is not running in process " + callerApp);
12913                }
12914                callingUid = callerApp.info.uid;
12915                callingPid = callerApp.pid;
12916            } else {
12917                callerPackage = null;
12918                callingUid = Binder.getCallingUid();
12919                callingPid = Binder.getCallingPid();
12920            }
12921
12922            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12923                    true, true, "registerReceiver", callerPackage);
12924
12925            List allSticky = null;
12926
12927            // Look for any matching sticky broadcasts...
12928            Iterator actions = filter.actionsIterator();
12929            if (actions != null) {
12930                while (actions.hasNext()) {
12931                    String action = (String)actions.next();
12932                    allSticky = getStickiesLocked(action, filter, allSticky,
12933                            UserHandle.USER_ALL);
12934                    allSticky = getStickiesLocked(action, filter, allSticky,
12935                            UserHandle.getUserId(callingUid));
12936                }
12937            } else {
12938                allSticky = getStickiesLocked(null, filter, allSticky,
12939                        UserHandle.USER_ALL);
12940                allSticky = getStickiesLocked(null, filter, allSticky,
12941                        UserHandle.getUserId(callingUid));
12942            }
12943
12944            // The first sticky in the list is returned directly back to
12945            // the client.
12946            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12947
12948            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12949                    + ": " + sticky);
12950
12951            if (receiver == null) {
12952                return sticky;
12953            }
12954
12955            ReceiverList rl
12956                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12957            if (rl == null) {
12958                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
12959                        userId, receiver);
12960                if (rl.app != null) {
12961                    rl.app.receivers.add(rl);
12962                } else {
12963                    try {
12964                        receiver.asBinder().linkToDeath(rl, 0);
12965                    } catch (RemoteException e) {
12966                        return sticky;
12967                    }
12968                    rl.linkedToDeath = true;
12969                }
12970                mRegisteredReceivers.put(receiver.asBinder(), rl);
12971            } else if (rl.uid != callingUid) {
12972                throw new IllegalArgumentException(
12973                        "Receiver requested to register for uid " + callingUid
12974                        + " was previously registered for uid " + rl.uid);
12975            } else if (rl.pid != callingPid) {
12976                throw new IllegalArgumentException(
12977                        "Receiver requested to register for pid " + callingPid
12978                        + " was previously registered for pid " + rl.pid);
12979            } else if (rl.userId != userId) {
12980                throw new IllegalArgumentException(
12981                        "Receiver requested to register for user " + userId
12982                        + " was previously registered for user " + rl.userId);
12983            }
12984            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
12985                    permission, callingUid, userId);
12986            rl.add(bf);
12987            if (!bf.debugCheck()) {
12988                Slog.w(TAG, "==> For Dynamic broadast");
12989            }
12990            mReceiverResolver.addFilter(bf);
12991
12992            // Enqueue broadcasts for all existing stickies that match
12993            // this filter.
12994            if (allSticky != null) {
12995                ArrayList receivers = new ArrayList();
12996                receivers.add(bf);
12997
12998                int N = allSticky.size();
12999                for (int i=0; i<N; i++) {
13000                    Intent intent = (Intent)allSticky.get(i);
13001                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13002                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13003                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13004                            null, null, false, true, true, -1);
13005                    queue.enqueueParallelBroadcastLocked(r);
13006                    queue.scheduleBroadcastsLocked();
13007                }
13008            }
13009
13010            return sticky;
13011        }
13012    }
13013
13014    public void unregisterReceiver(IIntentReceiver receiver) {
13015        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13016
13017        final long origId = Binder.clearCallingIdentity();
13018        try {
13019            boolean doTrim = false;
13020
13021            synchronized(this) {
13022                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13023                if (rl != null) {
13024                    if (rl.curBroadcast != null) {
13025                        BroadcastRecord r = rl.curBroadcast;
13026                        final boolean doNext = finishReceiverLocked(
13027                                receiver.asBinder(), r.resultCode, r.resultData,
13028                                r.resultExtras, r.resultAbort);
13029                        if (doNext) {
13030                            doTrim = true;
13031                            r.queue.processNextBroadcast(false);
13032                        }
13033                    }
13034
13035                    if (rl.app != null) {
13036                        rl.app.receivers.remove(rl);
13037                    }
13038                    removeReceiverLocked(rl);
13039                    if (rl.linkedToDeath) {
13040                        rl.linkedToDeath = false;
13041                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13042                    }
13043                }
13044            }
13045
13046            // If we actually concluded any broadcasts, we might now be able
13047            // to trim the recipients' apps from our working set
13048            if (doTrim) {
13049                trimApplications();
13050                return;
13051            }
13052
13053        } finally {
13054            Binder.restoreCallingIdentity(origId);
13055        }
13056    }
13057
13058    void removeReceiverLocked(ReceiverList rl) {
13059        mRegisteredReceivers.remove(rl.receiver.asBinder());
13060        int N = rl.size();
13061        for (int i=0; i<N; i++) {
13062            mReceiverResolver.removeFilter(rl.get(i));
13063        }
13064    }
13065
13066    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13067        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13068            ProcessRecord r = mLruProcesses.get(i);
13069            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13070                try {
13071                    r.thread.dispatchPackageBroadcast(cmd, packages);
13072                } catch (RemoteException ex) {
13073                }
13074            }
13075        }
13076    }
13077
13078    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13079            int[] users) {
13080        List<ResolveInfo> receivers = null;
13081        try {
13082            HashSet<ComponentName> singleUserReceivers = null;
13083            boolean scannedFirstReceivers = false;
13084            for (int user : users) {
13085                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13086                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13087                if (user != 0 && newReceivers != null) {
13088                    // If this is not the primary user, we need to check for
13089                    // any receivers that should be filtered out.
13090                    for (int i=0; i<newReceivers.size(); i++) {
13091                        ResolveInfo ri = newReceivers.get(i);
13092                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13093                            newReceivers.remove(i);
13094                            i--;
13095                        }
13096                    }
13097                }
13098                if (newReceivers != null && newReceivers.size() == 0) {
13099                    newReceivers = null;
13100                }
13101                if (receivers == null) {
13102                    receivers = newReceivers;
13103                } else if (newReceivers != null) {
13104                    // We need to concatenate the additional receivers
13105                    // found with what we have do far.  This would be easy,
13106                    // but we also need to de-dup any receivers that are
13107                    // singleUser.
13108                    if (!scannedFirstReceivers) {
13109                        // Collect any single user receivers we had already retrieved.
13110                        scannedFirstReceivers = true;
13111                        for (int i=0; i<receivers.size(); i++) {
13112                            ResolveInfo ri = receivers.get(i);
13113                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13114                                ComponentName cn = new ComponentName(
13115                                        ri.activityInfo.packageName, ri.activityInfo.name);
13116                                if (singleUserReceivers == null) {
13117                                    singleUserReceivers = new HashSet<ComponentName>();
13118                                }
13119                                singleUserReceivers.add(cn);
13120                            }
13121                        }
13122                    }
13123                    // Add the new results to the existing results, tracking
13124                    // and de-dupping single user receivers.
13125                    for (int i=0; i<newReceivers.size(); i++) {
13126                        ResolveInfo ri = newReceivers.get(i);
13127                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13128                            ComponentName cn = new ComponentName(
13129                                    ri.activityInfo.packageName, ri.activityInfo.name);
13130                            if (singleUserReceivers == null) {
13131                                singleUserReceivers = new HashSet<ComponentName>();
13132                            }
13133                            if (!singleUserReceivers.contains(cn)) {
13134                                singleUserReceivers.add(cn);
13135                                receivers.add(ri);
13136                            }
13137                        } else {
13138                            receivers.add(ri);
13139                        }
13140                    }
13141                }
13142            }
13143        } catch (RemoteException ex) {
13144            // pm is in same process, this will never happen.
13145        }
13146        return receivers;
13147    }
13148
13149    private final int broadcastIntentLocked(ProcessRecord callerApp,
13150            String callerPackage, Intent intent, String resolvedType,
13151            IIntentReceiver resultTo, int resultCode, String resultData,
13152            Bundle map, String requiredPermission, int appOp,
13153            boolean ordered, boolean sticky, int callingPid, int callingUid,
13154            int userId) {
13155        intent = new Intent(intent);
13156
13157        // By default broadcasts do not go to stopped apps.
13158        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13159
13160        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13161            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13162            + " ordered=" + ordered + " userid=" + userId);
13163        if ((resultTo != null) && !ordered) {
13164            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13165        }
13166
13167        userId = handleIncomingUser(callingPid, callingUid, userId,
13168                true, false, "broadcast", callerPackage);
13169
13170        // Make sure that the user who is receiving this broadcast is started.
13171        // If not, we will just skip it.
13172        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13173            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13174                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13175                Slog.w(TAG, "Skipping broadcast of " + intent
13176                        + ": user " + userId + " is stopped");
13177                return ActivityManager.BROADCAST_SUCCESS;
13178            }
13179        }
13180
13181        /*
13182         * Prevent non-system code (defined here to be non-persistent
13183         * processes) from sending protected broadcasts.
13184         */
13185        int callingAppId = UserHandle.getAppId(callingUid);
13186        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13187            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13188            callingUid == 0) {
13189            // Always okay.
13190        } else if (callerApp == null || !callerApp.persistent) {
13191            try {
13192                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13193                        intent.getAction())) {
13194                    String msg = "Permission Denial: not allowed to send broadcast "
13195                            + intent.getAction() + " from pid="
13196                            + callingPid + ", uid=" + callingUid;
13197                    Slog.w(TAG, msg);
13198                    throw new SecurityException(msg);
13199                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13200                    // Special case for compatibility: we don't want apps to send this,
13201                    // but historically it has not been protected and apps may be using it
13202                    // to poke their own app widget.  So, instead of making it protected,
13203                    // just limit it to the caller.
13204                    if (callerApp == null) {
13205                        String msg = "Permission Denial: not allowed to send broadcast "
13206                                + intent.getAction() + " from unknown caller.";
13207                        Slog.w(TAG, msg);
13208                        throw new SecurityException(msg);
13209                    } else if (intent.getComponent() != null) {
13210                        // They are good enough to send to an explicit component...  verify
13211                        // it is being sent to the calling app.
13212                        if (!intent.getComponent().getPackageName().equals(
13213                                callerApp.info.packageName)) {
13214                            String msg = "Permission Denial: not allowed to send broadcast "
13215                                    + intent.getAction() + " to "
13216                                    + intent.getComponent().getPackageName() + " from "
13217                                    + callerApp.info.packageName;
13218                            Slog.w(TAG, msg);
13219                            throw new SecurityException(msg);
13220                        }
13221                    } else {
13222                        // Limit broadcast to their own package.
13223                        intent.setPackage(callerApp.info.packageName);
13224                    }
13225                }
13226            } catch (RemoteException e) {
13227                Slog.w(TAG, "Remote exception", e);
13228                return ActivityManager.BROADCAST_SUCCESS;
13229            }
13230        }
13231
13232        // Handle special intents: if this broadcast is from the package
13233        // manager about a package being removed, we need to remove all of
13234        // its activities from the history stack.
13235        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13236                intent.getAction());
13237        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13238                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13239                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13240                || uidRemoved) {
13241            if (checkComponentPermission(
13242                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13243                    callingPid, callingUid, -1, true)
13244                    == PackageManager.PERMISSION_GRANTED) {
13245                if (uidRemoved) {
13246                    final Bundle intentExtras = intent.getExtras();
13247                    final int uid = intentExtras != null
13248                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13249                    if (uid >= 0) {
13250                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13251                        synchronized (bs) {
13252                            bs.removeUidStatsLocked(uid);
13253                        }
13254                        mAppOpsService.uidRemoved(uid);
13255                    }
13256                } else {
13257                    // If resources are unavailable just force stop all
13258                    // those packages and flush the attribute cache as well.
13259                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13260                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13261                        if (list != null && (list.length > 0)) {
13262                            for (String pkg : list) {
13263                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
13264                                        "storage unmount");
13265                            }
13266                            sendPackageBroadcastLocked(
13267                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13268                        }
13269                    } else {
13270                        Uri data = intent.getData();
13271                        String ssp;
13272                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13273                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13274                                    intent.getAction());
13275                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13276                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13277                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13278                                        false, userId, removed ? "pkg removed" : "pkg changed");
13279                            }
13280                            if (removed) {
13281                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13282                                        new String[] {ssp}, userId);
13283                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13284                                    mAppOpsService.packageRemoved(
13285                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13286
13287                                    // Remove all permissions granted from/to this package
13288                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13289                                }
13290                            }
13291                        }
13292                    }
13293                }
13294            } else {
13295                String msg = "Permission Denial: " + intent.getAction()
13296                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13297                        + ", uid=" + callingUid + ")"
13298                        + " requires "
13299                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13300                Slog.w(TAG, msg);
13301                throw new SecurityException(msg);
13302            }
13303
13304        // Special case for adding a package: by default turn on compatibility
13305        // mode.
13306        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13307            Uri data = intent.getData();
13308            String ssp;
13309            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13310                mCompatModePackages.handlePackageAddedLocked(ssp,
13311                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13312            }
13313        }
13314
13315        /*
13316         * If this is the time zone changed action, queue up a message that will reset the timezone
13317         * of all currently running processes. This message will get queued up before the broadcast
13318         * happens.
13319         */
13320        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13321            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13322        }
13323
13324        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13325            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13326        }
13327
13328        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13329            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13330            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13331        }
13332
13333        // Add to the sticky list if requested.
13334        if (sticky) {
13335            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13336                    callingPid, callingUid)
13337                    != PackageManager.PERMISSION_GRANTED) {
13338                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13339                        + callingPid + ", uid=" + callingUid
13340                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13341                Slog.w(TAG, msg);
13342                throw new SecurityException(msg);
13343            }
13344            if (requiredPermission != null) {
13345                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13346                        + " and enforce permission " + requiredPermission);
13347                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13348            }
13349            if (intent.getComponent() != null) {
13350                throw new SecurityException(
13351                        "Sticky broadcasts can't target a specific component");
13352            }
13353            // We use userId directly here, since the "all" target is maintained
13354            // as a separate set of sticky broadcasts.
13355            if (userId != UserHandle.USER_ALL) {
13356                // But first, if this is not a broadcast to all users, then
13357                // make sure it doesn't conflict with an existing broadcast to
13358                // all users.
13359                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13360                        UserHandle.USER_ALL);
13361                if (stickies != null) {
13362                    ArrayList<Intent> list = stickies.get(intent.getAction());
13363                    if (list != null) {
13364                        int N = list.size();
13365                        int i;
13366                        for (i=0; i<N; i++) {
13367                            if (intent.filterEquals(list.get(i))) {
13368                                throw new IllegalArgumentException(
13369                                        "Sticky broadcast " + intent + " for user "
13370                                        + userId + " conflicts with existing global broadcast");
13371                            }
13372                        }
13373                    }
13374                }
13375            }
13376            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13377            if (stickies == null) {
13378                stickies = new ArrayMap<String, ArrayList<Intent>>();
13379                mStickyBroadcasts.put(userId, stickies);
13380            }
13381            ArrayList<Intent> list = stickies.get(intent.getAction());
13382            if (list == null) {
13383                list = new ArrayList<Intent>();
13384                stickies.put(intent.getAction(), list);
13385            }
13386            int N = list.size();
13387            int i;
13388            for (i=0; i<N; i++) {
13389                if (intent.filterEquals(list.get(i))) {
13390                    // This sticky already exists, replace it.
13391                    list.set(i, new Intent(intent));
13392                    break;
13393                }
13394            }
13395            if (i >= N) {
13396                list.add(new Intent(intent));
13397            }
13398        }
13399
13400        int[] users;
13401        if (userId == UserHandle.USER_ALL) {
13402            // Caller wants broadcast to go to all started users.
13403            users = mStartedUserArray;
13404        } else {
13405            // Caller wants broadcast to go to one specific user.
13406            users = new int[] {userId};
13407        }
13408
13409        // Figure out who all will receive this broadcast.
13410        List receivers = null;
13411        List<BroadcastFilter> registeredReceivers = null;
13412        // Need to resolve the intent to interested receivers...
13413        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13414                 == 0) {
13415            receivers = collectReceiverComponents(intent, resolvedType, users);
13416        }
13417        if (intent.getComponent() == null) {
13418            registeredReceivers = mReceiverResolver.queryIntent(intent,
13419                    resolvedType, false, userId);
13420        }
13421
13422        final boolean replacePending =
13423                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13424
13425        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13426                + " replacePending=" + replacePending);
13427
13428        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13429        if (!ordered && NR > 0) {
13430            // If we are not serializing this broadcast, then send the
13431            // registered receivers separately so they don't wait for the
13432            // components to be launched.
13433            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13434            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13435                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13436                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13437                    ordered, sticky, false, userId);
13438            if (DEBUG_BROADCAST) Slog.v(
13439                    TAG, "Enqueueing parallel broadcast " + r);
13440            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13441            if (!replaced) {
13442                queue.enqueueParallelBroadcastLocked(r);
13443                queue.scheduleBroadcastsLocked();
13444            }
13445            registeredReceivers = null;
13446            NR = 0;
13447        }
13448
13449        // Merge into one list.
13450        int ir = 0;
13451        if (receivers != null) {
13452            // A special case for PACKAGE_ADDED: do not allow the package
13453            // being added to see this broadcast.  This prevents them from
13454            // using this as a back door to get run as soon as they are
13455            // installed.  Maybe in the future we want to have a special install
13456            // broadcast or such for apps, but we'd like to deliberately make
13457            // this decision.
13458            String skipPackages[] = null;
13459            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13460                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13461                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13462                Uri data = intent.getData();
13463                if (data != null) {
13464                    String pkgName = data.getSchemeSpecificPart();
13465                    if (pkgName != null) {
13466                        skipPackages = new String[] { pkgName };
13467                    }
13468                }
13469            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13470                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13471            }
13472            if (skipPackages != null && (skipPackages.length > 0)) {
13473                for (String skipPackage : skipPackages) {
13474                    if (skipPackage != null) {
13475                        int NT = receivers.size();
13476                        for (int it=0; it<NT; it++) {
13477                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13478                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13479                                receivers.remove(it);
13480                                it--;
13481                                NT--;
13482                            }
13483                        }
13484                    }
13485                }
13486            }
13487
13488            int NT = receivers != null ? receivers.size() : 0;
13489            int it = 0;
13490            ResolveInfo curt = null;
13491            BroadcastFilter curr = null;
13492            while (it < NT && ir < NR) {
13493                if (curt == null) {
13494                    curt = (ResolveInfo)receivers.get(it);
13495                }
13496                if (curr == null) {
13497                    curr = registeredReceivers.get(ir);
13498                }
13499                if (curr.getPriority() >= curt.priority) {
13500                    // Insert this broadcast record into the final list.
13501                    receivers.add(it, curr);
13502                    ir++;
13503                    curr = null;
13504                    it++;
13505                    NT++;
13506                } else {
13507                    // Skip to the next ResolveInfo in the final list.
13508                    it++;
13509                    curt = null;
13510                }
13511            }
13512        }
13513        while (ir < NR) {
13514            if (receivers == null) {
13515                receivers = new ArrayList();
13516            }
13517            receivers.add(registeredReceivers.get(ir));
13518            ir++;
13519        }
13520
13521        if ((receivers != null && receivers.size() > 0)
13522                || resultTo != null) {
13523            BroadcastQueue queue = broadcastQueueForIntent(intent);
13524            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13525                    callerPackage, callingPid, callingUid, resolvedType,
13526                    requiredPermission, appOp, receivers, resultTo, resultCode,
13527                    resultData, map, ordered, sticky, false, userId);
13528            if (DEBUG_BROADCAST) Slog.v(
13529                    TAG, "Enqueueing ordered broadcast " + r
13530                    + ": prev had " + queue.mOrderedBroadcasts.size());
13531            if (DEBUG_BROADCAST) {
13532                int seq = r.intent.getIntExtra("seq", -1);
13533                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13534            }
13535            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13536            if (!replaced) {
13537                queue.enqueueOrderedBroadcastLocked(r);
13538                queue.scheduleBroadcastsLocked();
13539            }
13540        }
13541
13542        return ActivityManager.BROADCAST_SUCCESS;
13543    }
13544
13545    final Intent verifyBroadcastLocked(Intent intent) {
13546        // Refuse possible leaked file descriptors
13547        if (intent != null && intent.hasFileDescriptors() == true) {
13548            throw new IllegalArgumentException("File descriptors passed in Intent");
13549        }
13550
13551        int flags = intent.getFlags();
13552
13553        if (!mProcessesReady) {
13554            // if the caller really truly claims to know what they're doing, go
13555            // ahead and allow the broadcast without launching any receivers
13556            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13557                intent = new Intent(intent);
13558                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13559            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13560                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13561                        + " before boot completion");
13562                throw new IllegalStateException("Cannot broadcast before boot completed");
13563            }
13564        }
13565
13566        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13567            throw new IllegalArgumentException(
13568                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13569        }
13570
13571        return intent;
13572    }
13573
13574    public final int broadcastIntent(IApplicationThread caller,
13575            Intent intent, String resolvedType, IIntentReceiver resultTo,
13576            int resultCode, String resultData, Bundle map,
13577            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13578        enforceNotIsolatedCaller("broadcastIntent");
13579        synchronized(this) {
13580            intent = verifyBroadcastLocked(intent);
13581
13582            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13583            final int callingPid = Binder.getCallingPid();
13584            final int callingUid = Binder.getCallingUid();
13585            final long origId = Binder.clearCallingIdentity();
13586            int res = broadcastIntentLocked(callerApp,
13587                    callerApp != null ? callerApp.info.packageName : null,
13588                    intent, resolvedType, resultTo,
13589                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13590                    callingPid, callingUid, userId);
13591            Binder.restoreCallingIdentity(origId);
13592            return res;
13593        }
13594    }
13595
13596    int broadcastIntentInPackage(String packageName, int uid,
13597            Intent intent, String resolvedType, IIntentReceiver resultTo,
13598            int resultCode, String resultData, Bundle map,
13599            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13600        synchronized(this) {
13601            intent = verifyBroadcastLocked(intent);
13602
13603            final long origId = Binder.clearCallingIdentity();
13604            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13605                    resultTo, resultCode, resultData, map, requiredPermission,
13606                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13607            Binder.restoreCallingIdentity(origId);
13608            return res;
13609        }
13610    }
13611
13612    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13613        // Refuse possible leaked file descriptors
13614        if (intent != null && intent.hasFileDescriptors() == true) {
13615            throw new IllegalArgumentException("File descriptors passed in Intent");
13616        }
13617
13618        userId = handleIncomingUser(Binder.getCallingPid(),
13619                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13620
13621        synchronized(this) {
13622            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13623                    != PackageManager.PERMISSION_GRANTED) {
13624                String msg = "Permission Denial: unbroadcastIntent() from pid="
13625                        + Binder.getCallingPid()
13626                        + ", uid=" + Binder.getCallingUid()
13627                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13628                Slog.w(TAG, msg);
13629                throw new SecurityException(msg);
13630            }
13631            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13632            if (stickies != null) {
13633                ArrayList<Intent> list = stickies.get(intent.getAction());
13634                if (list != null) {
13635                    int N = list.size();
13636                    int i;
13637                    for (i=0; i<N; i++) {
13638                        if (intent.filterEquals(list.get(i))) {
13639                            list.remove(i);
13640                            break;
13641                        }
13642                    }
13643                    if (list.size() <= 0) {
13644                        stickies.remove(intent.getAction());
13645                    }
13646                }
13647                if (stickies.size() <= 0) {
13648                    mStickyBroadcasts.remove(userId);
13649                }
13650            }
13651        }
13652    }
13653
13654    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13655            String resultData, Bundle resultExtras, boolean resultAbort) {
13656        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13657        if (r == null) {
13658            Slog.w(TAG, "finishReceiver called but not found on queue");
13659            return false;
13660        }
13661
13662        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13663    }
13664
13665    void backgroundServicesFinishedLocked(int userId) {
13666        for (BroadcastQueue queue : mBroadcastQueues) {
13667            queue.backgroundServicesFinishedLocked(userId);
13668        }
13669    }
13670
13671    public void finishReceiver(IBinder who, int resultCode, String resultData,
13672            Bundle resultExtras, boolean resultAbort) {
13673        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13674
13675        // Refuse possible leaked file descriptors
13676        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13677            throw new IllegalArgumentException("File descriptors passed in Bundle");
13678        }
13679
13680        final long origId = Binder.clearCallingIdentity();
13681        try {
13682            boolean doNext = false;
13683            BroadcastRecord r;
13684
13685            synchronized(this) {
13686                r = broadcastRecordForReceiverLocked(who);
13687                if (r != null) {
13688                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13689                        resultData, resultExtras, resultAbort, true);
13690                }
13691            }
13692
13693            if (doNext) {
13694                r.queue.processNextBroadcast(false);
13695            }
13696            trimApplications();
13697        } finally {
13698            Binder.restoreCallingIdentity(origId);
13699        }
13700    }
13701
13702    // =========================================================
13703    // INSTRUMENTATION
13704    // =========================================================
13705
13706    public boolean startInstrumentation(ComponentName className,
13707            String profileFile, int flags, Bundle arguments,
13708            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13709            int userId) {
13710        enforceNotIsolatedCaller("startInstrumentation");
13711        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13712                userId, false, true, "startInstrumentation", null);
13713        // Refuse possible leaked file descriptors
13714        if (arguments != null && arguments.hasFileDescriptors()) {
13715            throw new IllegalArgumentException("File descriptors passed in Bundle");
13716        }
13717
13718        synchronized(this) {
13719            InstrumentationInfo ii = null;
13720            ApplicationInfo ai = null;
13721            try {
13722                ii = mContext.getPackageManager().getInstrumentationInfo(
13723                    className, STOCK_PM_FLAGS);
13724                ai = AppGlobals.getPackageManager().getApplicationInfo(
13725                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13726            } catch (PackageManager.NameNotFoundException e) {
13727            } catch (RemoteException e) {
13728            }
13729            if (ii == null) {
13730                reportStartInstrumentationFailure(watcher, className,
13731                        "Unable to find instrumentation info for: " + className);
13732                return false;
13733            }
13734            if (ai == null) {
13735                reportStartInstrumentationFailure(watcher, className,
13736                        "Unable to find instrumentation target package: " + ii.targetPackage);
13737                return false;
13738            }
13739
13740            int match = mContext.getPackageManager().checkSignatures(
13741                    ii.targetPackage, ii.packageName);
13742            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13743                String msg = "Permission Denial: starting instrumentation "
13744                        + className + " from pid="
13745                        + Binder.getCallingPid()
13746                        + ", uid=" + Binder.getCallingPid()
13747                        + " not allowed because package " + ii.packageName
13748                        + " does not have a signature matching the target "
13749                        + ii.targetPackage;
13750                reportStartInstrumentationFailure(watcher, className, msg);
13751                throw new SecurityException(msg);
13752            }
13753
13754            final long origId = Binder.clearCallingIdentity();
13755            // Instrumentation can kill and relaunch even persistent processes
13756            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
13757                    "start instr");
13758            ProcessRecord app = addAppLocked(ai, false);
13759            app.instrumentationClass = className;
13760            app.instrumentationInfo = ai;
13761            app.instrumentationProfileFile = profileFile;
13762            app.instrumentationArguments = arguments;
13763            app.instrumentationWatcher = watcher;
13764            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13765            app.instrumentationResultClass = className;
13766            Binder.restoreCallingIdentity(origId);
13767        }
13768
13769        return true;
13770    }
13771
13772    /**
13773     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13774     * error to the logs, but if somebody is watching, send the report there too.  This enables
13775     * the "am" command to report errors with more information.
13776     *
13777     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13778     * @param cn The component name of the instrumentation.
13779     * @param report The error report.
13780     */
13781    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13782            ComponentName cn, String report) {
13783        Slog.w(TAG, report);
13784        try {
13785            if (watcher != null) {
13786                Bundle results = new Bundle();
13787                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13788                results.putString("Error", report);
13789                watcher.instrumentationStatus(cn, -1, results);
13790            }
13791        } catch (RemoteException e) {
13792            Slog.w(TAG, e);
13793        }
13794    }
13795
13796    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13797        if (app.instrumentationWatcher != null) {
13798            try {
13799                // NOTE:  IInstrumentationWatcher *must* be oneway here
13800                app.instrumentationWatcher.instrumentationFinished(
13801                    app.instrumentationClass,
13802                    resultCode,
13803                    results);
13804            } catch (RemoteException e) {
13805            }
13806        }
13807        if (app.instrumentationUiAutomationConnection != null) {
13808            try {
13809                app.instrumentationUiAutomationConnection.shutdown();
13810            } catch (RemoteException re) {
13811                /* ignore */
13812            }
13813            // Only a UiAutomation can set this flag and now that
13814            // it is finished we make sure it is reset to its default.
13815            mUserIsMonkey = false;
13816        }
13817        app.instrumentationWatcher = null;
13818        app.instrumentationUiAutomationConnection = null;
13819        app.instrumentationClass = null;
13820        app.instrumentationInfo = null;
13821        app.instrumentationProfileFile = null;
13822        app.instrumentationArguments = null;
13823
13824        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
13825                "finished inst");
13826    }
13827
13828    public void finishInstrumentation(IApplicationThread target,
13829            int resultCode, Bundle results) {
13830        int userId = UserHandle.getCallingUserId();
13831        // Refuse possible leaked file descriptors
13832        if (results != null && results.hasFileDescriptors()) {
13833            throw new IllegalArgumentException("File descriptors passed in Intent");
13834        }
13835
13836        synchronized(this) {
13837            ProcessRecord app = getRecordForAppLocked(target);
13838            if (app == null) {
13839                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13840                return;
13841            }
13842            final long origId = Binder.clearCallingIdentity();
13843            finishInstrumentationLocked(app, resultCode, results);
13844            Binder.restoreCallingIdentity(origId);
13845        }
13846    }
13847
13848    // =========================================================
13849    // CONFIGURATION
13850    // =========================================================
13851
13852    public ConfigurationInfo getDeviceConfigurationInfo() {
13853        ConfigurationInfo config = new ConfigurationInfo();
13854        synchronized (this) {
13855            config.reqTouchScreen = mConfiguration.touchscreen;
13856            config.reqKeyboardType = mConfiguration.keyboard;
13857            config.reqNavigation = mConfiguration.navigation;
13858            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13859                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13860                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13861            }
13862            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13863                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13864                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13865            }
13866            config.reqGlEsVersion = GL_ES_VERSION;
13867        }
13868        return config;
13869    }
13870
13871    ActivityStack getFocusedStack() {
13872        return mStackSupervisor.getFocusedStack();
13873    }
13874
13875    public Configuration getConfiguration() {
13876        Configuration ci;
13877        synchronized(this) {
13878            ci = new Configuration(mConfiguration);
13879        }
13880        return ci;
13881    }
13882
13883    public void updatePersistentConfiguration(Configuration values) {
13884        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13885                "updateConfiguration()");
13886        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13887                "updateConfiguration()");
13888        if (values == null) {
13889            throw new NullPointerException("Configuration must not be null");
13890        }
13891
13892        synchronized(this) {
13893            final long origId = Binder.clearCallingIdentity();
13894            updateConfigurationLocked(values, null, true, false);
13895            Binder.restoreCallingIdentity(origId);
13896        }
13897    }
13898
13899    public void updateConfiguration(Configuration values) {
13900        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13901                "updateConfiguration()");
13902
13903        synchronized(this) {
13904            if (values == null && mWindowManager != null) {
13905                // sentinel: fetch the current configuration from the window manager
13906                values = mWindowManager.computeNewConfiguration();
13907            }
13908
13909            if (mWindowManager != null) {
13910                mProcessList.applyDisplaySize(mWindowManager);
13911            }
13912
13913            final long origId = Binder.clearCallingIdentity();
13914            if (values != null) {
13915                Settings.System.clearConfiguration(values);
13916            }
13917            updateConfigurationLocked(values, null, false, false);
13918            Binder.restoreCallingIdentity(origId);
13919        }
13920    }
13921
13922    /**
13923     * Do either or both things: (1) change the current configuration, and (2)
13924     * make sure the given activity is running with the (now) current
13925     * configuration.  Returns true if the activity has been left running, or
13926     * false if <var>starting</var> is being destroyed to match the new
13927     * configuration.
13928     * @param persistent TODO
13929     */
13930    boolean updateConfigurationLocked(Configuration values,
13931            ActivityRecord starting, boolean persistent, boolean initLocale) {
13932        int changes = 0;
13933
13934        if (values != null) {
13935            Configuration newConfig = new Configuration(mConfiguration);
13936            changes = newConfig.updateFrom(values);
13937            if (changes != 0) {
13938                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13939                    Slog.i(TAG, "Updating configuration to: " + values);
13940                }
13941
13942                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13943
13944                if (values.locale != null && !initLocale) {
13945                    saveLocaleLocked(values.locale,
13946                                     !values.locale.equals(mConfiguration.locale),
13947                                     values.userSetLocale);
13948                }
13949
13950                mConfigurationSeq++;
13951                if (mConfigurationSeq <= 0) {
13952                    mConfigurationSeq = 1;
13953                }
13954                newConfig.seq = mConfigurationSeq;
13955                mConfiguration = newConfig;
13956                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
13957
13958                final Configuration configCopy = new Configuration(mConfiguration);
13959
13960                // TODO: If our config changes, should we auto dismiss any currently
13961                // showing dialogs?
13962                mShowDialogs = shouldShowDialogs(newConfig);
13963
13964                AttributeCache ac = AttributeCache.instance();
13965                if (ac != null) {
13966                    ac.updateConfiguration(configCopy);
13967                }
13968
13969                // Make sure all resources in our process are updated
13970                // right now, so that anyone who is going to retrieve
13971                // resource values after we return will be sure to get
13972                // the new ones.  This is especially important during
13973                // boot, where the first config change needs to guarantee
13974                // all resources have that config before following boot
13975                // code is executed.
13976                mSystemThread.applyConfigurationToResources(configCopy);
13977
13978                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
13979                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
13980                    msg.obj = new Configuration(configCopy);
13981                    mHandler.sendMessage(msg);
13982                }
13983
13984                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13985                    ProcessRecord app = mLruProcesses.get(i);
13986                    try {
13987                        if (app.thread != null) {
13988                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
13989                                    + app.processName + " new config " + mConfiguration);
13990                            app.thread.scheduleConfigurationChanged(configCopy);
13991                        }
13992                    } catch (Exception e) {
13993                    }
13994                }
13995                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
13996                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13997                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
13998                        | Intent.FLAG_RECEIVER_FOREGROUND);
13999                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14000                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14001                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14002                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14003                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14004                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14005                    broadcastIntentLocked(null, null, intent,
14006                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14007                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14008                }
14009            }
14010        }
14011
14012        boolean kept = true;
14013        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14014        // mainStack is null during startup.
14015        if (mainStack != null) {
14016            if (changes != 0 && starting == null) {
14017                // If the configuration changed, and the caller is not already
14018                // in the process of starting an activity, then find the top
14019                // activity to check if its configuration needs to change.
14020                starting = mainStack.topRunningActivityLocked(null);
14021            }
14022
14023            if (starting != null) {
14024                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14025                // And we need to make sure at this point that all other activities
14026                // are made visible with the correct configuration.
14027                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14028            }
14029        }
14030
14031        if (values != null && mWindowManager != null) {
14032            mWindowManager.setNewConfiguration(mConfiguration);
14033        }
14034
14035        return kept;
14036    }
14037
14038    /**
14039     * Decide based on the configuration whether we should shouw the ANR,
14040     * crash, etc dialogs.  The idea is that if there is no affordnace to
14041     * press the on-screen buttons, we shouldn't show the dialog.
14042     *
14043     * A thought: SystemUI might also want to get told about this, the Power
14044     * dialog / global actions also might want different behaviors.
14045     */
14046    private static final boolean shouldShowDialogs(Configuration config) {
14047        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14048                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14049    }
14050
14051    /**
14052     * Save the locale.  You must be inside a synchronized (this) block.
14053     */
14054    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14055        if(isDiff) {
14056            SystemProperties.set("user.language", l.getLanguage());
14057            SystemProperties.set("user.region", l.getCountry());
14058        }
14059
14060        if(isPersist) {
14061            SystemProperties.set("persist.sys.language", l.getLanguage());
14062            SystemProperties.set("persist.sys.country", l.getCountry());
14063            SystemProperties.set("persist.sys.localevar", l.getVariant());
14064        }
14065    }
14066
14067    @Override
14068    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14069        ActivityRecord srec = ActivityRecord.forToken(token);
14070        return srec != null && srec.task.affinity != null &&
14071                srec.task.affinity.equals(destAffinity);
14072    }
14073
14074    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14075            Intent resultData) {
14076
14077        synchronized (this) {
14078            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14079            if (stack != null) {
14080                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14081            }
14082            return false;
14083        }
14084    }
14085
14086    public int getLaunchedFromUid(IBinder activityToken) {
14087        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14088        if (srec == null) {
14089            return -1;
14090        }
14091        return srec.launchedFromUid;
14092    }
14093
14094    public String getLaunchedFromPackage(IBinder activityToken) {
14095        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14096        if (srec == null) {
14097            return null;
14098        }
14099        return srec.launchedFromPackage;
14100    }
14101
14102    // =========================================================
14103    // LIFETIME MANAGEMENT
14104    // =========================================================
14105
14106    // Returns which broadcast queue the app is the current [or imminent] receiver
14107    // on, or 'null' if the app is not an active broadcast recipient.
14108    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14109        BroadcastRecord r = app.curReceiver;
14110        if (r != null) {
14111            return r.queue;
14112        }
14113
14114        // It's not the current receiver, but it might be starting up to become one
14115        synchronized (this) {
14116            for (BroadcastQueue queue : mBroadcastQueues) {
14117                r = queue.mPendingBroadcast;
14118                if (r != null && r.curApp == app) {
14119                    // found it; report which queue it's in
14120                    return queue;
14121                }
14122            }
14123        }
14124
14125        return null;
14126    }
14127
14128    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14129            boolean doingAll, long now) {
14130        if (mAdjSeq == app.adjSeq) {
14131            // This adjustment has already been computed.
14132            return app.curRawAdj;
14133        }
14134
14135        if (app.thread == null) {
14136            app.adjSeq = mAdjSeq;
14137            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14138            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14139            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14140        }
14141
14142        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14143        app.adjSource = null;
14144        app.adjTarget = null;
14145        app.empty = false;
14146        app.cached = false;
14147
14148        final int activitiesSize = app.activities.size();
14149
14150        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14151            // The max adjustment doesn't allow this app to be anything
14152            // below foreground, so it is not worth doing work for it.
14153            app.adjType = "fixed";
14154            app.adjSeq = mAdjSeq;
14155            app.curRawAdj = app.maxAdj;
14156            app.foregroundActivities = false;
14157            app.keeping = true;
14158            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14159            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14160            // System process can do UI, and when they do we want to have
14161            // them trim their memory after the user leaves the UI.  To
14162            // facilitate this, here we need to determine whether or not it
14163            // is currently showing UI.
14164            app.systemNoUi = true;
14165            if (app == TOP_APP) {
14166                app.systemNoUi = false;
14167            } else if (activitiesSize > 0) {
14168                for (int j = 0; j < activitiesSize; j++) {
14169                    final ActivityRecord r = app.activities.get(j);
14170                    if (r.visible) {
14171                        app.systemNoUi = false;
14172                    }
14173                }
14174            }
14175            if (!app.systemNoUi) {
14176                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14177            }
14178            return (app.curAdj=app.maxAdj);
14179        }
14180
14181        app.keeping = false;
14182        app.systemNoUi = false;
14183
14184        // Determine the importance of the process, starting with most
14185        // important to least, and assign an appropriate OOM adjustment.
14186        int adj;
14187        int schedGroup;
14188        int procState;
14189        boolean foregroundActivities = false;
14190        boolean interesting = false;
14191        BroadcastQueue queue;
14192        if (app == TOP_APP) {
14193            // The last app on the list is the foreground app.
14194            adj = ProcessList.FOREGROUND_APP_ADJ;
14195            schedGroup = Process.THREAD_GROUP_DEFAULT;
14196            app.adjType = "top-activity";
14197            foregroundActivities = true;
14198            interesting = true;
14199            procState = ActivityManager.PROCESS_STATE_TOP;
14200        } else if (app.instrumentationClass != null) {
14201            // Don't want to kill running instrumentation.
14202            adj = ProcessList.FOREGROUND_APP_ADJ;
14203            schedGroup = Process.THREAD_GROUP_DEFAULT;
14204            app.adjType = "instrumentation";
14205            interesting = true;
14206            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14207        } else if ((queue = isReceivingBroadcast(app)) != null) {
14208            // An app that is currently receiving a broadcast also
14209            // counts as being in the foreground for OOM killer purposes.
14210            // It's placed in a sched group based on the nature of the
14211            // broadcast as reflected by which queue it's active in.
14212            adj = ProcessList.FOREGROUND_APP_ADJ;
14213            schedGroup = (queue == mFgBroadcastQueue)
14214                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14215            app.adjType = "broadcast";
14216            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14217        } else if (app.executingServices.size() > 0) {
14218            // An app that is currently executing a service callback also
14219            // counts as being in the foreground.
14220            adj = ProcessList.FOREGROUND_APP_ADJ;
14221            schedGroup = app.execServicesFg ?
14222                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14223            app.adjType = "exec-service";
14224            procState = ActivityManager.PROCESS_STATE_SERVICE;
14225            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14226        } else {
14227            // As far as we know the process is empty.  We may change our mind later.
14228            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14229            // At this point we don't actually know the adjustment.  Use the cached adj
14230            // value that the caller wants us to.
14231            adj = cachedAdj;
14232            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14233            app.cached = true;
14234            app.empty = true;
14235            app.adjType = "cch-empty";
14236        }
14237
14238        // Examine all activities if not already foreground.
14239        if (!foregroundActivities && activitiesSize > 0) {
14240            for (int j = 0; j < activitiesSize; j++) {
14241                final ActivityRecord r = app.activities.get(j);
14242                if (r.app != app) {
14243                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14244                            + app + "?!?");
14245                    continue;
14246                }
14247                if (r.visible) {
14248                    // App has a visible activity; only upgrade adjustment.
14249                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14250                        adj = ProcessList.VISIBLE_APP_ADJ;
14251                        app.adjType = "visible";
14252                    }
14253                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14254                        procState = ActivityManager.PROCESS_STATE_TOP;
14255                    }
14256                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14257                    app.cached = false;
14258                    app.empty = false;
14259                    foregroundActivities = true;
14260                    break;
14261                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14262                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14263                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14264                        app.adjType = "pausing";
14265                    }
14266                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14267                        procState = ActivityManager.PROCESS_STATE_TOP;
14268                    }
14269                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14270                    app.cached = false;
14271                    app.empty = false;
14272                    foregroundActivities = true;
14273                } else if (r.state == ActivityState.STOPPING) {
14274                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14275                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14276                        app.adjType = "stopping";
14277                    }
14278                    // For the process state, we will at this point consider the
14279                    // process to be cached.  It will be cached either as an activity
14280                    // or empty depending on whether the activity is finishing.  We do
14281                    // this so that we can treat the process as cached for purposes of
14282                    // memory trimming (determing current memory level, trim command to
14283                    // send to process) since there can be an arbitrary number of stopping
14284                    // processes and they should soon all go into the cached state.
14285                    if (!r.finishing) {
14286                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14287                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14288                        }
14289                    }
14290                    app.cached = false;
14291                    app.empty = false;
14292                    foregroundActivities = true;
14293                } else {
14294                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14295                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14296                        app.adjType = "cch-act";
14297                    }
14298                }
14299            }
14300        }
14301
14302        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14303            if (app.foregroundServices) {
14304                // The user is aware of this app, so make it visible.
14305                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14306                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14307                app.cached = false;
14308                app.adjType = "fg-service";
14309                schedGroup = Process.THREAD_GROUP_DEFAULT;
14310            } else if (app.forcingToForeground != null) {
14311                // The user is aware of this app, so make it visible.
14312                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14313                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14314                app.cached = false;
14315                app.adjType = "force-fg";
14316                app.adjSource = app.forcingToForeground;
14317                schedGroup = Process.THREAD_GROUP_DEFAULT;
14318            }
14319        }
14320
14321        if (app.foregroundServices) {
14322            interesting = true;
14323        }
14324
14325        if (app == mHeavyWeightProcess) {
14326            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14327                // We don't want to kill the current heavy-weight process.
14328                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14329                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14330                app.cached = false;
14331                app.adjType = "heavy";
14332            }
14333            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14334                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14335            }
14336        }
14337
14338        if (app == mHomeProcess) {
14339            if (adj > ProcessList.HOME_APP_ADJ) {
14340                // This process is hosting what we currently consider to be the
14341                // home app, so we don't want to let it go into the background.
14342                adj = ProcessList.HOME_APP_ADJ;
14343                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14344                app.cached = false;
14345                app.adjType = "home";
14346            }
14347            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14348                procState = ActivityManager.PROCESS_STATE_HOME;
14349            }
14350        }
14351
14352        if (app == mPreviousProcess && app.activities.size() > 0) {
14353            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14354                // This was the previous process that showed UI to the user.
14355                // We want to try to keep it around more aggressively, to give
14356                // a good experience around switching between two apps.
14357                adj = ProcessList.PREVIOUS_APP_ADJ;
14358                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14359                app.cached = false;
14360                app.adjType = "previous";
14361            }
14362            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14363                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14364            }
14365        }
14366
14367        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14368                + " reason=" + app.adjType);
14369
14370        // By default, we use the computed adjustment.  It may be changed if
14371        // there are applications dependent on our services or providers, but
14372        // this gives us a baseline and makes sure we don't get into an
14373        // infinite recursion.
14374        app.adjSeq = mAdjSeq;
14375        app.curRawAdj = adj;
14376        app.hasStartedServices = false;
14377
14378        if (mBackupTarget != null && app == mBackupTarget.app) {
14379            // If possible we want to avoid killing apps while they're being backed up
14380            if (adj > ProcessList.BACKUP_APP_ADJ) {
14381                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14382                adj = ProcessList.BACKUP_APP_ADJ;
14383                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14384                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14385                }
14386                app.adjType = "backup";
14387                app.cached = false;
14388            }
14389            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14390                procState = ActivityManager.PROCESS_STATE_BACKUP;
14391            }
14392        }
14393
14394        boolean mayBeTop = false;
14395
14396        for (int is = app.services.size()-1;
14397                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14398                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14399                        || procState > ActivityManager.PROCESS_STATE_TOP);
14400                is--) {
14401            ServiceRecord s = app.services.valueAt(is);
14402            if (s.startRequested) {
14403                app.hasStartedServices = true;
14404                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14405                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14406                }
14407                if (app.hasShownUi && app != mHomeProcess) {
14408                    // If this process has shown some UI, let it immediately
14409                    // go to the LRU list because it may be pretty heavy with
14410                    // UI stuff.  We'll tag it with a label just to help
14411                    // debug and understand what is going on.
14412                    if (adj > ProcessList.SERVICE_ADJ) {
14413                        app.adjType = "cch-started-ui-services";
14414                    }
14415                } else {
14416                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14417                        // This service has seen some activity within
14418                        // recent memory, so we will keep its process ahead
14419                        // of the background processes.
14420                        if (adj > ProcessList.SERVICE_ADJ) {
14421                            adj = ProcessList.SERVICE_ADJ;
14422                            app.adjType = "started-services";
14423                            app.cached = false;
14424                        }
14425                    }
14426                    // If we have let the service slide into the background
14427                    // state, still have some text describing what it is doing
14428                    // even though the service no longer has an impact.
14429                    if (adj > ProcessList.SERVICE_ADJ) {
14430                        app.adjType = "cch-started-services";
14431                    }
14432                }
14433                // Don't kill this process because it is doing work; it
14434                // has said it is doing work.
14435                app.keeping = true;
14436            }
14437            for (int conni = s.connections.size()-1;
14438                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14439                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14440                            || procState > ActivityManager.PROCESS_STATE_TOP);
14441                    conni--) {
14442                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14443                for (int i = 0;
14444                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14445                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14446                                || procState > ActivityManager.PROCESS_STATE_TOP);
14447                        i++) {
14448                    // XXX should compute this based on the max of
14449                    // all connected clients.
14450                    ConnectionRecord cr = clist.get(i);
14451                    if (cr.binding.client == app) {
14452                        // Binding to ourself is not interesting.
14453                        continue;
14454                    }
14455                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14456                        ProcessRecord client = cr.binding.client;
14457                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14458                                TOP_APP, doingAll, now);
14459                        int clientProcState = client.curProcState;
14460                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14461                            // If the other app is cached for any reason, for purposes here
14462                            // we are going to consider it empty.  The specific cached state
14463                            // doesn't propagate except under certain conditions.
14464                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14465                        }
14466                        String adjType = null;
14467                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14468                            // Not doing bind OOM management, so treat
14469                            // this guy more like a started service.
14470                            if (app.hasShownUi && app != mHomeProcess) {
14471                                // If this process has shown some UI, let it immediately
14472                                // go to the LRU list because it may be pretty heavy with
14473                                // UI stuff.  We'll tag it with a label just to help
14474                                // debug and understand what is going on.
14475                                if (adj > clientAdj) {
14476                                    adjType = "cch-bound-ui-services";
14477                                }
14478                                app.cached = false;
14479                                clientAdj = adj;
14480                                clientProcState = procState;
14481                            } else {
14482                                if (now >= (s.lastActivity
14483                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14484                                    // This service has not seen activity within
14485                                    // recent memory, so allow it to drop to the
14486                                    // LRU list if there is no other reason to keep
14487                                    // it around.  We'll also tag it with a label just
14488                                    // to help debug and undertand what is going on.
14489                                    if (adj > clientAdj) {
14490                                        adjType = "cch-bound-services";
14491                                    }
14492                                    clientAdj = adj;
14493                                }
14494                            }
14495                        }
14496                        if (adj > clientAdj) {
14497                            // If this process has recently shown UI, and
14498                            // the process that is binding to it is less
14499                            // important than being visible, then we don't
14500                            // care about the binding as much as we care
14501                            // about letting this process get into the LRU
14502                            // list to be killed and restarted if needed for
14503                            // memory.
14504                            if (app.hasShownUi && app != mHomeProcess
14505                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14506                                adjType = "cch-bound-ui-services";
14507                            } else {
14508                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14509                                        |Context.BIND_IMPORTANT)) != 0) {
14510                                    adj = clientAdj;
14511                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14512                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14513                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14514                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14515                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14516                                    adj = clientAdj;
14517                                } else {
14518                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14519                                        adj = ProcessList.VISIBLE_APP_ADJ;
14520                                    }
14521                                }
14522                                if (!client.cached) {
14523                                    app.cached = false;
14524                                }
14525                                if (client.keeping) {
14526                                    app.keeping = true;
14527                                }
14528                                adjType = "service";
14529                            }
14530                        }
14531                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14532                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14533                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14534                            }
14535                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14536                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14537                                    // Special handling of clients who are in the top state.
14538                                    // We *may* want to consider this process to be in the
14539                                    // top state as well, but only if there is not another
14540                                    // reason for it to be running.  Being on the top is a
14541                                    // special state, meaning you are specifically running
14542                                    // for the current top app.  If the process is already
14543                                    // running in the background for some other reason, it
14544                                    // is more important to continue considering it to be
14545                                    // in the background state.
14546                                    mayBeTop = true;
14547                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14548                                } else {
14549                                    // Special handling for above-top states (persistent
14550                                    // processes).  These should not bring the current process
14551                                    // into the top state, since they are not on top.  Instead
14552                                    // give them the best state after that.
14553                                    clientProcState =
14554                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14555                                }
14556                            }
14557                        } else {
14558                            if (clientProcState <
14559                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14560                                clientProcState =
14561                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14562                            }
14563                        }
14564                        if (procState > clientProcState) {
14565                            procState = clientProcState;
14566                        }
14567                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14568                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14569                            app.pendingUiClean = true;
14570                        }
14571                        if (adjType != null) {
14572                            app.adjType = adjType;
14573                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14574                                    .REASON_SERVICE_IN_USE;
14575                            app.adjSource = cr.binding.client;
14576                            app.adjSourceOom = clientAdj;
14577                            app.adjTarget = s.name;
14578                        }
14579                    }
14580                    final ActivityRecord a = cr.activity;
14581                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14582                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14583                                (a.visible || a.state == ActivityState.RESUMED
14584                                 || a.state == ActivityState.PAUSING)) {
14585                            adj = ProcessList.FOREGROUND_APP_ADJ;
14586                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14587                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14588                            }
14589                            app.cached = false;
14590                            app.adjType = "service";
14591                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14592                                    .REASON_SERVICE_IN_USE;
14593                            app.adjSource = a;
14594                            app.adjSourceOom = adj;
14595                            app.adjTarget = s.name;
14596                        }
14597                    }
14598                }
14599            }
14600        }
14601
14602        for (int provi = app.pubProviders.size()-1;
14603                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14604                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14605                        || procState > ActivityManager.PROCESS_STATE_TOP);
14606                provi--) {
14607            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14608            for (int i = cpr.connections.size()-1;
14609                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14610                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14611                            || procState > ActivityManager.PROCESS_STATE_TOP);
14612                    i--) {
14613                ContentProviderConnection conn = cpr.connections.get(i);
14614                ProcessRecord client = conn.client;
14615                if (client == app) {
14616                    // Being our own client is not interesting.
14617                    continue;
14618                }
14619                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14620                int clientProcState = client.curProcState;
14621                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14622                    // If the other app is cached for any reason, for purposes here
14623                    // we are going to consider it empty.
14624                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14625                }
14626                if (adj > clientAdj) {
14627                    if (app.hasShownUi && app != mHomeProcess
14628                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14629                        app.adjType = "cch-ui-provider";
14630                    } else {
14631                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14632                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14633                        app.adjType = "provider";
14634                    }
14635                    app.cached &= client.cached;
14636                    app.keeping |= client.keeping;
14637                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14638                            .REASON_PROVIDER_IN_USE;
14639                    app.adjSource = client;
14640                    app.adjSourceOom = clientAdj;
14641                    app.adjTarget = cpr.name;
14642                }
14643                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14644                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14645                        // Special handling of clients who are in the top state.
14646                        // We *may* want to consider this process to be in the
14647                        // top state as well, but only if there is not another
14648                        // reason for it to be running.  Being on the top is a
14649                        // special state, meaning you are specifically running
14650                        // for the current top app.  If the process is already
14651                        // running in the background for some other reason, it
14652                        // is more important to continue considering it to be
14653                        // in the background state.
14654                        mayBeTop = true;
14655                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14656                    } else {
14657                        // Special handling for above-top states (persistent
14658                        // processes).  These should not bring the current process
14659                        // into the top state, since they are not on top.  Instead
14660                        // give them the best state after that.
14661                        clientProcState =
14662                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14663                    }
14664                }
14665                if (procState > clientProcState) {
14666                    procState = clientProcState;
14667                }
14668                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14669                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14670                }
14671            }
14672            // If the provider has external (non-framework) process
14673            // dependencies, ensure that its adjustment is at least
14674            // FOREGROUND_APP_ADJ.
14675            if (cpr.hasExternalProcessHandles()) {
14676                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14677                    adj = ProcessList.FOREGROUND_APP_ADJ;
14678                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14679                    app.cached = false;
14680                    app.keeping = true;
14681                    app.adjType = "provider";
14682                    app.adjTarget = cpr.name;
14683                }
14684                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14685                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14686                }
14687            }
14688        }
14689
14690        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14691            // A client of one of our services or providers is in the top state.  We
14692            // *may* want to be in the top state, but not if we are already running in
14693            // the background for some other reason.  For the decision here, we are going
14694            // to pick out a few specific states that we want to remain in when a client
14695            // is top (states that tend to be longer-term) and otherwise allow it to go
14696            // to the top state.
14697            switch (procState) {
14698                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14699                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14700                case ActivityManager.PROCESS_STATE_SERVICE:
14701                    // These all are longer-term states, so pull them up to the top
14702                    // of the background states, but not all the way to the top state.
14703                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14704                    break;
14705                default:
14706                    // Otherwise, top is a better choice, so take it.
14707                    procState = ActivityManager.PROCESS_STATE_TOP;
14708                    break;
14709            }
14710        }
14711
14712        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14713            // This is a cached process, but with client activities.  Mark it so.
14714            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14715            app.adjType = "cch-client-act";
14716        }
14717
14718        if (adj == ProcessList.SERVICE_ADJ) {
14719            if (doingAll) {
14720                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14721                mNewNumServiceProcs++;
14722                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14723                if (!app.serviceb) {
14724                    // This service isn't far enough down on the LRU list to
14725                    // normally be a B service, but if we are low on RAM and it
14726                    // is large we want to force it down since we would prefer to
14727                    // keep launcher over it.
14728                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14729                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14730                        app.serviceHighRam = true;
14731                        app.serviceb = true;
14732                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14733                    } else {
14734                        mNewNumAServiceProcs++;
14735                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14736                    }
14737                } else {
14738                    app.serviceHighRam = false;
14739                }
14740            }
14741            if (app.serviceb) {
14742                adj = ProcessList.SERVICE_B_ADJ;
14743            }
14744        }
14745
14746        app.curRawAdj = adj;
14747
14748        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14749        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14750        if (adj > app.maxAdj) {
14751            adj = app.maxAdj;
14752            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14753                schedGroup = Process.THREAD_GROUP_DEFAULT;
14754            }
14755        }
14756        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14757            app.keeping = true;
14758        }
14759
14760        // Do final modification to adj.  Everything we do between here and applying
14761        // the final setAdj must be done in this function, because we will also use
14762        // it when computing the final cached adj later.  Note that we don't need to
14763        // worry about this for max adj above, since max adj will always be used to
14764        // keep it out of the cached vaues.
14765        adj = app.modifyRawOomAdj(adj);
14766
14767        app.curProcState = procState;
14768
14769        int importance = app.memImportance;
14770        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14771            app.curAdj = adj;
14772            app.curSchedGroup = schedGroup;
14773            if (!interesting) {
14774                // For this reporting, if there is not something explicitly
14775                // interesting in this process then we will push it to the
14776                // background importance.
14777                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14778            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14779                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14780            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14781                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14782            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14783                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14784            } else if (adj >= ProcessList.SERVICE_ADJ) {
14785                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14786            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14787                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14788            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14789                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14790            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14791                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14792            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14793                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14794            } else {
14795                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14796            }
14797        }
14798
14799        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14800        if (foregroundActivities != app.foregroundActivities) {
14801            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14802        }
14803        if (changes != 0) {
14804            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14805            app.memImportance = importance;
14806            app.foregroundActivities = foregroundActivities;
14807            int i = mPendingProcessChanges.size()-1;
14808            ProcessChangeItem item = null;
14809            while (i >= 0) {
14810                item = mPendingProcessChanges.get(i);
14811                if (item.pid == app.pid) {
14812                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14813                    break;
14814                }
14815                i--;
14816            }
14817            if (i < 0) {
14818                // No existing item in pending changes; need a new one.
14819                final int NA = mAvailProcessChanges.size();
14820                if (NA > 0) {
14821                    item = mAvailProcessChanges.remove(NA-1);
14822                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14823                } else {
14824                    item = new ProcessChangeItem();
14825                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14826                }
14827                item.changes = 0;
14828                item.pid = app.pid;
14829                item.uid = app.info.uid;
14830                if (mPendingProcessChanges.size() == 0) {
14831                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14832                            "*** Enqueueing dispatch processes changed!");
14833                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14834                }
14835                mPendingProcessChanges.add(item);
14836            }
14837            item.changes |= changes;
14838            item.importance = importance;
14839            item.foregroundActivities = foregroundActivities;
14840            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14841                    + Integer.toHexString(System.identityHashCode(item))
14842                    + " " + app.toShortString() + ": changes=" + item.changes
14843                    + " importance=" + item.importance
14844                    + " foreground=" + item.foregroundActivities
14845                    + " type=" + app.adjType + " source=" + app.adjSource
14846                    + " target=" + app.adjTarget);
14847        }
14848
14849        return app.curRawAdj;
14850    }
14851
14852    /**
14853     * Schedule PSS collection of a process.
14854     */
14855    void requestPssLocked(ProcessRecord proc, int procState) {
14856        if (mPendingPssProcesses.contains(proc)) {
14857            return;
14858        }
14859        if (mPendingPssProcesses.size() == 0) {
14860            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14861        }
14862        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14863        proc.pssProcState = procState;
14864        mPendingPssProcesses.add(proc);
14865    }
14866
14867    /**
14868     * Schedule PSS collection of all processes.
14869     */
14870    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14871        if (!always) {
14872            if (now < (mLastFullPssTime +
14873                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14874                return;
14875            }
14876        }
14877        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14878        mLastFullPssTime = now;
14879        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14880        mPendingPssProcesses.clear();
14881        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14882            ProcessRecord app = mLruProcesses.get(i);
14883            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14884                app.pssProcState = app.setProcState;
14885                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14886                        mSleeping, now);
14887                mPendingPssProcesses.add(app);
14888            }
14889        }
14890        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14891    }
14892
14893    /**
14894     * Ask a given process to GC right now.
14895     */
14896    final void performAppGcLocked(ProcessRecord app) {
14897        try {
14898            app.lastRequestedGc = SystemClock.uptimeMillis();
14899            if (app.thread != null) {
14900                if (app.reportLowMemory) {
14901                    app.reportLowMemory = false;
14902                    app.thread.scheduleLowMemory();
14903                } else {
14904                    app.thread.processInBackground();
14905                }
14906            }
14907        } catch (Exception e) {
14908            // whatever.
14909        }
14910    }
14911
14912    /**
14913     * Returns true if things are idle enough to perform GCs.
14914     */
14915    private final boolean canGcNowLocked() {
14916        boolean processingBroadcasts = false;
14917        for (BroadcastQueue q : mBroadcastQueues) {
14918            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14919                processingBroadcasts = true;
14920            }
14921        }
14922        return !processingBroadcasts
14923                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14924    }
14925
14926    /**
14927     * Perform GCs on all processes that are waiting for it, but only
14928     * if things are idle.
14929     */
14930    final void performAppGcsLocked() {
14931        final int N = mProcessesToGc.size();
14932        if (N <= 0) {
14933            return;
14934        }
14935        if (canGcNowLocked()) {
14936            while (mProcessesToGc.size() > 0) {
14937                ProcessRecord proc = mProcessesToGc.remove(0);
14938                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14939                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14940                            <= SystemClock.uptimeMillis()) {
14941                        // To avoid spamming the system, we will GC processes one
14942                        // at a time, waiting a few seconds between each.
14943                        performAppGcLocked(proc);
14944                        scheduleAppGcsLocked();
14945                        return;
14946                    } else {
14947                        // It hasn't been long enough since we last GCed this
14948                        // process...  put it in the list to wait for its time.
14949                        addProcessToGcListLocked(proc);
14950                        break;
14951                    }
14952                }
14953            }
14954
14955            scheduleAppGcsLocked();
14956        }
14957    }
14958
14959    /**
14960     * If all looks good, perform GCs on all processes waiting for them.
14961     */
14962    final void performAppGcsIfAppropriateLocked() {
14963        if (canGcNowLocked()) {
14964            performAppGcsLocked();
14965            return;
14966        }
14967        // Still not idle, wait some more.
14968        scheduleAppGcsLocked();
14969    }
14970
14971    /**
14972     * Schedule the execution of all pending app GCs.
14973     */
14974    final void scheduleAppGcsLocked() {
14975        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
14976
14977        if (mProcessesToGc.size() > 0) {
14978            // Schedule a GC for the time to the next process.
14979            ProcessRecord proc = mProcessesToGc.get(0);
14980            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14981
14982            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
14983            long now = SystemClock.uptimeMillis();
14984            if (when < (now+GC_TIMEOUT)) {
14985                when = now + GC_TIMEOUT;
14986            }
14987            mHandler.sendMessageAtTime(msg, when);
14988        }
14989    }
14990
14991    /**
14992     * Add a process to the array of processes waiting to be GCed.  Keeps the
14993     * list in sorted order by the last GC time.  The process can't already be
14994     * on the list.
14995     */
14996    final void addProcessToGcListLocked(ProcessRecord proc) {
14997        boolean added = false;
14998        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14999            if (mProcessesToGc.get(i).lastRequestedGc <
15000                    proc.lastRequestedGc) {
15001                added = true;
15002                mProcessesToGc.add(i+1, proc);
15003                break;
15004            }
15005        }
15006        if (!added) {
15007            mProcessesToGc.add(0, proc);
15008        }
15009    }
15010
15011    /**
15012     * Set up to ask a process to GC itself.  This will either do it
15013     * immediately, or put it on the list of processes to gc the next
15014     * time things are idle.
15015     */
15016    final void scheduleAppGcLocked(ProcessRecord app) {
15017        long now = SystemClock.uptimeMillis();
15018        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15019            return;
15020        }
15021        if (!mProcessesToGc.contains(app)) {
15022            addProcessToGcListLocked(app);
15023            scheduleAppGcsLocked();
15024        }
15025    }
15026
15027    final void checkExcessivePowerUsageLocked(boolean doKills) {
15028        updateCpuStatsNow();
15029
15030        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15031        boolean doWakeKills = doKills;
15032        boolean doCpuKills = doKills;
15033        if (mLastPowerCheckRealtime == 0) {
15034            doWakeKills = false;
15035        }
15036        if (mLastPowerCheckUptime == 0) {
15037            doCpuKills = false;
15038        }
15039        if (stats.isScreenOn()) {
15040            doWakeKills = false;
15041        }
15042        final long curRealtime = SystemClock.elapsedRealtime();
15043        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15044        final long curUptime = SystemClock.uptimeMillis();
15045        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15046        mLastPowerCheckRealtime = curRealtime;
15047        mLastPowerCheckUptime = curUptime;
15048        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15049            doWakeKills = false;
15050        }
15051        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15052            doCpuKills = false;
15053        }
15054        int i = mLruProcesses.size();
15055        while (i > 0) {
15056            i--;
15057            ProcessRecord app = mLruProcesses.get(i);
15058            if (!app.keeping) {
15059                long wtime;
15060                synchronized (stats) {
15061                    wtime = stats.getProcessWakeTime(app.info.uid,
15062                            app.pid, curRealtime);
15063                }
15064                long wtimeUsed = wtime - app.lastWakeTime;
15065                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15066                if (DEBUG_POWER) {
15067                    StringBuilder sb = new StringBuilder(128);
15068                    sb.append("Wake for ");
15069                    app.toShortString(sb);
15070                    sb.append(": over ");
15071                    TimeUtils.formatDuration(realtimeSince, sb);
15072                    sb.append(" used ");
15073                    TimeUtils.formatDuration(wtimeUsed, sb);
15074                    sb.append(" (");
15075                    sb.append((wtimeUsed*100)/realtimeSince);
15076                    sb.append("%)");
15077                    Slog.i(TAG, sb.toString());
15078                    sb.setLength(0);
15079                    sb.append("CPU for ");
15080                    app.toShortString(sb);
15081                    sb.append(": over ");
15082                    TimeUtils.formatDuration(uptimeSince, sb);
15083                    sb.append(" used ");
15084                    TimeUtils.formatDuration(cputimeUsed, sb);
15085                    sb.append(" (");
15086                    sb.append((cputimeUsed*100)/uptimeSince);
15087                    sb.append("%)");
15088                    Slog.i(TAG, sb.toString());
15089                }
15090                // If a process has held a wake lock for more
15091                // than 50% of the time during this period,
15092                // that sounds bad.  Kill!
15093                if (doWakeKills && realtimeSince > 0
15094                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15095                    synchronized (stats) {
15096                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15097                                realtimeSince, wtimeUsed);
15098                    }
15099                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15100                            + " during " + realtimeSince);
15101                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15102                } else if (doCpuKills && uptimeSince > 0
15103                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15104                    synchronized (stats) {
15105                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15106                                uptimeSince, cputimeUsed);
15107                    }
15108                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15109                            + " during " + uptimeSince);
15110                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15111                } else {
15112                    app.lastWakeTime = wtime;
15113                    app.lastCpuTime = app.curCpuTime;
15114                }
15115            }
15116        }
15117    }
15118
15119    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15120            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15121        boolean success = true;
15122
15123        if (app.curRawAdj != app.setRawAdj) {
15124            if (wasKeeping && !app.keeping) {
15125                // This app is no longer something we want to keep.  Note
15126                // its current wake lock time to later know to kill it if
15127                // it is not behaving well.
15128                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15129                synchronized (stats) {
15130                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15131                            app.pid, SystemClock.elapsedRealtime());
15132                }
15133                app.lastCpuTime = app.curCpuTime;
15134            }
15135
15136            app.setRawAdj = app.curRawAdj;
15137        }
15138
15139        if (app.curAdj != app.setAdj) {
15140            ProcessList.setOomAdj(app.pid, app.curAdj);
15141            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15142                TAG, "Set " + app.pid + " " + app.processName +
15143                " adj " + app.curAdj + ": " + app.adjType);
15144            app.setAdj = app.curAdj;
15145        }
15146
15147        if (app.setSchedGroup != app.curSchedGroup) {
15148            app.setSchedGroup = app.curSchedGroup;
15149            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15150                    "Setting process group of " + app.processName
15151                    + " to " + app.curSchedGroup);
15152            if (app.waitingToKill != null &&
15153                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15154                killUnneededProcessLocked(app, app.waitingToKill);
15155                success = false;
15156            } else {
15157                if (true) {
15158                    long oldId = Binder.clearCallingIdentity();
15159                    try {
15160                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15161                    } catch (Exception e) {
15162                        Slog.w(TAG, "Failed setting process group of " + app.pid
15163                                + " to " + app.curSchedGroup);
15164                        e.printStackTrace();
15165                    } finally {
15166                        Binder.restoreCallingIdentity(oldId);
15167                    }
15168                } else {
15169                    if (app.thread != null) {
15170                        try {
15171                            app.thread.setSchedulingGroup(app.curSchedGroup);
15172                        } catch (RemoteException e) {
15173                        }
15174                    }
15175                }
15176                Process.setSwappiness(app.pid,
15177                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15178            }
15179        }
15180        if (app.repProcState != app.curProcState) {
15181            app.repProcState = app.curProcState;
15182            if (!reportingProcessState && app.thread != null) {
15183                try {
15184                    if (false) {
15185                        //RuntimeException h = new RuntimeException("here");
15186                        Slog.i(TAG, "Sending new process state " + app.repProcState
15187                                + " to " + app /*, h*/);
15188                    }
15189                    app.thread.setProcessState(app.repProcState);
15190                } catch (RemoteException e) {
15191                }
15192            }
15193        }
15194        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15195                app.setProcState)) {
15196            app.lastStateTime = now;
15197            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15198                    mSleeping, now);
15199            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15200                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15201                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15202                    + (app.nextPssTime-now) + ": " + app);
15203        } else {
15204            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15205                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15206                requestPssLocked(app, app.setProcState);
15207                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15208                        mSleeping, now);
15209            } else if (false && DEBUG_PSS) {
15210                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15211            }
15212        }
15213        if (app.setProcState != app.curProcState) {
15214            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15215                    "Proc state change of " + app.processName
15216                    + " to " + app.curProcState);
15217            app.setProcState = app.curProcState;
15218            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15219                app.notCachedSinceIdle = false;
15220            }
15221            if (!doingAll) {
15222                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15223            } else {
15224                app.procStateChanged = true;
15225            }
15226        }
15227        return success;
15228    }
15229
15230    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15231        if (proc.thread != null && proc.baseProcessTracker != null) {
15232            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15233        }
15234    }
15235
15236    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15237            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15238        if (app.thread == null) {
15239            return false;
15240        }
15241
15242        final boolean wasKeeping = app.keeping;
15243
15244        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15245
15246        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15247                reportingProcessState, now);
15248    }
15249
15250    private final ActivityRecord resumedAppLocked() {
15251        return mStackSupervisor.resumedAppLocked();
15252    }
15253
15254    final boolean updateOomAdjLocked(ProcessRecord app) {
15255        return updateOomAdjLocked(app, false);
15256    }
15257
15258    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15259        final ActivityRecord TOP_ACT = resumedAppLocked();
15260        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15261        final boolean wasCached = app.cached;
15262
15263        mAdjSeq++;
15264
15265        // This is the desired cached adjusment we want to tell it to use.
15266        // If our app is currently cached, we know it, and that is it.  Otherwise,
15267        // we don't know it yet, and it needs to now be cached we will then
15268        // need to do a complete oom adj.
15269        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15270                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15271        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15272                SystemClock.uptimeMillis());
15273        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15274            // Changed to/from cached state, so apps after it in the LRU
15275            // list may also be changed.
15276            updateOomAdjLocked();
15277        }
15278        return success;
15279    }
15280
15281    final void updateOomAdjLocked() {
15282        final ActivityRecord TOP_ACT = resumedAppLocked();
15283        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15284        final long now = SystemClock.uptimeMillis();
15285        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15286        final int N = mLruProcesses.size();
15287
15288        if (false) {
15289            RuntimeException e = new RuntimeException();
15290            e.fillInStackTrace();
15291            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15292        }
15293
15294        mAdjSeq++;
15295        mNewNumServiceProcs = 0;
15296        mNewNumAServiceProcs = 0;
15297
15298        final int emptyProcessLimit;
15299        final int cachedProcessLimit;
15300        if (mProcessLimit <= 0) {
15301            emptyProcessLimit = cachedProcessLimit = 0;
15302        } else if (mProcessLimit == 1) {
15303            emptyProcessLimit = 1;
15304            cachedProcessLimit = 0;
15305        } else {
15306            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15307            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15308        }
15309
15310        // Let's determine how many processes we have running vs.
15311        // how many slots we have for background processes; we may want
15312        // to put multiple processes in a slot of there are enough of
15313        // them.
15314        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15315                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15316        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15317        if (numEmptyProcs > cachedProcessLimit) {
15318            // If there are more empty processes than our limit on cached
15319            // processes, then use the cached process limit for the factor.
15320            // This ensures that the really old empty processes get pushed
15321            // down to the bottom, so if we are running low on memory we will
15322            // have a better chance at keeping around more cached processes
15323            // instead of a gazillion empty processes.
15324            numEmptyProcs = cachedProcessLimit;
15325        }
15326        int emptyFactor = numEmptyProcs/numSlots;
15327        if (emptyFactor < 1) emptyFactor = 1;
15328        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15329        if (cachedFactor < 1) cachedFactor = 1;
15330        int stepCached = 0;
15331        int stepEmpty = 0;
15332        int numCached = 0;
15333        int numEmpty = 0;
15334        int numTrimming = 0;
15335
15336        mNumNonCachedProcs = 0;
15337        mNumCachedHiddenProcs = 0;
15338
15339        // First update the OOM adjustment for each of the
15340        // application processes based on their current state.
15341        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15342        int nextCachedAdj = curCachedAdj+1;
15343        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15344        int nextEmptyAdj = curEmptyAdj+2;
15345        for (int i=N-1; i>=0; i--) {
15346            ProcessRecord app = mLruProcesses.get(i);
15347            if (!app.killedByAm && app.thread != null) {
15348                app.procStateChanged = false;
15349                final boolean wasKeeping = app.keeping;
15350                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15351
15352                // If we haven't yet assigned the final cached adj
15353                // to the process, do that now.
15354                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15355                    switch (app.curProcState) {
15356                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15357                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15358                            // This process is a cached process holding activities...
15359                            // assign it the next cached value for that type, and then
15360                            // step that cached level.
15361                            app.curRawAdj = curCachedAdj;
15362                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15363                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15364                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15365                                    + ")");
15366                            if (curCachedAdj != nextCachedAdj) {
15367                                stepCached++;
15368                                if (stepCached >= cachedFactor) {
15369                                    stepCached = 0;
15370                                    curCachedAdj = nextCachedAdj;
15371                                    nextCachedAdj += 2;
15372                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15373                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15374                                    }
15375                                }
15376                            }
15377                            break;
15378                        default:
15379                            // For everything else, assign next empty cached process
15380                            // level and bump that up.  Note that this means that
15381                            // long-running services that have dropped down to the
15382                            // cached level will be treated as empty (since their process
15383                            // state is still as a service), which is what we want.
15384                            app.curRawAdj = curEmptyAdj;
15385                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15386                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15387                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15388                                    + ")");
15389                            if (curEmptyAdj != nextEmptyAdj) {
15390                                stepEmpty++;
15391                                if (stepEmpty >= emptyFactor) {
15392                                    stepEmpty = 0;
15393                                    curEmptyAdj = nextEmptyAdj;
15394                                    nextEmptyAdj += 2;
15395                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15396                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15397                                    }
15398                                }
15399                            }
15400                            break;
15401                    }
15402                }
15403
15404                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15405
15406                // Count the number of process types.
15407                switch (app.curProcState) {
15408                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15409                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15410                        mNumCachedHiddenProcs++;
15411                        numCached++;
15412                        if (numCached > cachedProcessLimit) {
15413                            killUnneededProcessLocked(app, "cached #" + numCached);
15414                        }
15415                        break;
15416                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15417                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15418                                && app.lastActivityTime < oldTime) {
15419                            killUnneededProcessLocked(app, "empty for "
15420                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15421                                    / 1000) + "s");
15422                        } else {
15423                            numEmpty++;
15424                            if (numEmpty > emptyProcessLimit) {
15425                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15426                            }
15427                        }
15428                        break;
15429                    default:
15430                        mNumNonCachedProcs++;
15431                        break;
15432                }
15433
15434                if (app.isolated && app.services.size() <= 0) {
15435                    // If this is an isolated process, and there are no
15436                    // services running in it, then the process is no longer
15437                    // needed.  We agressively kill these because we can by
15438                    // definition not re-use the same process again, and it is
15439                    // good to avoid having whatever code was running in them
15440                    // left sitting around after no longer needed.
15441                    killUnneededProcessLocked(app, "isolated not needed");
15442                }
15443
15444                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15445                        && !app.killedByAm) {
15446                    numTrimming++;
15447                }
15448            }
15449        }
15450
15451        mNumServiceProcs = mNewNumServiceProcs;
15452
15453        // Now determine the memory trimming level of background processes.
15454        // Unfortunately we need to start at the back of the list to do this
15455        // properly.  We only do this if the number of background apps we
15456        // are managing to keep around is less than half the maximum we desire;
15457        // if we are keeping a good number around, we'll let them use whatever
15458        // memory they want.
15459        final int numCachedAndEmpty = numCached + numEmpty;
15460        int memFactor;
15461        if (numCached <= ProcessList.TRIM_CACHED_APPS
15462                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15463            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15464                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15465            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15466                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15467            } else {
15468                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15469            }
15470        } else {
15471            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15472        }
15473        // We always allow the memory level to go up (better).  We only allow it to go
15474        // down if we are in a state where that is allowed, *and* the total number of processes
15475        // has gone down since last time.
15476        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15477                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15478                + " last=" + mLastNumProcesses);
15479        if (memFactor > mLastMemoryLevel) {
15480            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15481                memFactor = mLastMemoryLevel;
15482                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15483            }
15484        }
15485        mLastMemoryLevel = memFactor;
15486        mLastNumProcesses = mLruProcesses.size();
15487        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15488        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15489        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15490            if (mLowRamStartTime == 0) {
15491                mLowRamStartTime = now;
15492            }
15493            int step = 0;
15494            int fgTrimLevel;
15495            switch (memFactor) {
15496                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15497                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15498                    break;
15499                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15500                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15501                    break;
15502                default:
15503                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15504                    break;
15505            }
15506            int factor = numTrimming/3;
15507            int minFactor = 2;
15508            if (mHomeProcess != null) minFactor++;
15509            if (mPreviousProcess != null) minFactor++;
15510            if (factor < minFactor) factor = minFactor;
15511            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15512            for (int i=N-1; i>=0; i--) {
15513                ProcessRecord app = mLruProcesses.get(i);
15514                if (allChanged || app.procStateChanged) {
15515                    setProcessTrackerState(app, trackerMemFactor, now);
15516                    app.procStateChanged = false;
15517                }
15518                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15519                        && !app.killedByAm) {
15520                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15521                        try {
15522                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15523                                    "Trimming memory of " + app.processName
15524                                    + " to " + curLevel);
15525                            app.thread.scheduleTrimMemory(curLevel);
15526                        } catch (RemoteException e) {
15527                        }
15528                        if (false) {
15529                            // For now we won't do this; our memory trimming seems
15530                            // to be good enough at this point that destroying
15531                            // activities causes more harm than good.
15532                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15533                                    && app != mHomeProcess && app != mPreviousProcess) {
15534                                // Need to do this on its own message because the stack may not
15535                                // be in a consistent state at this point.
15536                                // For these apps we will also finish their activities
15537                                // to help them free memory.
15538                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15539                            }
15540                        }
15541                    }
15542                    app.trimMemoryLevel = curLevel;
15543                    step++;
15544                    if (step >= factor) {
15545                        step = 0;
15546                        switch (curLevel) {
15547                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15548                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15549                                break;
15550                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15551                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15552                                break;
15553                        }
15554                    }
15555                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15556                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15557                            && app.thread != null) {
15558                        try {
15559                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15560                                    "Trimming memory of heavy-weight " + app.processName
15561                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15562                            app.thread.scheduleTrimMemory(
15563                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15564                        } catch (RemoteException e) {
15565                        }
15566                    }
15567                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15568                } else {
15569                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15570                            || app.systemNoUi) && app.pendingUiClean) {
15571                        // If this application is now in the background and it
15572                        // had done UI, then give it the special trim level to
15573                        // have it free UI resources.
15574                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15575                        if (app.trimMemoryLevel < level && app.thread != null) {
15576                            try {
15577                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15578                                        "Trimming memory of bg-ui " + app.processName
15579                                        + " to " + level);
15580                                app.thread.scheduleTrimMemory(level);
15581                            } catch (RemoteException e) {
15582                            }
15583                        }
15584                        app.pendingUiClean = false;
15585                    }
15586                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15587                        try {
15588                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15589                                    "Trimming memory of fg " + app.processName
15590                                    + " to " + fgTrimLevel);
15591                            app.thread.scheduleTrimMemory(fgTrimLevel);
15592                        } catch (RemoteException e) {
15593                        }
15594                    }
15595                    app.trimMemoryLevel = fgTrimLevel;
15596                }
15597            }
15598        } else {
15599            if (mLowRamStartTime != 0) {
15600                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15601                mLowRamStartTime = 0;
15602            }
15603            for (int i=N-1; i>=0; i--) {
15604                ProcessRecord app = mLruProcesses.get(i);
15605                if (allChanged || app.procStateChanged) {
15606                    setProcessTrackerState(app, trackerMemFactor, now);
15607                    app.procStateChanged = false;
15608                }
15609                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15610                        || app.systemNoUi) && app.pendingUiClean) {
15611                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15612                            && app.thread != null) {
15613                        try {
15614                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15615                                    "Trimming memory of ui hidden " + app.processName
15616                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15617                            app.thread.scheduleTrimMemory(
15618                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15619                        } catch (RemoteException e) {
15620                        }
15621                    }
15622                    app.pendingUiClean = false;
15623                }
15624                app.trimMemoryLevel = 0;
15625            }
15626        }
15627
15628        if (mAlwaysFinishActivities) {
15629            // Need to do this on its own message because the stack may not
15630            // be in a consistent state at this point.
15631            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15632        }
15633
15634        if (allChanged) {
15635            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15636        }
15637
15638        if (mProcessStats.shouldWriteNowLocked(now)) {
15639            mHandler.post(new Runnable() {
15640                @Override public void run() {
15641                    synchronized (ActivityManagerService.this) {
15642                        mProcessStats.writeStateAsyncLocked();
15643                    }
15644                }
15645            });
15646        }
15647
15648        if (DEBUG_OOM_ADJ) {
15649            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15650        }
15651    }
15652
15653    final void trimApplications() {
15654        synchronized (this) {
15655            int i;
15656
15657            // First remove any unused application processes whose package
15658            // has been removed.
15659            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15660                final ProcessRecord app = mRemovedProcesses.get(i);
15661                if (app.activities.size() == 0
15662                        && app.curReceiver == null && app.services.size() == 0) {
15663                    Slog.i(
15664                        TAG, "Exiting empty application process "
15665                        + app.processName + " ("
15666                        + (app.thread != null ? app.thread.asBinder() : null)
15667                        + ")\n");
15668                    if (app.pid > 0 && app.pid != MY_PID) {
15669                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15670                                app.processName, app.setAdj, "empty");
15671                        app.killedByAm = true;
15672                        Process.killProcessQuiet(app.pid);
15673                    } else {
15674                        try {
15675                            app.thread.scheduleExit();
15676                        } catch (Exception e) {
15677                            // Ignore exceptions.
15678                        }
15679                    }
15680                    cleanUpApplicationRecordLocked(app, false, true, -1);
15681                    mRemovedProcesses.remove(i);
15682
15683                    if (app.persistent) {
15684                        if (app.persistent) {
15685                            addAppLocked(app.info, false);
15686                        }
15687                    }
15688                }
15689            }
15690
15691            // Now update the oom adj for all processes.
15692            updateOomAdjLocked();
15693        }
15694    }
15695
15696    /** This method sends the specified signal to each of the persistent apps */
15697    public void signalPersistentProcesses(int sig) throws RemoteException {
15698        if (sig != Process.SIGNAL_USR1) {
15699            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15700        }
15701
15702        synchronized (this) {
15703            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15704                    != PackageManager.PERMISSION_GRANTED) {
15705                throw new SecurityException("Requires permission "
15706                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15707            }
15708
15709            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15710                ProcessRecord r = mLruProcesses.get(i);
15711                if (r.thread != null && r.persistent) {
15712                    Process.sendSignal(r.pid, sig);
15713                }
15714            }
15715        }
15716    }
15717
15718    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15719        if (proc == null || proc == mProfileProc) {
15720            proc = mProfileProc;
15721            path = mProfileFile;
15722            profileType = mProfileType;
15723            clearProfilerLocked();
15724        }
15725        if (proc == null) {
15726            return;
15727        }
15728        try {
15729            proc.thread.profilerControl(false, path, null, profileType);
15730        } catch (RemoteException e) {
15731            throw new IllegalStateException("Process disappeared");
15732        }
15733    }
15734
15735    private void clearProfilerLocked() {
15736        if (mProfileFd != null) {
15737            try {
15738                mProfileFd.close();
15739            } catch (IOException e) {
15740            }
15741        }
15742        mProfileApp = null;
15743        mProfileProc = null;
15744        mProfileFile = null;
15745        mProfileType = 0;
15746        mAutoStopProfiler = false;
15747    }
15748
15749    public boolean profileControl(String process, int userId, boolean start,
15750            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15751
15752        try {
15753            synchronized (this) {
15754                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15755                // its own permission.
15756                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15757                        != PackageManager.PERMISSION_GRANTED) {
15758                    throw new SecurityException("Requires permission "
15759                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15760                }
15761
15762                if (start && fd == null) {
15763                    throw new IllegalArgumentException("null fd");
15764                }
15765
15766                ProcessRecord proc = null;
15767                if (process != null) {
15768                    proc = findProcessLocked(process, userId, "profileControl");
15769                }
15770
15771                if (start && (proc == null || proc.thread == null)) {
15772                    throw new IllegalArgumentException("Unknown process: " + process);
15773                }
15774
15775                if (start) {
15776                    stopProfilerLocked(null, null, 0);
15777                    setProfileApp(proc.info, proc.processName, path, fd, false);
15778                    mProfileProc = proc;
15779                    mProfileType = profileType;
15780                    try {
15781                        fd = fd.dup();
15782                    } catch (IOException e) {
15783                        fd = null;
15784                    }
15785                    proc.thread.profilerControl(start, path, fd, profileType);
15786                    fd = null;
15787                    mProfileFd = null;
15788                } else {
15789                    stopProfilerLocked(proc, path, profileType);
15790                    if (fd != null) {
15791                        try {
15792                            fd.close();
15793                        } catch (IOException e) {
15794                        }
15795                    }
15796                }
15797
15798                return true;
15799            }
15800        } catch (RemoteException e) {
15801            throw new IllegalStateException("Process disappeared");
15802        } finally {
15803            if (fd != null) {
15804                try {
15805                    fd.close();
15806                } catch (IOException e) {
15807                }
15808            }
15809        }
15810    }
15811
15812    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15813        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15814                userId, true, true, callName, null);
15815        ProcessRecord proc = null;
15816        try {
15817            int pid = Integer.parseInt(process);
15818            synchronized (mPidsSelfLocked) {
15819                proc = mPidsSelfLocked.get(pid);
15820            }
15821        } catch (NumberFormatException e) {
15822        }
15823
15824        if (proc == null) {
15825            ArrayMap<String, SparseArray<ProcessRecord>> all
15826                    = mProcessNames.getMap();
15827            SparseArray<ProcessRecord> procs = all.get(process);
15828            if (procs != null && procs.size() > 0) {
15829                proc = procs.valueAt(0);
15830                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15831                    for (int i=1; i<procs.size(); i++) {
15832                        ProcessRecord thisProc = procs.valueAt(i);
15833                        if (thisProc.userId == userId) {
15834                            proc = thisProc;
15835                            break;
15836                        }
15837                    }
15838                }
15839            }
15840        }
15841
15842        return proc;
15843    }
15844
15845    public boolean dumpHeap(String process, int userId, boolean managed,
15846            String path, ParcelFileDescriptor fd) throws RemoteException {
15847
15848        try {
15849            synchronized (this) {
15850                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15851                // its own permission (same as profileControl).
15852                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15853                        != PackageManager.PERMISSION_GRANTED) {
15854                    throw new SecurityException("Requires permission "
15855                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15856                }
15857
15858                if (fd == null) {
15859                    throw new IllegalArgumentException("null fd");
15860                }
15861
15862                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15863                if (proc == null || proc.thread == null) {
15864                    throw new IllegalArgumentException("Unknown process: " + process);
15865                }
15866
15867                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15868                if (!isDebuggable) {
15869                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15870                        throw new SecurityException("Process not debuggable: " + proc);
15871                    }
15872                }
15873
15874                proc.thread.dumpHeap(managed, path, fd);
15875                fd = null;
15876                return true;
15877            }
15878        } catch (RemoteException e) {
15879            throw new IllegalStateException("Process disappeared");
15880        } finally {
15881            if (fd != null) {
15882                try {
15883                    fd.close();
15884                } catch (IOException e) {
15885                }
15886            }
15887        }
15888    }
15889
15890    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15891    public void monitor() {
15892        synchronized (this) { }
15893    }
15894
15895    void onCoreSettingsChange(Bundle settings) {
15896        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15897            ProcessRecord processRecord = mLruProcesses.get(i);
15898            try {
15899                if (processRecord.thread != null) {
15900                    processRecord.thread.setCoreSettings(settings);
15901                }
15902            } catch (RemoteException re) {
15903                /* ignore */
15904            }
15905        }
15906    }
15907
15908    // Multi-user methods
15909
15910    @Override
15911    public boolean switchUser(final int userId) {
15912        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15913                != PackageManager.PERMISSION_GRANTED) {
15914            String msg = "Permission Denial: switchUser() from pid="
15915                    + Binder.getCallingPid()
15916                    + ", uid=" + Binder.getCallingUid()
15917                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15918            Slog.w(TAG, msg);
15919            throw new SecurityException(msg);
15920        }
15921
15922        final long ident = Binder.clearCallingIdentity();
15923        try {
15924            synchronized (this) {
15925                final int oldUserId = mCurrentUserId;
15926                if (oldUserId == userId) {
15927                    return true;
15928                }
15929
15930                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15931                if (userInfo == null) {
15932                    Slog.w(TAG, "No user info for user #" + userId);
15933                    return false;
15934                }
15935
15936                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15937                        R.anim.screen_user_enter);
15938
15939                boolean needStart = false;
15940
15941                // If the user we are switching to is not currently started, then
15942                // we need to start it now.
15943                if (mStartedUsers.get(userId) == null) {
15944                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
15945                    updateStartedUserArrayLocked();
15946                    needStart = true;
15947                }
15948
15949                mCurrentUserId = userId;
15950                final Integer userIdInt = Integer.valueOf(userId);
15951                mUserLru.remove(userIdInt);
15952                mUserLru.add(userIdInt);
15953
15954                mWindowManager.setCurrentUser(userId);
15955
15956                // Once the internal notion of the active user has switched, we lock the device
15957                // with the option to show the user switcher on the keyguard.
15958                mWindowManager.lockNow(null);
15959
15960                final UserStartedState uss = mStartedUsers.get(userId);
15961
15962                // Make sure user is in the started state.  If it is currently
15963                // stopping, we need to knock that off.
15964                if (uss.mState == UserStartedState.STATE_STOPPING) {
15965                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
15966                    // so we can just fairly silently bring the user back from
15967                    // the almost-dead.
15968                    uss.mState = UserStartedState.STATE_RUNNING;
15969                    updateStartedUserArrayLocked();
15970                    needStart = true;
15971                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
15972                    // This means ACTION_SHUTDOWN has been sent, so we will
15973                    // need to treat this as a new boot of the user.
15974                    uss.mState = UserStartedState.STATE_BOOTING;
15975                    updateStartedUserArrayLocked();
15976                    needStart = true;
15977                }
15978
15979                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
15980                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
15981                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
15982                        oldUserId, userId, uss));
15983                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
15984                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
15985                if (needStart) {
15986                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
15987                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15988                            | Intent.FLAG_RECEIVER_FOREGROUND);
15989                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
15990                    broadcastIntentLocked(null, null, intent,
15991                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15992                            false, false, MY_PID, Process.SYSTEM_UID, userId);
15993                }
15994
15995                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
15996                    if (userId != 0) {
15997                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
15998                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15999                        broadcastIntentLocked(null, null, intent, null,
16000                                new IIntentReceiver.Stub() {
16001                                    public void performReceive(Intent intent, int resultCode,
16002                                            String data, Bundle extras, boolean ordered,
16003                                            boolean sticky, int sendingUser) {
16004                                        userInitialized(uss, userId);
16005                                    }
16006                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16007                                true, false, MY_PID, Process.SYSTEM_UID,
16008                                userId);
16009                        uss.initializing = true;
16010                    } else {
16011                        getUserManagerLocked().makeInitialized(userInfo.id);
16012                    }
16013                }
16014
16015                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16016                if (homeInFront) {
16017                    startHomeActivityLocked(userId);
16018                } else {
16019                    mStackSupervisor.resumeTopActivitiesLocked();
16020                }
16021
16022                EventLogTags.writeAmSwitchUser(userId);
16023                getUserManagerLocked().userForeground(userId);
16024                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16025                if (needStart) {
16026                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16027                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16028                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16029                    broadcastIntentLocked(null, null, intent,
16030                            null, new IIntentReceiver.Stub() {
16031                                @Override
16032                                public void performReceive(Intent intent, int resultCode, String data,
16033                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16034                                        throws RemoteException {
16035                                }
16036                            }, 0, null, null,
16037                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16038                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16039                }
16040            }
16041        } finally {
16042            Binder.restoreCallingIdentity(ident);
16043        }
16044
16045        return true;
16046    }
16047
16048    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16049        long ident = Binder.clearCallingIdentity();
16050        try {
16051            Intent intent;
16052            if (oldUserId >= 0) {
16053                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16054                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16055                        | Intent.FLAG_RECEIVER_FOREGROUND);
16056                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16057                broadcastIntentLocked(null, null, intent,
16058                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16059                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16060            }
16061            if (newUserId >= 0) {
16062                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16063                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16064                        | Intent.FLAG_RECEIVER_FOREGROUND);
16065                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16066                broadcastIntentLocked(null, null, intent,
16067                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16068                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16069                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16070                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16071                        | Intent.FLAG_RECEIVER_FOREGROUND);
16072                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16073                broadcastIntentLocked(null, null, intent,
16074                        null, null, 0, null, null,
16075                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16076                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16077            }
16078        } finally {
16079            Binder.restoreCallingIdentity(ident);
16080        }
16081    }
16082
16083    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16084            final int newUserId) {
16085        final int N = mUserSwitchObservers.beginBroadcast();
16086        if (N > 0) {
16087            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16088                int mCount = 0;
16089                @Override
16090                public void sendResult(Bundle data) throws RemoteException {
16091                    synchronized (ActivityManagerService.this) {
16092                        if (mCurUserSwitchCallback == this) {
16093                            mCount++;
16094                            if (mCount == N) {
16095                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16096                            }
16097                        }
16098                    }
16099                }
16100            };
16101            synchronized (this) {
16102                uss.switching = true;
16103                mCurUserSwitchCallback = callback;
16104            }
16105            for (int i=0; i<N; i++) {
16106                try {
16107                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16108                            newUserId, callback);
16109                } catch (RemoteException e) {
16110                }
16111            }
16112        } else {
16113            synchronized (this) {
16114                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16115            }
16116        }
16117        mUserSwitchObservers.finishBroadcast();
16118    }
16119
16120    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16121        synchronized (this) {
16122            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16123            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16124        }
16125    }
16126
16127    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16128        mCurUserSwitchCallback = null;
16129        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16130        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16131                oldUserId, newUserId, uss));
16132    }
16133
16134    void userInitialized(UserStartedState uss, int newUserId) {
16135        completeSwitchAndInitalize(uss, newUserId, true, false);
16136    }
16137
16138    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16139        completeSwitchAndInitalize(uss, newUserId, false, true);
16140    }
16141
16142    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16143            boolean clearInitializing, boolean clearSwitching) {
16144        boolean unfrozen = false;
16145        synchronized (this) {
16146            if (clearInitializing) {
16147                uss.initializing = false;
16148                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16149            }
16150            if (clearSwitching) {
16151                uss.switching = false;
16152            }
16153            if (!uss.switching && !uss.initializing) {
16154                mWindowManager.stopFreezingScreen();
16155                unfrozen = true;
16156            }
16157        }
16158        if (unfrozen) {
16159            final int N = mUserSwitchObservers.beginBroadcast();
16160            for (int i=0; i<N; i++) {
16161                try {
16162                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16163                } catch (RemoteException e) {
16164                }
16165            }
16166            mUserSwitchObservers.finishBroadcast();
16167        }
16168    }
16169
16170    void finishUserSwitch(UserStartedState uss) {
16171        synchronized (this) {
16172            if (uss.mState == UserStartedState.STATE_BOOTING
16173                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16174                uss.mState = UserStartedState.STATE_RUNNING;
16175                final int userId = uss.mHandle.getIdentifier();
16176                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16177                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16178                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16179                broadcastIntentLocked(null, null, intent,
16180                        null, null, 0, null, null,
16181                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16182                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16183            }
16184            int num = mUserLru.size();
16185            int i = 0;
16186            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16187                Integer oldUserId = mUserLru.get(i);
16188                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16189                if (oldUss == null) {
16190                    // Shouldn't happen, but be sane if it does.
16191                    mUserLru.remove(i);
16192                    num--;
16193                    continue;
16194                }
16195                if (oldUss.mState == UserStartedState.STATE_STOPPING
16196                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16197                    // This user is already stopping, doesn't count.
16198                    num--;
16199                    i++;
16200                    continue;
16201                }
16202                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16203                    // Owner and current can't be stopped, but count as running.
16204                    i++;
16205                    continue;
16206                }
16207                // This is a user to be stopped.
16208                stopUserLocked(oldUserId, null);
16209                num--;
16210                i++;
16211            }
16212        }
16213    }
16214
16215    @Override
16216    public int stopUser(final int userId, final IStopUserCallback callback) {
16217        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16218                != PackageManager.PERMISSION_GRANTED) {
16219            String msg = "Permission Denial: switchUser() from pid="
16220                    + Binder.getCallingPid()
16221                    + ", uid=" + Binder.getCallingUid()
16222                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16223            Slog.w(TAG, msg);
16224            throw new SecurityException(msg);
16225        }
16226        if (userId <= 0) {
16227            throw new IllegalArgumentException("Can't stop primary user " + userId);
16228        }
16229        synchronized (this) {
16230            return stopUserLocked(userId, callback);
16231        }
16232    }
16233
16234    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16235        if (mCurrentUserId == userId) {
16236            return ActivityManager.USER_OP_IS_CURRENT;
16237        }
16238
16239        final UserStartedState uss = mStartedUsers.get(userId);
16240        if (uss == null) {
16241            // User is not started, nothing to do...  but we do need to
16242            // callback if requested.
16243            if (callback != null) {
16244                mHandler.post(new Runnable() {
16245                    @Override
16246                    public void run() {
16247                        try {
16248                            callback.userStopped(userId);
16249                        } catch (RemoteException e) {
16250                        }
16251                    }
16252                });
16253            }
16254            return ActivityManager.USER_OP_SUCCESS;
16255        }
16256
16257        if (callback != null) {
16258            uss.mStopCallbacks.add(callback);
16259        }
16260
16261        if (uss.mState != UserStartedState.STATE_STOPPING
16262                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16263            uss.mState = UserStartedState.STATE_STOPPING;
16264            updateStartedUserArrayLocked();
16265
16266            long ident = Binder.clearCallingIdentity();
16267            try {
16268                // We are going to broadcast ACTION_USER_STOPPING and then
16269                // once that is done send a final ACTION_SHUTDOWN and then
16270                // stop the user.
16271                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16272                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16273                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16274                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16275                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16276                // This is the result receiver for the final shutdown broadcast.
16277                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16278                    @Override
16279                    public void performReceive(Intent intent, int resultCode, String data,
16280                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16281                        finishUserStop(uss);
16282                    }
16283                };
16284                // This is the result receiver for the initial stopping broadcast.
16285                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16286                    @Override
16287                    public void performReceive(Intent intent, int resultCode, String data,
16288                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16289                        // On to the next.
16290                        synchronized (ActivityManagerService.this) {
16291                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16292                                // Whoops, we are being started back up.  Abort, abort!
16293                                return;
16294                            }
16295                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16296                        }
16297                        broadcastIntentLocked(null, null, shutdownIntent,
16298                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16299                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16300                    }
16301                };
16302                // Kick things off.
16303                broadcastIntentLocked(null, null, stoppingIntent,
16304                        null, stoppingReceiver, 0, null, null,
16305                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16306                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16307            } finally {
16308                Binder.restoreCallingIdentity(ident);
16309            }
16310        }
16311
16312        return ActivityManager.USER_OP_SUCCESS;
16313    }
16314
16315    void finishUserStop(UserStartedState uss) {
16316        final int userId = uss.mHandle.getIdentifier();
16317        boolean stopped;
16318        ArrayList<IStopUserCallback> callbacks;
16319        synchronized (this) {
16320            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16321            if (mStartedUsers.get(userId) != uss) {
16322                stopped = false;
16323            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16324                stopped = false;
16325            } else {
16326                stopped = true;
16327                // User can no longer run.
16328                mStartedUsers.remove(userId);
16329                mUserLru.remove(Integer.valueOf(userId));
16330                updateStartedUserArrayLocked();
16331
16332                // Clean up all state and processes associated with the user.
16333                // Kill all the processes for the user.
16334                forceStopUserLocked(userId, "finish user");
16335            }
16336        }
16337
16338        for (int i=0; i<callbacks.size(); i++) {
16339            try {
16340                if (stopped) callbacks.get(i).userStopped(userId);
16341                else callbacks.get(i).userStopAborted(userId);
16342            } catch (RemoteException e) {
16343            }
16344        }
16345
16346        mStackSupervisor.removeUserLocked(userId);
16347    }
16348
16349    @Override
16350    public UserInfo getCurrentUser() {
16351        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16352                != PackageManager.PERMISSION_GRANTED) && (
16353                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16354                != PackageManager.PERMISSION_GRANTED)) {
16355            String msg = "Permission Denial: getCurrentUser() from pid="
16356                    + Binder.getCallingPid()
16357                    + ", uid=" + Binder.getCallingUid()
16358                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16359            Slog.w(TAG, msg);
16360            throw new SecurityException(msg);
16361        }
16362        synchronized (this) {
16363            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16364        }
16365    }
16366
16367    int getCurrentUserIdLocked() {
16368        return mCurrentUserId;
16369    }
16370
16371    @Override
16372    public boolean isUserRunning(int userId, boolean orStopped) {
16373        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16374                != PackageManager.PERMISSION_GRANTED) {
16375            String msg = "Permission Denial: isUserRunning() from pid="
16376                    + Binder.getCallingPid()
16377                    + ", uid=" + Binder.getCallingUid()
16378                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16379            Slog.w(TAG, msg);
16380            throw new SecurityException(msg);
16381        }
16382        synchronized (this) {
16383            return isUserRunningLocked(userId, orStopped);
16384        }
16385    }
16386
16387    boolean isUserRunningLocked(int userId, boolean orStopped) {
16388        UserStartedState state = mStartedUsers.get(userId);
16389        if (state == null) {
16390            return false;
16391        }
16392        if (orStopped) {
16393            return true;
16394        }
16395        return state.mState != UserStartedState.STATE_STOPPING
16396                && state.mState != UserStartedState.STATE_SHUTDOWN;
16397    }
16398
16399    @Override
16400    public int[] getRunningUserIds() {
16401        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16402                != PackageManager.PERMISSION_GRANTED) {
16403            String msg = "Permission Denial: isUserRunning() from pid="
16404                    + Binder.getCallingPid()
16405                    + ", uid=" + Binder.getCallingUid()
16406                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16407            Slog.w(TAG, msg);
16408            throw new SecurityException(msg);
16409        }
16410        synchronized (this) {
16411            return mStartedUserArray;
16412        }
16413    }
16414
16415    private void updateStartedUserArrayLocked() {
16416        int num = 0;
16417        for (int i=0; i<mStartedUsers.size();  i++) {
16418            UserStartedState uss = mStartedUsers.valueAt(i);
16419            // This list does not include stopping users.
16420            if (uss.mState != UserStartedState.STATE_STOPPING
16421                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16422                num++;
16423            }
16424        }
16425        mStartedUserArray = new int[num];
16426        num = 0;
16427        for (int i=0; i<mStartedUsers.size();  i++) {
16428            UserStartedState uss = mStartedUsers.valueAt(i);
16429            if (uss.mState != UserStartedState.STATE_STOPPING
16430                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16431                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16432                num++;
16433            }
16434        }
16435    }
16436
16437    @Override
16438    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16439        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16440                != PackageManager.PERMISSION_GRANTED) {
16441            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16442                    + Binder.getCallingPid()
16443                    + ", uid=" + Binder.getCallingUid()
16444                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16445            Slog.w(TAG, msg);
16446            throw new SecurityException(msg);
16447        }
16448
16449        mUserSwitchObservers.register(observer);
16450    }
16451
16452    @Override
16453    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16454        mUserSwitchObservers.unregister(observer);
16455    }
16456
16457    private boolean userExists(int userId) {
16458        if (userId == 0) {
16459            return true;
16460        }
16461        UserManagerService ums = getUserManagerLocked();
16462        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16463    }
16464
16465    int[] getUsersLocked() {
16466        UserManagerService ums = getUserManagerLocked();
16467        return ums != null ? ums.getUserIds() : new int[] { 0 };
16468    }
16469
16470    UserManagerService getUserManagerLocked() {
16471        if (mUserManager == null) {
16472            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16473            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16474        }
16475        return mUserManager;
16476    }
16477
16478    private int applyUserId(int uid, int userId) {
16479        return UserHandle.getUid(userId, uid);
16480    }
16481
16482    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16483        if (info == null) return null;
16484        ApplicationInfo newInfo = new ApplicationInfo(info);
16485        newInfo.uid = applyUserId(info.uid, userId);
16486        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16487                + info.packageName;
16488        return newInfo;
16489    }
16490
16491    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16492        if (aInfo == null
16493                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16494            return aInfo;
16495        }
16496
16497        ActivityInfo info = new ActivityInfo(aInfo);
16498        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16499        return info;
16500    }
16501
16502    private final class LocalService extends ActivityManagerInternal {
16503        @Override
16504        public void goingToSleep() {
16505            ActivityManagerService.this.goingToSleep();
16506        }
16507
16508        @Override
16509        public void wakingUp() {
16510            ActivityManagerService.this.wakingUp();
16511        }
16512    }
16513}
16514