ActivityManagerService.java revision 9e289d70a8baaed0030413b5991653792e2a816d
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
28
29import android.app.AppOpsManager;
30import android.app.IActivityContainer;
31import android.app.IActivityContainerCallback;
32import android.appwidget.AppWidgetManager;
33import android.graphics.Rect;
34import android.util.ArrayMap;
35
36import com.android.internal.R;
37import com.android.internal.annotations.GuardedBy;
38import com.android.internal.app.IAppOpsService;
39import com.android.internal.app.ProcessMap;
40import com.android.internal.app.ProcessStats;
41import com.android.internal.os.BackgroundThread;
42import com.android.internal.os.BatteryStatsImpl;
43import com.android.internal.os.ProcessCpuTracker;
44import com.android.internal.os.TransferPipe;
45import com.android.internal.os.Zygote;
46import com.android.internal.util.FastPrintWriter;
47import com.android.internal.util.FastXmlSerializer;
48import com.android.internal.util.MemInfoReader;
49import com.android.internal.util.Preconditions;
50import com.android.server.AppOpsService;
51import com.android.server.AttributeCache;
52import com.android.server.IntentResolver;
53import com.android.server.LocalServices;
54import com.android.server.ServiceThread;
55import com.android.server.SystemService;
56import com.android.server.Watchdog;
57import com.android.server.am.ActivityStack.ActivityState;
58import com.android.server.firewall.IntentFirewall;
59import com.android.server.pm.UserManagerService;
60import com.android.server.wm.AppTransition;
61import com.android.server.wm.WindowManagerService;
62import com.google.android.collect.Lists;
63import com.google.android.collect.Maps;
64
65import libcore.io.IoUtils;
66
67import org.xmlpull.v1.XmlPullParser;
68import org.xmlpull.v1.XmlPullParserException;
69import org.xmlpull.v1.XmlSerializer;
70
71import android.app.Activity;
72import android.app.ActivityManager;
73import android.app.ActivityManager.RunningTaskInfo;
74import android.app.ActivityManager.StackInfo;
75import android.app.ActivityManagerInternal;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.ApplicationErrorReport;
82import android.app.Dialog;
83import android.app.IActivityController;
84import android.app.IApplicationThread;
85import android.app.IInstrumentationWatcher;
86import android.app.INotificationManager;
87import android.app.IProcessObserver;
88import android.app.IServiceConnection;
89import android.app.IStopUserCallback;
90import android.app.IThumbnailReceiver;
91import android.app.IUiAutomationConnection;
92import android.app.IUserSwitchObserver;
93import android.app.Instrumentation;
94import android.app.Notification;
95import android.app.NotificationManager;
96import android.app.PendingIntent;
97import android.app.backup.IBackupManager;
98import android.content.ActivityNotFoundException;
99import android.content.BroadcastReceiver;
100import android.content.ClipData;
101import android.content.ComponentCallbacks2;
102import android.content.ComponentName;
103import android.content.ContentProvider;
104import android.content.ContentResolver;
105import android.content.Context;
106import android.content.DialogInterface;
107import android.content.IContentProvider;
108import android.content.IIntentReceiver;
109import android.content.IIntentSender;
110import android.content.Intent;
111import android.content.IntentFilter;
112import android.content.IntentSender;
113import android.content.pm.ActivityInfo;
114import android.content.pm.ApplicationInfo;
115import android.content.pm.ConfigurationInfo;
116import android.content.pm.IPackageDataObserver;
117import android.content.pm.IPackageManager;
118import android.content.pm.InstrumentationInfo;
119import android.content.pm.PackageInfo;
120import android.content.pm.PackageManager;
121import android.content.pm.ParceledListSlice;
122import android.content.pm.UserInfo;
123import android.content.pm.PackageManager.NameNotFoundException;
124import android.content.pm.PathPermission;
125import android.content.pm.ProviderInfo;
126import android.content.pm.ResolveInfo;
127import android.content.pm.ServiceInfo;
128import android.content.res.CompatibilityInfo;
129import android.content.res.Configuration;
130import android.graphics.Bitmap;
131import android.net.Proxy;
132import android.net.ProxyProperties;
133import android.net.Uri;
134import android.os.Binder;
135import android.os.Build;
136import android.os.Bundle;
137import android.os.Debug;
138import android.os.DropBoxManager;
139import android.os.Environment;
140import android.os.FactoryTest;
141import android.os.FileObserver;
142import android.os.FileUtils;
143import android.os.Handler;
144import android.os.IBinder;
145import android.os.IPermissionController;
146import android.os.IRemoteCallback;
147import android.os.IUserManager;
148import android.os.Looper;
149import android.os.Message;
150import android.os.Parcel;
151import android.os.ParcelFileDescriptor;
152import android.os.Process;
153import android.os.RemoteCallbackList;
154import android.os.RemoteException;
155import android.os.SELinux;
156import android.os.ServiceManager;
157import android.os.StrictMode;
158import android.os.SystemClock;
159import android.os.SystemProperties;
160import android.os.UpdateLock;
161import android.os.UserHandle;
162import android.provider.Settings;
163import android.text.format.DateUtils;
164import android.text.format.Time;
165import android.util.AtomicFile;
166import android.util.EventLog;
167import android.util.Log;
168import android.util.Pair;
169import android.util.PrintWriterPrinter;
170import android.util.Slog;
171import android.util.SparseArray;
172import android.util.TimeUtils;
173import android.util.Xml;
174import android.view.Gravity;
175import android.view.LayoutInflater;
176import android.view.View;
177import android.view.WindowManager;
178
179import java.io.BufferedInputStream;
180import java.io.BufferedOutputStream;
181import java.io.DataInputStream;
182import java.io.DataOutputStream;
183import java.io.File;
184import java.io.FileDescriptor;
185import java.io.FileInputStream;
186import java.io.FileNotFoundException;
187import java.io.FileOutputStream;
188import java.io.IOException;
189import java.io.InputStreamReader;
190import java.io.PrintWriter;
191import java.io.StringWriter;
192import java.lang.ref.WeakReference;
193import java.util.ArrayList;
194import java.util.Arrays;
195import java.util.Collections;
196import java.util.Comparator;
197import java.util.HashMap;
198import java.util.HashSet;
199import java.util.Iterator;
200import java.util.List;
201import java.util.Locale;
202import java.util.Map;
203import java.util.Set;
204import java.util.concurrent.atomic.AtomicBoolean;
205import java.util.concurrent.atomic.AtomicLong;
206
207public final class ActivityManagerService extends ActivityManagerNative
208        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
209    private static final String USER_DATA_DIR = "/data/user/";
210    static final String TAG = "ActivityManager";
211    static final String TAG_MU = "ActivityManagerServiceMU";
212    static final boolean DEBUG = false;
213    static final boolean localLOGV = DEBUG;
214    static final boolean DEBUG_BACKUP = localLOGV || false;
215    static final boolean DEBUG_BROADCAST = localLOGV || false;
216    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_CLEANUP = localLOGV || false;
219    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
220    static final boolean DEBUG_FOCUS = false;
221    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
222    static final boolean DEBUG_MU = localLOGV || false;
223    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
224    static final boolean DEBUG_LRU = localLOGV || false;
225    static final boolean DEBUG_PAUSE = localLOGV || false;
226    static final boolean DEBUG_POWER = localLOGV || false;
227    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
228    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
229    static final boolean DEBUG_PROCESSES = localLOGV || false;
230    static final boolean DEBUG_PROVIDER = localLOGV || false;
231    static final boolean DEBUG_RESULTS = localLOGV || false;
232    static final boolean DEBUG_SERVICE = localLOGV || false;
233    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
234    static final boolean DEBUG_STACK = localLOGV || false;
235    static final boolean DEBUG_SWITCH = localLOGV || false;
236    static final boolean DEBUG_TASKS = localLOGV || false;
237    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
238    static final boolean DEBUG_TRANSITION = localLOGV || false;
239    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
240    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
241    static final boolean DEBUG_VISBILITY = localLOGV || false;
242    static final boolean DEBUG_PSS = localLOGV || false;
243    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
244    static final boolean VALIDATE_TOKENS = false;
245    static final boolean SHOW_ACTIVITY_START_TIME = true;
246
247    // Control over CPU and battery monitoring.
248    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
249    static final boolean MONITOR_CPU_USAGE = true;
250    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
251    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
252    static final boolean MONITOR_THREAD_CPU_USAGE = false;
253
254    // The flags that are set for all calls we make to the package manager.
255    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
256
257    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
258
259    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
260
261    // Maximum number of recent tasks that we can remember.
262    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
263
264    // Amount of time after a call to stopAppSwitches() during which we will
265    // prevent further untrusted switches from happening.
266    static final long APP_SWITCH_DELAY_TIME = 5*1000;
267
268    // How long we wait for a launched process to attach to the activity manager
269    // before we decide it's never going to come up for real.
270    static final int PROC_START_TIMEOUT = 10*1000;
271
272    // How long we wait for a launched process to attach to the activity manager
273    // before we decide it's never going to come up for real, when the process was
274    // started with a wrapper for instrumentation (such as Valgrind) because it
275    // could take much longer than usual.
276    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
277
278    // How long to wait after going idle before forcing apps to GC.
279    static final int GC_TIMEOUT = 5*1000;
280
281    // The minimum amount of time between successive GC requests for a process.
282    static final int GC_MIN_INTERVAL = 60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process.
285    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
286
287    // The minimum amount of time between successive PSS requests for a process
288    // when the request is due to the memory state being lowered.
289    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
290
291    // The rate at which we check for apps using excessive power -- 15 mins.
292    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
293
294    // The minimum sample duration we will allow before deciding we have
295    // enough data on wake locks to start killing things.
296    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
297
298    // The minimum sample duration we will allow before deciding we have
299    // enough data on CPU usage to start killing things.
300    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
301
302    // How long we allow a receiver to run before giving up on it.
303    static final int BROADCAST_FG_TIMEOUT = 10*1000;
304    static final int BROADCAST_BG_TIMEOUT = 60*1000;
305
306    // How long we wait until we timeout on key dispatching.
307    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
308
309    // How long we wait until we timeout on key dispatching during instrumentation.
310    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
311
312    // Amount of time we wait for observers to handle a user switch before
313    // giving up on them and unfreezing the screen.
314    static final int USER_SWITCH_TIMEOUT = 2*1000;
315
316    // Maximum number of users we allow to be running at a time.
317    static final int MAX_RUNNING_USERS = 3;
318
319    // How long to wait in getAssistContextExtras for the activity and foreground services
320    // to respond with the result.
321    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
322
323    // Maximum number of persisted Uri grants a package is allowed
324    static final int MAX_PERSISTED_URI_GRANTS = 128;
325
326    static final int MY_PID = Process.myPid();
327
328    static final String[] EMPTY_STRING_ARRAY = new String[0];
329
330    // How many bytes to write into the dropbox log before truncating
331    static final int DROPBOX_MAX_SIZE = 256 * 1024;
332
333    /** Run all ActivityStacks through this */
334    ActivityStackSupervisor mStackSupervisor;
335
336    public IntentFirewall mIntentFirewall;
337
338    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
339    // default actuion automatically.  Important for devices without direct input
340    // devices.
341    private boolean mShowDialogs = true;
342
343    /**
344     * Description of a request to start a new activity, which has been held
345     * due to app switches being disabled.
346     */
347    static class PendingActivityLaunch {
348        final ActivityRecord r;
349        final ActivityRecord sourceRecord;
350        final int startFlags;
351        final ActivityStack stack;
352
353        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
354                int _startFlags, ActivityStack _stack) {
355            r = _r;
356            sourceRecord = _sourceRecord;
357            startFlags = _startFlags;
358            stack = _stack;
359        }
360    }
361
362    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
363            = new ArrayList<PendingActivityLaunch>();
364
365    BroadcastQueue mFgBroadcastQueue;
366    BroadcastQueue mBgBroadcastQueue;
367    // Convenient for easy iteration over the queues. Foreground is first
368    // so that dispatch of foreground broadcasts gets precedence.
369    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
370
371    BroadcastQueue broadcastQueueForIntent(Intent intent) {
372        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
373        if (DEBUG_BACKGROUND_BROADCAST) {
374            Slog.i(TAG, "Broadcast intent " + intent + " on "
375                    + (isFg ? "foreground" : "background")
376                    + " queue");
377        }
378        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
379    }
380
381    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
382        for (BroadcastQueue queue : mBroadcastQueues) {
383            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
384            if (r != null) {
385                return r;
386            }
387        }
388        return null;
389    }
390
391    /**
392     * Activity we have told the window manager to have key focus.
393     */
394    ActivityRecord mFocusedActivity = null;
395
396    /**
397     * List of intents that were used to start the most recent tasks.
398     */
399    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
400
401    public class PendingAssistExtras extends Binder implements Runnable {
402        public final ActivityRecord activity;
403        public boolean haveResult = false;
404        public Bundle result = null;
405        public PendingAssistExtras(ActivityRecord _activity) {
406            activity = _activity;
407        }
408        @Override
409        public void run() {
410            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
411            synchronized (this) {
412                haveResult = true;
413                notifyAll();
414            }
415        }
416    }
417
418    final ArrayList<PendingAssistExtras> mPendingAssistExtras
419            = new ArrayList<PendingAssistExtras>();
420
421    /**
422     * Process management.
423     */
424    final ProcessList mProcessList = new ProcessList();
425
426    /**
427     * All of the applications we currently have running organized by name.
428     * The keys are strings of the application package name (as
429     * returned by the package manager), and the keys are ApplicationRecord
430     * objects.
431     */
432    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
433
434    /**
435     * Tracking long-term execution of processes to look for abuse and other
436     * bad app behavior.
437     */
438    final ProcessStatsService mProcessStats;
439
440    /**
441     * The currently running isolated processes.
442     */
443    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
444
445    /**
446     * Counter for assigning isolated process uids, to avoid frequently reusing the
447     * same ones.
448     */
449    int mNextIsolatedProcessUid = 0;
450
451    /**
452     * The currently running heavy-weight process, if any.
453     */
454    ProcessRecord mHeavyWeightProcess = null;
455
456    /**
457     * The last time that various processes have crashed.
458     */
459    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
460
461    /**
462     * Information about a process that is currently marked as bad.
463     */
464    static final class BadProcessInfo {
465        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
466            this.time = time;
467            this.shortMsg = shortMsg;
468            this.longMsg = longMsg;
469            this.stack = stack;
470        }
471
472        final long time;
473        final String shortMsg;
474        final String longMsg;
475        final String stack;
476    }
477
478    /**
479     * Set of applications that we consider to be bad, and will reject
480     * incoming broadcasts from (which the user has no control over).
481     * Processes are added to this set when they have crashed twice within
482     * a minimum amount of time; they are removed from it when they are
483     * later restarted (hopefully due to some user action).  The value is the
484     * time it was added to the list.
485     */
486    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
487
488    /**
489     * All of the processes we currently have running organized by pid.
490     * The keys are the pid running the application.
491     *
492     * <p>NOTE: This object is protected by its own lock, NOT the global
493     * activity manager lock!
494     */
495    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
496
497    /**
498     * All of the processes that have been forced to be foreground.  The key
499     * is the pid of the caller who requested it (we hold a death
500     * link on it).
501     */
502    abstract class ForegroundToken implements IBinder.DeathRecipient {
503        int pid;
504        IBinder token;
505    }
506    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
507
508    /**
509     * List of records for processes that someone had tried to start before the
510     * system was ready.  We don't start them at that point, but ensure they
511     * are started by the time booting is complete.
512     */
513    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
514
515    /**
516     * List of persistent applications that are in the process
517     * of being started.
518     */
519    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
520
521    /**
522     * Processes that are being forcibly torn down.
523     */
524    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of running applications, sorted by recent usage.
528     * The first entry in the list is the least recently used.
529     */
530    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Where in mLruProcesses that the processes hosting activities start.
534     */
535    int mLruProcessActivityStart = 0;
536
537    /**
538     * Where in mLruProcesses that the processes hosting services start.
539     * This is after (lower index) than mLruProcessesActivityStart.
540     */
541    int mLruProcessServiceStart = 0;
542
543    /**
544     * List of processes that should gc as soon as things are idle.
545     */
546    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
547
548    /**
549     * Processes we want to collect PSS data from.
550     */
551    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Last time we requested PSS data of all processes.
555     */
556    long mLastFullPssTime = SystemClock.uptimeMillis();
557
558    /**
559     * This is the process holding what we currently consider to be
560     * the "home" activity.
561     */
562    ProcessRecord mHomeProcess;
563
564    /**
565     * This is the process holding the activity the user last visited that
566     * is in a different process from the one they are currently in.
567     */
568    ProcessRecord mPreviousProcess;
569
570    /**
571     * The time at which the previous process was last visible.
572     */
573    long mPreviousProcessVisibleTime;
574
575    /**
576     * Which uses have been started, so are allowed to run code.
577     */
578    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
579
580    /**
581     * LRU list of history of current users.  Most recently current is at the end.
582     */
583    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
584
585    /**
586     * Constant array of the users that are currently started.
587     */
588    int[] mStartedUserArray = new int[] { 0 };
589
590    /**
591     * Registered observers of the user switching mechanics.
592     */
593    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
594            = new RemoteCallbackList<IUserSwitchObserver>();
595
596    /**
597     * Currently active user switch.
598     */
599    Object mCurUserSwitchCallback;
600
601    /**
602     * Packages that the user has asked to have run in screen size
603     * compatibility mode instead of filling the screen.
604     */
605    final CompatModePackages mCompatModePackages;
606
607    /**
608     * Set of IntentSenderRecord objects that are currently active.
609     */
610    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
611            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
612
613    /**
614     * Fingerprints (hashCode()) of stack traces that we've
615     * already logged DropBox entries for.  Guarded by itself.  If
616     * something (rogue user app) forces this over
617     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
618     */
619    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
620    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
621
622    /**
623     * Strict Mode background batched logging state.
624     *
625     * The string buffer is guarded by itself, and its lock is also
626     * used to determine if another batched write is already
627     * in-flight.
628     */
629    private final StringBuilder mStrictModeBuffer = new StringBuilder();
630
631    /**
632     * Keeps track of all IIntentReceivers that have been registered for
633     * broadcasts.  Hash keys are the receiver IBinder, hash value is
634     * a ReceiverList.
635     */
636    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
637            new HashMap<IBinder, ReceiverList>();
638
639    /**
640     * Resolver for broadcast intents to registered receivers.
641     * Holds BroadcastFilter (subclass of IntentFilter).
642     */
643    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
644            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
645        @Override
646        protected boolean allowFilterResult(
647                BroadcastFilter filter, List<BroadcastFilter> dest) {
648            IBinder target = filter.receiverList.receiver.asBinder();
649            for (int i=dest.size()-1; i>=0; i--) {
650                if (dest.get(i).receiverList.receiver.asBinder() == target) {
651                    return false;
652                }
653            }
654            return true;
655        }
656
657        @Override
658        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
659            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
660                    || userId == filter.owningUserId) {
661                return super.newResult(filter, match, userId);
662            }
663            return null;
664        }
665
666        @Override
667        protected BroadcastFilter[] newArray(int size) {
668            return new BroadcastFilter[size];
669        }
670
671        @Override
672        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
673            return packageName.equals(filter.packageName);
674        }
675    };
676
677    /**
678     * State of all active sticky broadcasts per user.  Keys are the action of the
679     * sticky Intent, values are an ArrayList of all broadcasted intents with
680     * that action (which should usually be one).  The SparseArray is keyed
681     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
682     * for stickies that are sent to all users.
683     */
684    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
685            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
686
687    final ActiveServices mServices;
688
689    /**
690     * Backup/restore process management
691     */
692    String mBackupAppName = null;
693    BackupRecord mBackupTarget = null;
694
695    /**
696     * List of PendingThumbnailsRecord objects of clients who are still
697     * waiting to receive all of the thumbnails for a task.
698     */
699    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
700            new ArrayList<PendingThumbnailsRecord>();
701
702    final ProviderMap mProviderMap;
703
704    /**
705     * List of content providers who have clients waiting for them.  The
706     * application is currently being launched and the provider will be
707     * removed from this list once it is published.
708     */
709    final ArrayList<ContentProviderRecord> mLaunchingProviders
710            = new ArrayList<ContentProviderRecord>();
711
712    /**
713     * File storing persisted {@link #mGrantedUriPermissions}.
714     */
715    private final AtomicFile mGrantFile;
716
717    /** XML constants used in {@link #mGrantFile} */
718    private static final String TAG_URI_GRANTS = "uri-grants";
719    private static final String TAG_URI_GRANT = "uri-grant";
720    private static final String ATTR_USER_HANDLE = "userHandle";
721    private static final String ATTR_SOURCE_PKG = "sourcePkg";
722    private static final String ATTR_TARGET_PKG = "targetPkg";
723    private static final String ATTR_URI = "uri";
724    private static final String ATTR_MODE_FLAGS = "modeFlags";
725    private static final String ATTR_CREATED_TIME = "createdTime";
726
727    /**
728     * Global set of specific {@link Uri} permissions that have been granted.
729     * This optimized lookup structure maps from {@link UriPermission#targetUid}
730     * to {@link UriPermission#uri} to {@link UriPermission}.
731     */
732    @GuardedBy("this")
733    private final SparseArray<ArrayMap<Uri, UriPermission>>
734            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
735
736    CoreSettingsObserver mCoreSettingsObserver;
737
738    /**
739     * Thread-local storage used to carry caller permissions over through
740     * indirect content-provider access.
741     */
742    private class Identity {
743        public int pid;
744        public int uid;
745
746        Identity(int _pid, int _uid) {
747            pid = _pid;
748            uid = _uid;
749        }
750    }
751
752    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
753
754    /**
755     * All information we have collected about the runtime performance of
756     * any user id that can impact battery performance.
757     */
758    final BatteryStatsService mBatteryStatsService;
759
760    /**
761     * Information about component usage
762     */
763    final UsageStatsService mUsageStatsService;
764
765    /**
766     * Information about and control over application operations
767     */
768    final AppOpsService mAppOpsService;
769
770    /**
771     * Current configuration information.  HistoryRecord objects are given
772     * a reference to this object to indicate which configuration they are
773     * currently running in, so this object must be kept immutable.
774     */
775    Configuration mConfiguration = new Configuration();
776
777    /**
778     * Current sequencing integer of the configuration, for skipping old
779     * configurations.
780     */
781    int mConfigurationSeq = 0;
782
783    /**
784     * Hardware-reported OpenGLES version.
785     */
786    final int GL_ES_VERSION;
787
788    /**
789     * List of initialization arguments to pass to all processes when binding applications to them.
790     * For example, references to the commonly used services.
791     */
792    HashMap<String, IBinder> mAppBindArgs;
793
794    /**
795     * Temporary to avoid allocations.  Protected by main lock.
796     */
797    final StringBuilder mStringBuilder = new StringBuilder(256);
798
799    /**
800     * Used to control how we initialize the service.
801     */
802    ComponentName mTopComponent;
803    String mTopAction = Intent.ACTION_MAIN;
804    String mTopData;
805    boolean mProcessesReady = false;
806    boolean mSystemReady = false;
807    boolean mBooting = false;
808    boolean mWaitingUpdate = false;
809    boolean mDidUpdate = false;
810    boolean mOnBattery = false;
811    boolean mLaunchWarningShown = false;
812
813    Context mContext;
814
815    int mFactoryTest;
816
817    boolean mCheckedForSetup;
818
819    /**
820     * The time at which we will allow normal application switches again,
821     * after a call to {@link #stopAppSwitches()}.
822     */
823    long mAppSwitchesAllowedTime;
824
825    /**
826     * This is set to true after the first switch after mAppSwitchesAllowedTime
827     * is set; any switches after that will clear the time.
828     */
829    boolean mDidAppSwitch;
830
831    /**
832     * Last time (in realtime) at which we checked for power usage.
833     */
834    long mLastPowerCheckRealtime;
835
836    /**
837     * Last time (in uptime) at which we checked for power usage.
838     */
839    long mLastPowerCheckUptime;
840
841    /**
842     * Set while we are wanting to sleep, to prevent any
843     * activities from being started/resumed.
844     */
845    boolean mSleeping = false;
846
847    /**
848     * State of external calls telling us if the device is asleep.
849     */
850    boolean mWentToSleep = false;
851
852    /**
853     * State of external call telling us if the lock screen is shown.
854     */
855    boolean mLockScreenShown = false;
856
857    /**
858     * Set if we are shutting down the system, similar to sleeping.
859     */
860    boolean mShuttingDown = false;
861
862    /**
863     * Current sequence id for oom_adj computation traversal.
864     */
865    int mAdjSeq = 0;
866
867    /**
868     * Current sequence id for process LRU updating.
869     */
870    int mLruSeq = 0;
871
872    /**
873     * Keep track of the non-cached/empty process we last found, to help
874     * determine how to distribute cached/empty processes next time.
875     */
876    int mNumNonCachedProcs = 0;
877
878    /**
879     * Keep track of the number of cached hidden procs, to balance oom adj
880     * distribution between those and empty procs.
881     */
882    int mNumCachedHiddenProcs = 0;
883
884    /**
885     * Keep track of the number of service processes we last found, to
886     * determine on the next iteration which should be B services.
887     */
888    int mNumServiceProcs = 0;
889    int mNewNumAServiceProcs = 0;
890    int mNewNumServiceProcs = 0;
891
892    /**
893     * Allow the current computed overall memory level of the system to go down?
894     * This is set to false when we are killing processes for reasons other than
895     * memory management, so that the now smaller process list will not be taken as
896     * an indication that memory is tighter.
897     */
898    boolean mAllowLowerMemLevel = false;
899
900    /**
901     * The last computed memory level, for holding when we are in a state that
902     * processes are going away for other reasons.
903     */
904    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
905
906    /**
907     * The last total number of process we have, to determine if changes actually look
908     * like a shrinking number of process due to lower RAM.
909     */
910    int mLastNumProcesses;
911
912    /**
913     * The uptime of the last time we performed idle maintenance.
914     */
915    long mLastIdleTime = SystemClock.uptimeMillis();
916
917    /**
918     * Total time spent with RAM that has been added in the past since the last idle time.
919     */
920    long mLowRamTimeSinceLastIdle = 0;
921
922    /**
923     * If RAM is currently low, when that horrible situatin started.
924     */
925    long mLowRamStartTime = 0;
926
927    /**
928     * This is set if we had to do a delayed dexopt of an app before launching
929     * it, to increasing the ANR timeouts in that case.
930     */
931    boolean mDidDexOpt;
932
933    /**
934     * Set if the systemServer made a call to enterSafeMode.
935     */
936    boolean mSafeMode;
937
938    String mDebugApp = null;
939    boolean mWaitForDebugger = false;
940    boolean mDebugTransient = false;
941    String mOrigDebugApp = null;
942    boolean mOrigWaitForDebugger = false;
943    boolean mAlwaysFinishActivities = false;
944    IActivityController mController = null;
945    String mProfileApp = null;
946    ProcessRecord mProfileProc = null;
947    String mProfileFile;
948    ParcelFileDescriptor mProfileFd;
949    int mProfileType = 0;
950    boolean mAutoStopProfiler = false;
951    String mOpenGlTraceApp = null;
952
953    static class ProcessChangeItem {
954        static final int CHANGE_ACTIVITIES = 1<<0;
955        static final int CHANGE_IMPORTANCE= 1<<1;
956        int changes;
957        int uid;
958        int pid;
959        int importance;
960        boolean foregroundActivities;
961    }
962
963    final RemoteCallbackList<IProcessObserver> mProcessObservers
964            = new RemoteCallbackList<IProcessObserver>();
965    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
966
967    final ArrayList<ProcessChangeItem> mPendingProcessChanges
968            = new ArrayList<ProcessChangeItem>();
969    final ArrayList<ProcessChangeItem> mAvailProcessChanges
970            = new ArrayList<ProcessChangeItem>();
971
972    /**
973     * Runtime CPU use collection thread.  This object's lock is used to
974     * protect all related state.
975     */
976    final Thread mProcessCpuThread;
977
978    /**
979     * Used to collect process stats when showing not responding dialog.
980     * Protected by mProcessCpuThread.
981     */
982    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
983            MONITOR_THREAD_CPU_USAGE);
984    final AtomicLong mLastCpuTime = new AtomicLong(0);
985    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
986
987    long mLastWriteTime = 0;
988
989    /**
990     * Used to retain an update lock when the foreground activity is in
991     * immersive mode.
992     */
993    final UpdateLock mUpdateLock = new UpdateLock("immersive");
994
995    /**
996     * Set to true after the system has finished booting.
997     */
998    boolean mBooted = false;
999
1000    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1001    int mProcessLimitOverride = -1;
1002
1003    WindowManagerService mWindowManager;
1004
1005    final ActivityThread mSystemThread;
1006
1007    int mCurrentUserId = 0;
1008    private UserManagerService mUserManager;
1009
1010    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1011        final ProcessRecord mApp;
1012        final int mPid;
1013        final IApplicationThread mAppThread;
1014
1015        AppDeathRecipient(ProcessRecord app, int pid,
1016                IApplicationThread thread) {
1017            if (localLOGV) Slog.v(
1018                TAG, "New death recipient " + this
1019                + " for thread " + thread.asBinder());
1020            mApp = app;
1021            mPid = pid;
1022            mAppThread = thread;
1023        }
1024
1025        @Override
1026        public void binderDied() {
1027            if (localLOGV) Slog.v(
1028                TAG, "Death received in " + this
1029                + " for thread " + mAppThread.asBinder());
1030            synchronized(ActivityManagerService.this) {
1031                appDiedLocked(mApp, mPid, mAppThread);
1032            }
1033        }
1034    }
1035
1036    static final int SHOW_ERROR_MSG = 1;
1037    static final int SHOW_NOT_RESPONDING_MSG = 2;
1038    static final int SHOW_FACTORY_ERROR_MSG = 3;
1039    static final int UPDATE_CONFIGURATION_MSG = 4;
1040    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1041    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1042    static final int SERVICE_TIMEOUT_MSG = 12;
1043    static final int UPDATE_TIME_ZONE = 13;
1044    static final int SHOW_UID_ERROR_MSG = 14;
1045    static final int IM_FEELING_LUCKY_MSG = 15;
1046    static final int PROC_START_TIMEOUT_MSG = 20;
1047    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1048    static final int KILL_APPLICATION_MSG = 22;
1049    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1050    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1051    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1052    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1053    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1054    static final int CLEAR_DNS_CACHE_MSG = 28;
1055    static final int UPDATE_HTTP_PROXY_MSG = 29;
1056    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1057    static final int DISPATCH_PROCESSES_CHANGED = 31;
1058    static final int DISPATCH_PROCESS_DIED = 32;
1059    static final int REPORT_MEM_USAGE_MSG = 33;
1060    static final int REPORT_USER_SWITCH_MSG = 34;
1061    static final int CONTINUE_USER_SWITCH_MSG = 35;
1062    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1063    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1064    static final int PERSIST_URI_GRANTS_MSG = 38;
1065    static final int REQUEST_ALL_PSS_MSG = 39;
1066    static final int UPDATE_TIME = 40;
1067
1068    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1069    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1070    static final int FIRST_COMPAT_MODE_MSG = 300;
1071    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1072
1073    AlertDialog mUidAlert;
1074    CompatModeDialog mCompatModeDialog;
1075    long mLastMemUsageReportTime = 0;
1076
1077    /**
1078     * Flag whether the current user is a "monkey", i.e. whether
1079     * the UI is driven by a UI automation tool.
1080     */
1081    private boolean mUserIsMonkey;
1082
1083    final ServiceThread mHandlerThread;
1084    final MainHandler mHandler;
1085
1086    final class MainHandler extends Handler {
1087        public MainHandler(Looper looper) {
1088            super(looper, null, true);
1089        }
1090
1091        @Override
1092        public void handleMessage(Message msg) {
1093            switch (msg.what) {
1094            case SHOW_ERROR_MSG: {
1095                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1096                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1097                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1098                synchronized (ActivityManagerService.this) {
1099                    ProcessRecord proc = (ProcessRecord)data.get("app");
1100                    AppErrorResult res = (AppErrorResult) data.get("result");
1101                    if (proc != null && proc.crashDialog != null) {
1102                        Slog.e(TAG, "App already has crash dialog: " + proc);
1103                        if (res != null) {
1104                            res.set(0);
1105                        }
1106                        return;
1107                    }
1108                    if (!showBackground && UserHandle.getAppId(proc.uid)
1109                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1110                            && proc.pid != MY_PID) {
1111                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1112                        if (res != null) {
1113                            res.set(0);
1114                        }
1115                        return;
1116                    }
1117                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1118                        Dialog d = new AppErrorDialog(mContext,
1119                                ActivityManagerService.this, res, proc);
1120                        d.show();
1121                        proc.crashDialog = d;
1122                    } else {
1123                        // The device is asleep, so just pretend that the user
1124                        // saw a crash dialog and hit "force quit".
1125                        if (res != null) {
1126                            res.set(0);
1127                        }
1128                    }
1129                }
1130
1131                ensureBootCompleted();
1132            } break;
1133            case SHOW_NOT_RESPONDING_MSG: {
1134                synchronized (ActivityManagerService.this) {
1135                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1136                    ProcessRecord proc = (ProcessRecord)data.get("app");
1137                    if (proc != null && proc.anrDialog != null) {
1138                        Slog.e(TAG, "App already has anr dialog: " + proc);
1139                        return;
1140                    }
1141
1142                    Intent intent = new Intent("android.intent.action.ANR");
1143                    if (!mProcessesReady) {
1144                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1145                                | Intent.FLAG_RECEIVER_FOREGROUND);
1146                    }
1147                    broadcastIntentLocked(null, null, intent,
1148                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1149                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1150
1151                    if (mShowDialogs) {
1152                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1153                                mContext, proc, (ActivityRecord)data.get("activity"),
1154                                msg.arg1 != 0);
1155                        d.show();
1156                        proc.anrDialog = d;
1157                    } else {
1158                        // Just kill the app if there is no dialog to be shown.
1159                        killAppAtUsersRequest(proc, null);
1160                    }
1161                }
1162
1163                ensureBootCompleted();
1164            } break;
1165            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1166                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1167                synchronized (ActivityManagerService.this) {
1168                    ProcessRecord proc = (ProcessRecord) data.get("app");
1169                    if (proc == null) {
1170                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1171                        break;
1172                    }
1173                    if (proc.crashDialog != null) {
1174                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1175                        return;
1176                    }
1177                    AppErrorResult res = (AppErrorResult) data.get("result");
1178                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1179                        Dialog d = new StrictModeViolationDialog(mContext,
1180                                ActivityManagerService.this, res, proc);
1181                        d.show();
1182                        proc.crashDialog = d;
1183                    } else {
1184                        // The device is asleep, so just pretend that the user
1185                        // saw a crash dialog and hit "force quit".
1186                        res.set(0);
1187                    }
1188                }
1189                ensureBootCompleted();
1190            } break;
1191            case SHOW_FACTORY_ERROR_MSG: {
1192                Dialog d = new FactoryErrorDialog(
1193                    mContext, msg.getData().getCharSequence("msg"));
1194                d.show();
1195                ensureBootCompleted();
1196            } break;
1197            case UPDATE_CONFIGURATION_MSG: {
1198                final ContentResolver resolver = mContext.getContentResolver();
1199                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1200            } break;
1201            case GC_BACKGROUND_PROCESSES_MSG: {
1202                synchronized (ActivityManagerService.this) {
1203                    performAppGcsIfAppropriateLocked();
1204                }
1205            } break;
1206            case WAIT_FOR_DEBUGGER_MSG: {
1207                synchronized (ActivityManagerService.this) {
1208                    ProcessRecord app = (ProcessRecord)msg.obj;
1209                    if (msg.arg1 != 0) {
1210                        if (!app.waitedForDebugger) {
1211                            Dialog d = new AppWaitingForDebuggerDialog(
1212                                    ActivityManagerService.this,
1213                                    mContext, app);
1214                            app.waitDialog = d;
1215                            app.waitedForDebugger = true;
1216                            d.show();
1217                        }
1218                    } else {
1219                        if (app.waitDialog != null) {
1220                            app.waitDialog.dismiss();
1221                            app.waitDialog = null;
1222                        }
1223                    }
1224                }
1225            } break;
1226            case SERVICE_TIMEOUT_MSG: {
1227                if (mDidDexOpt) {
1228                    mDidDexOpt = false;
1229                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1230                    nmsg.obj = msg.obj;
1231                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1232                    return;
1233                }
1234                mServices.serviceTimeout((ProcessRecord)msg.obj);
1235            } break;
1236            case UPDATE_TIME_ZONE: {
1237                synchronized (ActivityManagerService.this) {
1238                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1239                        ProcessRecord r = mLruProcesses.get(i);
1240                        if (r.thread != null) {
1241                            try {
1242                                r.thread.updateTimeZone();
1243                            } catch (RemoteException ex) {
1244                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1245                            }
1246                        }
1247                    }
1248                }
1249            } break;
1250            case CLEAR_DNS_CACHE_MSG: {
1251                synchronized (ActivityManagerService.this) {
1252                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1253                        ProcessRecord r = mLruProcesses.get(i);
1254                        if (r.thread != null) {
1255                            try {
1256                                r.thread.clearDnsCache();
1257                            } catch (RemoteException ex) {
1258                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1259                            }
1260                        }
1261                    }
1262                }
1263            } break;
1264            case UPDATE_HTTP_PROXY_MSG: {
1265                ProxyProperties proxy = (ProxyProperties)msg.obj;
1266                String host = "";
1267                String port = "";
1268                String exclList = "";
1269                String pacFileUrl = null;
1270                if (proxy != null) {
1271                    host = proxy.getHost();
1272                    port = Integer.toString(proxy.getPort());
1273                    exclList = proxy.getExclusionList();
1274                    pacFileUrl = proxy.getPacFileUrl();
1275                }
1276                synchronized (ActivityManagerService.this) {
1277                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1278                        ProcessRecord r = mLruProcesses.get(i);
1279                        if (r.thread != null) {
1280                            try {
1281                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1282                            } catch (RemoteException ex) {
1283                                Slog.w(TAG, "Failed to update http proxy for: " +
1284                                        r.info.processName);
1285                            }
1286                        }
1287                    }
1288                }
1289            } break;
1290            case SHOW_UID_ERROR_MSG: {
1291                String title = "System UIDs Inconsistent";
1292                String text = "UIDs on the system are inconsistent, you need to wipe your"
1293                        + " data partition or your device will be unstable.";
1294                Log.e(TAG, title + ": " + text);
1295                if (mShowDialogs) {
1296                    // XXX This is a temporary dialog, no need to localize.
1297                    AlertDialog d = new BaseErrorDialog(mContext);
1298                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1299                    d.setCancelable(false);
1300                    d.setTitle(title);
1301                    d.setMessage(text);
1302                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1303                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1304                    mUidAlert = d;
1305                    d.show();
1306                }
1307            } break;
1308            case IM_FEELING_LUCKY_MSG: {
1309                if (mUidAlert != null) {
1310                    mUidAlert.dismiss();
1311                    mUidAlert = null;
1312                }
1313            } break;
1314            case PROC_START_TIMEOUT_MSG: {
1315                if (mDidDexOpt) {
1316                    mDidDexOpt = false;
1317                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1318                    nmsg.obj = msg.obj;
1319                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1320                    return;
1321                }
1322                ProcessRecord app = (ProcessRecord)msg.obj;
1323                synchronized (ActivityManagerService.this) {
1324                    processStartTimedOutLocked(app);
1325                }
1326            } break;
1327            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1328                synchronized (ActivityManagerService.this) {
1329                    doPendingActivityLaunchesLocked(true);
1330                }
1331            } break;
1332            case KILL_APPLICATION_MSG: {
1333                synchronized (ActivityManagerService.this) {
1334                    int appid = msg.arg1;
1335                    boolean restart = (msg.arg2 == 1);
1336                    Bundle bundle = (Bundle)msg.obj;
1337                    String pkg = bundle.getString("pkg");
1338                    String reason = bundle.getString("reason");
1339                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1340                            UserHandle.USER_ALL, reason);
1341                }
1342            } break;
1343            case FINALIZE_PENDING_INTENT_MSG: {
1344                ((PendingIntentRecord)msg.obj).completeFinalize();
1345            } break;
1346            case POST_HEAVY_NOTIFICATION_MSG: {
1347                INotificationManager inm = NotificationManager.getService();
1348                if (inm == null) {
1349                    return;
1350                }
1351
1352                ActivityRecord root = (ActivityRecord)msg.obj;
1353                ProcessRecord process = root.app;
1354                if (process == null) {
1355                    return;
1356                }
1357
1358                try {
1359                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1360                    String text = mContext.getString(R.string.heavy_weight_notification,
1361                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1362                    Notification notification = new Notification();
1363                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1364                    notification.when = 0;
1365                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1366                    notification.tickerText = text;
1367                    notification.defaults = 0; // please be quiet
1368                    notification.sound = null;
1369                    notification.vibrate = null;
1370                    notification.setLatestEventInfo(context, text,
1371                            mContext.getText(R.string.heavy_weight_notification_detail),
1372                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1373                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1374                                    new UserHandle(root.userId)));
1375
1376                    try {
1377                        int[] outId = new int[1];
1378                        inm.enqueueNotificationWithTag("android", "android", null,
1379                                R.string.heavy_weight_notification,
1380                                notification, outId, root.userId);
1381                    } catch (RuntimeException e) {
1382                        Slog.w(ActivityManagerService.TAG,
1383                                "Error showing notification for heavy-weight app", e);
1384                    } catch (RemoteException e) {
1385                    }
1386                } catch (NameNotFoundException e) {
1387                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1388                }
1389            } break;
1390            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1391                INotificationManager inm = NotificationManager.getService();
1392                if (inm == null) {
1393                    return;
1394                }
1395                try {
1396                    inm.cancelNotificationWithTag("android", null,
1397                            R.string.heavy_weight_notification,  msg.arg1);
1398                } catch (RuntimeException e) {
1399                    Slog.w(ActivityManagerService.TAG,
1400                            "Error canceling notification for service", e);
1401                } catch (RemoteException e) {
1402                }
1403            } break;
1404            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1405                synchronized (ActivityManagerService.this) {
1406                    checkExcessivePowerUsageLocked(true);
1407                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1408                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1409                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1410                }
1411            } break;
1412            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1413                synchronized (ActivityManagerService.this) {
1414                    ActivityRecord ar = (ActivityRecord)msg.obj;
1415                    if (mCompatModeDialog != null) {
1416                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1417                                ar.info.applicationInfo.packageName)) {
1418                            return;
1419                        }
1420                        mCompatModeDialog.dismiss();
1421                        mCompatModeDialog = null;
1422                    }
1423                    if (ar != null && false) {
1424                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1425                                ar.packageName)) {
1426                            int mode = mCompatModePackages.computeCompatModeLocked(
1427                                    ar.info.applicationInfo);
1428                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1429                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1430                                mCompatModeDialog = new CompatModeDialog(
1431                                        ActivityManagerService.this, mContext,
1432                                        ar.info.applicationInfo);
1433                                mCompatModeDialog.show();
1434                            }
1435                        }
1436                    }
1437                }
1438                break;
1439            }
1440            case DISPATCH_PROCESSES_CHANGED: {
1441                dispatchProcessesChanged();
1442                break;
1443            }
1444            case DISPATCH_PROCESS_DIED: {
1445                final int pid = msg.arg1;
1446                final int uid = msg.arg2;
1447                dispatchProcessDied(pid, uid);
1448                break;
1449            }
1450            case REPORT_MEM_USAGE_MSG: {
1451                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1452                Thread thread = new Thread() {
1453                    @Override public void run() {
1454                        final SparseArray<ProcessMemInfo> infoMap
1455                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1456                        for (int i=0, N=memInfos.size(); i<N; i++) {
1457                            ProcessMemInfo mi = memInfos.get(i);
1458                            infoMap.put(mi.pid, mi);
1459                        }
1460                        updateCpuStatsNow();
1461                        synchronized (mProcessCpuThread) {
1462                            final int N = mProcessCpuTracker.countStats();
1463                            for (int i=0; i<N; i++) {
1464                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1465                                if (st.vsize > 0) {
1466                                    long pss = Debug.getPss(st.pid, null);
1467                                    if (pss > 0) {
1468                                        if (infoMap.indexOfKey(st.pid) < 0) {
1469                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1470                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1471                                            mi.pss = pss;
1472                                            memInfos.add(mi);
1473                                        }
1474                                    }
1475                                }
1476                            }
1477                        }
1478
1479                        long totalPss = 0;
1480                        for (int i=0, N=memInfos.size(); i<N; i++) {
1481                            ProcessMemInfo mi = memInfos.get(i);
1482                            if (mi.pss == 0) {
1483                                mi.pss = Debug.getPss(mi.pid, null);
1484                            }
1485                            totalPss += mi.pss;
1486                        }
1487                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1488                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1489                                if (lhs.oomAdj != rhs.oomAdj) {
1490                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1491                                }
1492                                if (lhs.pss != rhs.pss) {
1493                                    return lhs.pss < rhs.pss ? 1 : -1;
1494                                }
1495                                return 0;
1496                            }
1497                        });
1498
1499                        StringBuilder tag = new StringBuilder(128);
1500                        StringBuilder stack = new StringBuilder(128);
1501                        tag.append("Low on memory -- ");
1502                        appendMemBucket(tag, totalPss, "total", false);
1503                        appendMemBucket(stack, totalPss, "total", true);
1504
1505                        StringBuilder logBuilder = new StringBuilder(1024);
1506                        logBuilder.append("Low on memory:\n");
1507
1508                        boolean firstLine = true;
1509                        int lastOomAdj = Integer.MIN_VALUE;
1510                        for (int i=0, N=memInfos.size(); i<N; i++) {
1511                            ProcessMemInfo mi = memInfos.get(i);
1512
1513                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1514                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1515                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1516                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1517                                if (lastOomAdj != mi.oomAdj) {
1518                                    lastOomAdj = mi.oomAdj;
1519                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1520                                        tag.append(" / ");
1521                                    }
1522                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1523                                        if (firstLine) {
1524                                            stack.append(":");
1525                                            firstLine = false;
1526                                        }
1527                                        stack.append("\n\t at ");
1528                                    } else {
1529                                        stack.append("$");
1530                                    }
1531                                } else {
1532                                    tag.append(" ");
1533                                    stack.append("$");
1534                                }
1535                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1536                                    appendMemBucket(tag, mi.pss, mi.name, false);
1537                                }
1538                                appendMemBucket(stack, mi.pss, mi.name, true);
1539                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1540                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1541                                    stack.append("(");
1542                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1543                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1544                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1545                                            stack.append(":");
1546                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1547                                        }
1548                                    }
1549                                    stack.append(")");
1550                                }
1551                            }
1552
1553                            logBuilder.append("  ");
1554                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1555                            logBuilder.append(' ');
1556                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1557                            logBuilder.append(' ');
1558                            ProcessList.appendRamKb(logBuilder, mi.pss);
1559                            logBuilder.append(" kB: ");
1560                            logBuilder.append(mi.name);
1561                            logBuilder.append(" (");
1562                            logBuilder.append(mi.pid);
1563                            logBuilder.append(") ");
1564                            logBuilder.append(mi.adjType);
1565                            logBuilder.append('\n');
1566                            if (mi.adjReason != null) {
1567                                logBuilder.append("                      ");
1568                                logBuilder.append(mi.adjReason);
1569                                logBuilder.append('\n');
1570                            }
1571                        }
1572
1573                        logBuilder.append("           ");
1574                        ProcessList.appendRamKb(logBuilder, totalPss);
1575                        logBuilder.append(" kB: TOTAL\n");
1576
1577                        long[] infos = new long[Debug.MEMINFO_COUNT];
1578                        Debug.getMemInfo(infos);
1579                        logBuilder.append("  MemInfo: ");
1580                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1581                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1582                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1583                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1584                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1585                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1586                            logBuilder.append("  ZRAM: ");
1587                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1588                            logBuilder.append(" kB RAM, ");
1589                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1590                            logBuilder.append(" kB swap total, ");
1591                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1592                            logBuilder.append(" kB swap free\n");
1593                        }
1594                        Slog.i(TAG, logBuilder.toString());
1595
1596                        StringBuilder dropBuilder = new StringBuilder(1024);
1597                        /*
1598                        StringWriter oomSw = new StringWriter();
1599                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1600                        StringWriter catSw = new StringWriter();
1601                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1602                        String[] emptyArgs = new String[] { };
1603                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1604                        oomPw.flush();
1605                        String oomString = oomSw.toString();
1606                        */
1607                        dropBuilder.append(stack);
1608                        dropBuilder.append('\n');
1609                        dropBuilder.append('\n');
1610                        dropBuilder.append(logBuilder);
1611                        dropBuilder.append('\n');
1612                        /*
1613                        dropBuilder.append(oomString);
1614                        dropBuilder.append('\n');
1615                        */
1616                        StringWriter catSw = new StringWriter();
1617                        synchronized (ActivityManagerService.this) {
1618                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1619                            String[] emptyArgs = new String[] { };
1620                            catPw.println();
1621                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1622                            catPw.println();
1623                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1624                                    false, false, null);
1625                            catPw.println();
1626                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1627                            catPw.flush();
1628                        }
1629                        dropBuilder.append(catSw.toString());
1630                        addErrorToDropBox("lowmem", null, "system_server", null,
1631                                null, tag.toString(), dropBuilder.toString(), null, null);
1632                        //Slog.i(TAG, "Sent to dropbox:");
1633                        //Slog.i(TAG, dropBuilder.toString());
1634                        synchronized (ActivityManagerService.this) {
1635                            long now = SystemClock.uptimeMillis();
1636                            if (mLastMemUsageReportTime < now) {
1637                                mLastMemUsageReportTime = now;
1638                            }
1639                        }
1640                    }
1641                };
1642                thread.start();
1643                break;
1644            }
1645            case REPORT_USER_SWITCH_MSG: {
1646                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1647                break;
1648            }
1649            case CONTINUE_USER_SWITCH_MSG: {
1650                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1651                break;
1652            }
1653            case USER_SWITCH_TIMEOUT_MSG: {
1654                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1655                break;
1656            }
1657            case IMMERSIVE_MODE_LOCK_MSG: {
1658                final boolean nextState = (msg.arg1 != 0);
1659                if (mUpdateLock.isHeld() != nextState) {
1660                    if (DEBUG_IMMERSIVE) {
1661                        final ActivityRecord r = (ActivityRecord) msg.obj;
1662                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1663                    }
1664                    if (nextState) {
1665                        mUpdateLock.acquire();
1666                    } else {
1667                        mUpdateLock.release();
1668                    }
1669                }
1670                break;
1671            }
1672            case PERSIST_URI_GRANTS_MSG: {
1673                writeGrantedUriPermissions();
1674                break;
1675            }
1676            case REQUEST_ALL_PSS_MSG: {
1677                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1678                break;
1679            }
1680            case UPDATE_TIME: {
1681                synchronized (ActivityManagerService.this) {
1682                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1683                        ProcessRecord r = mLruProcesses.get(i);
1684                        if (r.thread != null) {
1685                            try {
1686                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1687                            } catch (RemoteException ex) {
1688                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1689                            }
1690                        }
1691                    }
1692                }
1693
1694                break;
1695            }
1696            }
1697        }
1698    };
1699
1700    static final int COLLECT_PSS_BG_MSG = 1;
1701
1702    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1703        @Override
1704        public void handleMessage(Message msg) {
1705            switch (msg.what) {
1706            case COLLECT_PSS_BG_MSG: {
1707                int i=0, num=0;
1708                long start = SystemClock.uptimeMillis();
1709                long[] tmp = new long[1];
1710                do {
1711                    ProcessRecord proc;
1712                    int procState;
1713                    int pid;
1714                    synchronized (ActivityManagerService.this) {
1715                        if (i >= mPendingPssProcesses.size()) {
1716                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1717                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1718                            mPendingPssProcesses.clear();
1719                            return;
1720                        }
1721                        proc = mPendingPssProcesses.get(i);
1722                        procState = proc.pssProcState;
1723                        if (proc.thread != null && procState == proc.setProcState) {
1724                            pid = proc.pid;
1725                        } else {
1726                            proc = null;
1727                            pid = 0;
1728                        }
1729                        i++;
1730                    }
1731                    if (proc != null) {
1732                        long pss = Debug.getPss(pid, tmp);
1733                        synchronized (ActivityManagerService.this) {
1734                            if (proc.thread != null && proc.setProcState == procState
1735                                    && proc.pid == pid) {
1736                                num++;
1737                                proc.lastPssTime = SystemClock.uptimeMillis();
1738                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1739                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1740                                        + ": " + pss + " lastPss=" + proc.lastPss
1741                                        + " state=" + ProcessList.makeProcStateString(procState));
1742                                if (proc.initialIdlePss == 0) {
1743                                    proc.initialIdlePss = pss;
1744                                }
1745                                proc.lastPss = pss;
1746                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1747                                    proc.lastCachedPss = pss;
1748                                }
1749                            }
1750                        }
1751                    }
1752                } while (true);
1753            }
1754            }
1755        }
1756    };
1757
1758    public void setSystemProcess() {
1759        try {
1760            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1761            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1762            ServiceManager.addService("meminfo", new MemBinder(this));
1763            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1764            ServiceManager.addService("dbinfo", new DbBinder(this));
1765            if (MONITOR_CPU_USAGE) {
1766                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1767            }
1768            ServiceManager.addService("permission", new PermissionController(this));
1769
1770            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1771                    "android", STOCK_PM_FLAGS);
1772            mSystemThread.installSystemApplicationInfo(info);
1773
1774            synchronized (this) {
1775                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1776                app.persistent = true;
1777                app.pid = MY_PID;
1778                app.maxAdj = ProcessList.SYSTEM_ADJ;
1779                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1780                mProcessNames.put(app.processName, app.uid, app);
1781                synchronized (mPidsSelfLocked) {
1782                    mPidsSelfLocked.put(app.pid, app);
1783                }
1784                updateLruProcessLocked(app, false, null);
1785                updateOomAdjLocked();
1786            }
1787        } catch (PackageManager.NameNotFoundException e) {
1788            throw new RuntimeException(
1789                    "Unable to find android system package", e);
1790        }
1791    }
1792
1793    public void setWindowManager(WindowManagerService wm) {
1794        mWindowManager = wm;
1795        mStackSupervisor.setWindowManager(wm);
1796    }
1797
1798    public void startObservingNativeCrashes() {
1799        final NativeCrashListener ncl = new NativeCrashListener(this);
1800        ncl.start();
1801    }
1802
1803    public IAppOpsService getAppOpsService() {
1804        return mAppOpsService;
1805    }
1806
1807    static class MemBinder extends Binder {
1808        ActivityManagerService mActivityManagerService;
1809        MemBinder(ActivityManagerService activityManagerService) {
1810            mActivityManagerService = activityManagerService;
1811        }
1812
1813        @Override
1814        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1815            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1816                    != PackageManager.PERMISSION_GRANTED) {
1817                pw.println("Permission Denial: can't dump meminfo from from pid="
1818                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1819                        + " without permission " + android.Manifest.permission.DUMP);
1820                return;
1821            }
1822
1823            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1824        }
1825    }
1826
1827    static class GraphicsBinder extends Binder {
1828        ActivityManagerService mActivityManagerService;
1829        GraphicsBinder(ActivityManagerService activityManagerService) {
1830            mActivityManagerService = activityManagerService;
1831        }
1832
1833        @Override
1834        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1835            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1836                    != PackageManager.PERMISSION_GRANTED) {
1837                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1838                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1839                        + " without permission " + android.Manifest.permission.DUMP);
1840                return;
1841            }
1842
1843            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1844        }
1845    }
1846
1847    static class DbBinder extends Binder {
1848        ActivityManagerService mActivityManagerService;
1849        DbBinder(ActivityManagerService activityManagerService) {
1850            mActivityManagerService = activityManagerService;
1851        }
1852
1853        @Override
1854        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1855            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1856                    != PackageManager.PERMISSION_GRANTED) {
1857                pw.println("Permission Denial: can't dump dbinfo from from pid="
1858                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1859                        + " without permission " + android.Manifest.permission.DUMP);
1860                return;
1861            }
1862
1863            mActivityManagerService.dumpDbInfo(fd, pw, args);
1864        }
1865    }
1866
1867    static class CpuBinder extends Binder {
1868        ActivityManagerService mActivityManagerService;
1869        CpuBinder(ActivityManagerService activityManagerService) {
1870            mActivityManagerService = activityManagerService;
1871        }
1872
1873        @Override
1874        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1875            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1876                    != PackageManager.PERMISSION_GRANTED) {
1877                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1878                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1879                        + " without permission " + android.Manifest.permission.DUMP);
1880                return;
1881            }
1882
1883            synchronized (mActivityManagerService.mProcessCpuThread) {
1884                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1885                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1886                        SystemClock.uptimeMillis()));
1887            }
1888        }
1889    }
1890
1891    public static final class Lifecycle extends SystemService {
1892        private final ActivityManagerService mService;
1893
1894        public Lifecycle(Context context) {
1895            super(context);
1896            mService = new ActivityManagerService(context);
1897        }
1898
1899        @Override
1900        public void onStart() {
1901            mService.start();
1902        }
1903
1904        public ActivityManagerService getService() {
1905            return mService;
1906        }
1907    }
1908
1909    // Note: This method is invoked on the main thread but may need to attach various
1910    // handlers to other threads.  So take care to be explicit about the looper.
1911    public ActivityManagerService(Context systemContext) {
1912        mContext = systemContext;
1913        mFactoryTest = FactoryTest.getMode();
1914        mSystemThread = ActivityThread.currentActivityThread();
1915
1916        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1917
1918        mHandlerThread = new ServiceThread(TAG,
1919                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1920        mHandlerThread.start();
1921        mHandler = new MainHandler(mHandlerThread.getLooper());
1922
1923        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1924                "foreground", BROADCAST_FG_TIMEOUT, false);
1925        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1926                "background", BROADCAST_BG_TIMEOUT, true);
1927        mBroadcastQueues[0] = mFgBroadcastQueue;
1928        mBroadcastQueues[1] = mBgBroadcastQueue;
1929
1930        mServices = new ActiveServices(this);
1931        mProviderMap = new ProviderMap(this);
1932
1933        // TODO: Move creation of battery stats service outside of activity manager service.
1934        File dataDir = Environment.getDataDirectory();
1935        File systemDir = new File(dataDir, "system");
1936        systemDir.mkdirs();
1937        mBatteryStatsService = new BatteryStatsService(new File(
1938                systemDir, "batterystats.bin").toString(), mHandler);
1939        mBatteryStatsService.getActiveStatistics().readLocked();
1940        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1941        mOnBattery = DEBUG_POWER ? true
1942                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1943        mBatteryStatsService.getActiveStatistics().setCallback(this);
1944
1945        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1946
1947        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1948        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1949
1950        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1951
1952        // User 0 is the first and only user that runs at boot.
1953        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1954        mUserLru.add(Integer.valueOf(0));
1955        updateStartedUserArrayLocked();
1956
1957        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1958            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1959
1960        mConfiguration.setToDefaults();
1961        mConfiguration.setLocale(Locale.getDefault());
1962
1963        mConfigurationSeq = mConfiguration.seq = 1;
1964        mProcessCpuTracker.init();
1965
1966        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1967        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1968        mStackSupervisor = new ActivityStackSupervisor(this);
1969
1970        mProcessCpuThread = new Thread("CpuTracker") {
1971            @Override
1972            public void run() {
1973                while (true) {
1974                    try {
1975                        try {
1976                            synchronized(this) {
1977                                final long now = SystemClock.uptimeMillis();
1978                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1979                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1980                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1981                                //        + ", write delay=" + nextWriteDelay);
1982                                if (nextWriteDelay < nextCpuDelay) {
1983                                    nextCpuDelay = nextWriteDelay;
1984                                }
1985                                if (nextCpuDelay > 0) {
1986                                    mProcessCpuMutexFree.set(true);
1987                                    this.wait(nextCpuDelay);
1988                                }
1989                            }
1990                        } catch (InterruptedException e) {
1991                        }
1992                        updateCpuStatsNow();
1993                    } catch (Exception e) {
1994                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1995                    }
1996                }
1997            }
1998        };
1999
2000        Watchdog.getInstance().addMonitor(this);
2001        Watchdog.getInstance().addThread(mHandler);
2002    }
2003
2004    private void start() {
2005        mProcessCpuThread.start();
2006
2007        mBatteryStatsService.publish(mContext);
2008        mUsageStatsService.publish(mContext);
2009        mAppOpsService.publish(mContext);
2010
2011        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2012    }
2013
2014    @Override
2015    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2016            throws RemoteException {
2017        if (code == SYSPROPS_TRANSACTION) {
2018            // We need to tell all apps about the system property change.
2019            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2020            synchronized(this) {
2021                final int NP = mProcessNames.getMap().size();
2022                for (int ip=0; ip<NP; ip++) {
2023                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2024                    final int NA = apps.size();
2025                    for (int ia=0; ia<NA; ia++) {
2026                        ProcessRecord app = apps.valueAt(ia);
2027                        if (app.thread != null) {
2028                            procs.add(app.thread.asBinder());
2029                        }
2030                    }
2031                }
2032            }
2033
2034            int N = procs.size();
2035            for (int i=0; i<N; i++) {
2036                Parcel data2 = Parcel.obtain();
2037                try {
2038                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2039                } catch (RemoteException e) {
2040                }
2041                data2.recycle();
2042            }
2043        }
2044        try {
2045            return super.onTransact(code, data, reply, flags);
2046        } catch (RuntimeException e) {
2047            // The activity manager only throws security exceptions, so let's
2048            // log all others.
2049            if (!(e instanceof SecurityException)) {
2050                Slog.wtf(TAG, "Activity Manager Crash", e);
2051            }
2052            throw e;
2053        }
2054    }
2055
2056    void updateCpuStats() {
2057        final long now = SystemClock.uptimeMillis();
2058        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2059            return;
2060        }
2061        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2062            synchronized (mProcessCpuThread) {
2063                mProcessCpuThread.notify();
2064            }
2065        }
2066    }
2067
2068    void updateCpuStatsNow() {
2069        synchronized (mProcessCpuThread) {
2070            mProcessCpuMutexFree.set(false);
2071            final long now = SystemClock.uptimeMillis();
2072            boolean haveNewCpuStats = false;
2073
2074            if (MONITOR_CPU_USAGE &&
2075                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2076                mLastCpuTime.set(now);
2077                haveNewCpuStats = true;
2078                mProcessCpuTracker.update();
2079                //Slog.i(TAG, mProcessCpu.printCurrentState());
2080                //Slog.i(TAG, "Total CPU usage: "
2081                //        + mProcessCpu.getTotalCpuPercent() + "%");
2082
2083                // Slog the cpu usage if the property is set.
2084                if ("true".equals(SystemProperties.get("events.cpu"))) {
2085                    int user = mProcessCpuTracker.getLastUserTime();
2086                    int system = mProcessCpuTracker.getLastSystemTime();
2087                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2088                    int irq = mProcessCpuTracker.getLastIrqTime();
2089                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2090                    int idle = mProcessCpuTracker.getLastIdleTime();
2091
2092                    int total = user + system + iowait + irq + softIrq + idle;
2093                    if (total == 0) total = 1;
2094
2095                    EventLog.writeEvent(EventLogTags.CPU,
2096                            ((user+system+iowait+irq+softIrq) * 100) / total,
2097                            (user * 100) / total,
2098                            (system * 100) / total,
2099                            (iowait * 100) / total,
2100                            (irq * 100) / total,
2101                            (softIrq * 100) / total);
2102                }
2103            }
2104
2105            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2106            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2107            synchronized(bstats) {
2108                synchronized(mPidsSelfLocked) {
2109                    if (haveNewCpuStats) {
2110                        if (mOnBattery) {
2111                            int perc = bstats.startAddingCpuLocked();
2112                            int totalUTime = 0;
2113                            int totalSTime = 0;
2114                            final int N = mProcessCpuTracker.countStats();
2115                            for (int i=0; i<N; i++) {
2116                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2117                                if (!st.working) {
2118                                    continue;
2119                                }
2120                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2121                                int otherUTime = (st.rel_utime*perc)/100;
2122                                int otherSTime = (st.rel_stime*perc)/100;
2123                                totalUTime += otherUTime;
2124                                totalSTime += otherSTime;
2125                                if (pr != null) {
2126                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
2127                                            st.name, st.pid);
2128                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2129                                            st.rel_stime-otherSTime);
2130                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2131                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2132                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
2133                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2134                                    if (ps == null) {
2135                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
2136                                                "(Unknown)");
2137                                    }
2138                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2139                                            st.rel_stime-otherSTime);
2140                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2141                                } else {
2142                                    BatteryStatsImpl.Uid.Proc ps =
2143                                            bstats.getProcessStatsLocked(st.name, st.pid);
2144                                    if (ps != null) {
2145                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2146                                                st.rel_stime-otherSTime);
2147                                        ps.addSpeedStepTimes(cpuSpeedTimes);
2148                                    }
2149                                }
2150                            }
2151                            bstats.finishAddingCpuLocked(perc, totalUTime,
2152                                    totalSTime, cpuSpeedTimes);
2153                        }
2154                    }
2155                }
2156
2157                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2158                    mLastWriteTime = now;
2159                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2160                }
2161            }
2162        }
2163    }
2164
2165    @Override
2166    public void batteryNeedsCpuUpdate() {
2167        updateCpuStatsNow();
2168    }
2169
2170    @Override
2171    public void batteryPowerChanged(boolean onBattery) {
2172        // When plugging in, update the CPU stats first before changing
2173        // the plug state.
2174        updateCpuStatsNow();
2175        synchronized (this) {
2176            synchronized(mPidsSelfLocked) {
2177                mOnBattery = DEBUG_POWER ? true : onBattery;
2178            }
2179        }
2180    }
2181
2182    /**
2183     * Initialize the application bind args. These are passed to each
2184     * process when the bindApplication() IPC is sent to the process. They're
2185     * lazily setup to make sure the services are running when they're asked for.
2186     */
2187    private HashMap<String, IBinder> getCommonServicesLocked() {
2188        if (mAppBindArgs == null) {
2189            mAppBindArgs = new HashMap<String, IBinder>();
2190
2191            // Setup the application init args
2192            mAppBindArgs.put("package", ServiceManager.getService("package"));
2193            mAppBindArgs.put("window", ServiceManager.getService("window"));
2194            mAppBindArgs.put(Context.ALARM_SERVICE,
2195                    ServiceManager.getService(Context.ALARM_SERVICE));
2196        }
2197        return mAppBindArgs;
2198    }
2199
2200    final void setFocusedActivityLocked(ActivityRecord r) {
2201        if (mFocusedActivity != r) {
2202            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2203            mFocusedActivity = r;
2204            mStackSupervisor.setFocusedStack(r);
2205            if (r != null) {
2206                mWindowManager.setFocusedApp(r.appToken, true);
2207            }
2208            applyUpdateLockStateLocked(r);
2209        }
2210    }
2211
2212    @Override
2213    public void setFocusedStack(int stackId) {
2214        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2215        synchronized (ActivityManagerService.this) {
2216            ActivityStack stack = mStackSupervisor.getStack(stackId);
2217            if (stack != null) {
2218                ActivityRecord r = stack.topRunningActivityLocked(null);
2219                if (r != null) {
2220                    setFocusedActivityLocked(r);
2221                }
2222            }
2223        }
2224    }
2225
2226    @Override
2227    public void notifyActivityDrawn(IBinder token) {
2228        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2229        synchronized (this) {
2230            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2231            if (r != null) {
2232                r.task.stack.notifyActivityDrawnLocked(r);
2233            }
2234        }
2235    }
2236
2237    final void applyUpdateLockStateLocked(ActivityRecord r) {
2238        // Modifications to the UpdateLock state are done on our handler, outside
2239        // the activity manager's locks.  The new state is determined based on the
2240        // state *now* of the relevant activity record.  The object is passed to
2241        // the handler solely for logging detail, not to be consulted/modified.
2242        final boolean nextState = r != null && r.immersive;
2243        mHandler.sendMessage(
2244                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2245    }
2246
2247    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2248        Message msg = Message.obtain();
2249        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2250        msg.obj = r.task.askedCompatMode ? null : r;
2251        mHandler.sendMessage(msg);
2252    }
2253
2254    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2255            String what, Object obj, ProcessRecord srcApp) {
2256        app.lastActivityTime = now;
2257
2258        if (app.activities.size() > 0) {
2259            // Don't want to touch dependent processes that are hosting activities.
2260            return index;
2261        }
2262
2263        int lrui = mLruProcesses.lastIndexOf(app);
2264        if (lrui < 0) {
2265            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2266                    + what + " " + obj + " from " + srcApp);
2267            return index;
2268        }
2269
2270        if (lrui >= index) {
2271            // Don't want to cause this to move dependent processes *back* in the
2272            // list as if they were less frequently used.
2273            return index;
2274        }
2275
2276        if (lrui >= mLruProcessActivityStart) {
2277            // Don't want to touch dependent processes that are hosting activities.
2278            return index;
2279        }
2280
2281        mLruProcesses.remove(lrui);
2282        if (index > 0) {
2283            index--;
2284        }
2285        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2286                + " in LRU list: " + app);
2287        mLruProcesses.add(index, app);
2288        return index;
2289    }
2290
2291    final void removeLruProcessLocked(ProcessRecord app) {
2292        int lrui = mLruProcesses.lastIndexOf(app);
2293        if (lrui >= 0) {
2294            if (lrui <= mLruProcessActivityStart) {
2295                mLruProcessActivityStart--;
2296            }
2297            if (lrui <= mLruProcessServiceStart) {
2298                mLruProcessServiceStart--;
2299            }
2300            mLruProcesses.remove(lrui);
2301        }
2302    }
2303
2304    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2305            ProcessRecord client) {
2306        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2307        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2308        if (!activityChange && hasActivity) {
2309            // The process has activties, so we are only going to allow activity-based
2310            // adjustments move it.  It should be kept in the front of the list with other
2311            // processes that have activities, and we don't want those to change their
2312            // order except due to activity operations.
2313            return;
2314        }
2315
2316        mLruSeq++;
2317        final long now = SystemClock.uptimeMillis();
2318        app.lastActivityTime = now;
2319
2320        // First a quick reject: if the app is already at the position we will
2321        // put it, then there is nothing to do.
2322        if (hasActivity) {
2323            final int N = mLruProcesses.size();
2324            if (N > 0 && mLruProcesses.get(N-1) == app) {
2325                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2326                return;
2327            }
2328        } else {
2329            if (mLruProcessServiceStart > 0
2330                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2331                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2332                return;
2333            }
2334        }
2335
2336        int lrui = mLruProcesses.lastIndexOf(app);
2337
2338        if (app.persistent && lrui >= 0) {
2339            // We don't care about the position of persistent processes, as long as
2340            // they are in the list.
2341            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2342            return;
2343        }
2344
2345        /* In progress: compute new position first, so we can avoid doing work
2346           if the process is not actually going to move.  Not yet working.
2347        int addIndex;
2348        int nextIndex;
2349        boolean inActivity = false, inService = false;
2350        if (hasActivity) {
2351            // Process has activities, put it at the very tipsy-top.
2352            addIndex = mLruProcesses.size();
2353            nextIndex = mLruProcessServiceStart;
2354            inActivity = true;
2355        } else if (hasService) {
2356            // Process has services, put it at the top of the service list.
2357            addIndex = mLruProcessActivityStart;
2358            nextIndex = mLruProcessServiceStart;
2359            inActivity = true;
2360            inService = true;
2361        } else  {
2362            // Process not otherwise of interest, it goes to the top of the non-service area.
2363            addIndex = mLruProcessServiceStart;
2364            if (client != null) {
2365                int clientIndex = mLruProcesses.lastIndexOf(client);
2366                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2367                        + app);
2368                if (clientIndex >= 0 && addIndex > clientIndex) {
2369                    addIndex = clientIndex;
2370                }
2371            }
2372            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2373        }
2374
2375        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2376                + mLruProcessActivityStart + "): " + app);
2377        */
2378
2379        if (lrui >= 0) {
2380            if (lrui < mLruProcessActivityStart) {
2381                mLruProcessActivityStart--;
2382            }
2383            if (lrui < mLruProcessServiceStart) {
2384                mLruProcessServiceStart--;
2385            }
2386            /*
2387            if (addIndex > lrui) {
2388                addIndex--;
2389            }
2390            if (nextIndex > lrui) {
2391                nextIndex--;
2392            }
2393            */
2394            mLruProcesses.remove(lrui);
2395        }
2396
2397        /*
2398        mLruProcesses.add(addIndex, app);
2399        if (inActivity) {
2400            mLruProcessActivityStart++;
2401        }
2402        if (inService) {
2403            mLruProcessActivityStart++;
2404        }
2405        */
2406
2407        int nextIndex;
2408        if (hasActivity) {
2409            final int N = mLruProcesses.size();
2410            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2411                // Process doesn't have activities, but has clients with
2412                // activities...  move it up, but one below the top (the top
2413                // should always have a real activity).
2414                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2415                mLruProcesses.add(N-1, app);
2416                // To keep it from spamming the LRU list (by making a bunch of clients),
2417                // we will push down any other entries owned by the app.
2418                final int uid = app.info.uid;
2419                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2420                    ProcessRecord subProc = mLruProcesses.get(i);
2421                    if (subProc.info.uid == uid) {
2422                        // We want to push this one down the list.  If the process after
2423                        // it is for the same uid, however, don't do so, because we don't
2424                        // want them internally to be re-ordered.
2425                        if (mLruProcesses.get(i-1).info.uid != uid) {
2426                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2427                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2428                            ProcessRecord tmp = mLruProcesses.get(i);
2429                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2430                            mLruProcesses.set(i-1, tmp);
2431                            i--;
2432                        }
2433                    } else {
2434                        // A gap, we can stop here.
2435                        break;
2436                    }
2437                }
2438            } else {
2439                // Process has activities, put it at the very tipsy-top.
2440                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2441                mLruProcesses.add(app);
2442            }
2443            nextIndex = mLruProcessServiceStart;
2444        } else if (hasService) {
2445            // Process has services, put it at the top of the service list.
2446            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2447            mLruProcesses.add(mLruProcessActivityStart, app);
2448            nextIndex = mLruProcessServiceStart;
2449            mLruProcessActivityStart++;
2450        } else  {
2451            // Process not otherwise of interest, it goes to the top of the non-service area.
2452            int index = mLruProcessServiceStart;
2453            if (client != null) {
2454                // If there is a client, don't allow the process to be moved up higher
2455                // in the list than that client.
2456                int clientIndex = mLruProcesses.lastIndexOf(client);
2457                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2458                        + " when updating " + app);
2459                if (clientIndex <= lrui) {
2460                    // Don't allow the client index restriction to push it down farther in the
2461                    // list than it already is.
2462                    clientIndex = lrui;
2463                }
2464                if (clientIndex >= 0 && index > clientIndex) {
2465                    index = clientIndex;
2466                }
2467            }
2468            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2469            mLruProcesses.add(index, app);
2470            nextIndex = index-1;
2471            mLruProcessActivityStart++;
2472            mLruProcessServiceStart++;
2473        }
2474
2475        // If the app is currently using a content provider or service,
2476        // bump those processes as well.
2477        for (int j=app.connections.size()-1; j>=0; j--) {
2478            ConnectionRecord cr = app.connections.valueAt(j);
2479            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2480                    && cr.binding.service.app != null
2481                    && cr.binding.service.app.lruSeq != mLruSeq
2482                    && !cr.binding.service.app.persistent) {
2483                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2484                        "service connection", cr, app);
2485            }
2486        }
2487        for (int j=app.conProviders.size()-1; j>=0; j--) {
2488            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2489            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2490                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2491                        "provider reference", cpr, app);
2492            }
2493        }
2494    }
2495
2496    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2497        if (uid == Process.SYSTEM_UID) {
2498            // The system gets to run in any process.  If there are multiple
2499            // processes with the same uid, just pick the first (this
2500            // should never happen).
2501            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2502            if (procs == null) return null;
2503            final int N = procs.size();
2504            for (int i = 0; i < N; i++) {
2505                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2506            }
2507        }
2508        ProcessRecord proc = mProcessNames.get(processName, uid);
2509        if (false && proc != null && !keepIfLarge
2510                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2511                && proc.lastCachedPss >= 4000) {
2512            // Turn this condition on to cause killing to happen regularly, for testing.
2513            if (proc.baseProcessTracker != null) {
2514                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2515            }
2516            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2517                    + "k from cached");
2518        } else if (proc != null && !keepIfLarge
2519                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2520                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2521            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2522            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2523                if (proc.baseProcessTracker != null) {
2524                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2525                }
2526                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2527                        + "k from cached");
2528            }
2529        }
2530        return proc;
2531    }
2532
2533    void ensurePackageDexOpt(String packageName) {
2534        IPackageManager pm = AppGlobals.getPackageManager();
2535        try {
2536            if (pm.performDexOpt(packageName)) {
2537                mDidDexOpt = true;
2538            }
2539        } catch (RemoteException e) {
2540        }
2541    }
2542
2543    boolean isNextTransitionForward() {
2544        int transit = mWindowManager.getPendingAppTransition();
2545        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2546                || transit == AppTransition.TRANSIT_TASK_OPEN
2547                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2548    }
2549
2550    final ProcessRecord startProcessLocked(String processName,
2551            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2552            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2553            boolean isolated, boolean keepIfLarge) {
2554        ProcessRecord app;
2555        if (!isolated) {
2556            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2557        } else {
2558            // If this is an isolated process, it can't re-use an existing process.
2559            app = null;
2560        }
2561        // We don't have to do anything more if:
2562        // (1) There is an existing application record; and
2563        // (2) The caller doesn't think it is dead, OR there is no thread
2564        //     object attached to it so we know it couldn't have crashed; and
2565        // (3) There is a pid assigned to it, so it is either starting or
2566        //     already running.
2567        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2568                + " app=" + app + " knownToBeDead=" + knownToBeDead
2569                + " thread=" + (app != null ? app.thread : null)
2570                + " pid=" + (app != null ? app.pid : -1));
2571        if (app != null && app.pid > 0) {
2572            if (!knownToBeDead || app.thread == null) {
2573                // We already have the app running, or are waiting for it to
2574                // come up (we have a pid but not yet its thread), so keep it.
2575                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2576                // If this is a new package in the process, add the package to the list
2577                app.addPackage(info.packageName, mProcessStats);
2578                return app;
2579            }
2580
2581            // An application record is attached to a previous process,
2582            // clean it up now.
2583            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2584            handleAppDiedLocked(app, true, true);
2585        }
2586
2587        String hostingNameStr = hostingName != null
2588                ? hostingName.flattenToShortString() : null;
2589
2590        if (!isolated) {
2591            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2592                // If we are in the background, then check to see if this process
2593                // is bad.  If so, we will just silently fail.
2594                if (mBadProcesses.get(info.processName, info.uid) != null) {
2595                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2596                            + "/" + info.processName);
2597                    return null;
2598                }
2599            } else {
2600                // When the user is explicitly starting a process, then clear its
2601                // crash count so that we won't make it bad until they see at
2602                // least one crash dialog again, and make the process good again
2603                // if it had been bad.
2604                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2605                        + "/" + info.processName);
2606                mProcessCrashTimes.remove(info.processName, info.uid);
2607                if (mBadProcesses.get(info.processName, info.uid) != null) {
2608                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2609                            UserHandle.getUserId(info.uid), info.uid,
2610                            info.processName);
2611                    mBadProcesses.remove(info.processName, info.uid);
2612                    if (app != null) {
2613                        app.bad = false;
2614                    }
2615                }
2616            }
2617        }
2618
2619        if (app == null) {
2620            app = newProcessRecordLocked(info, processName, isolated);
2621            if (app == null) {
2622                Slog.w(TAG, "Failed making new process record for "
2623                        + processName + "/" + info.uid + " isolated=" + isolated);
2624                return null;
2625            }
2626            mProcessNames.put(processName, app.uid, app);
2627            if (isolated) {
2628                mIsolatedProcesses.put(app.uid, app);
2629            }
2630        } else {
2631            // If this is a new package in the process, add the package to the list
2632            app.addPackage(info.packageName, mProcessStats);
2633        }
2634
2635        // If the system is not ready yet, then hold off on starting this
2636        // process until it is.
2637        if (!mProcessesReady
2638                && !isAllowedWhileBooting(info)
2639                && !allowWhileBooting) {
2640            if (!mProcessesOnHold.contains(app)) {
2641                mProcessesOnHold.add(app);
2642            }
2643            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2644            return app;
2645        }
2646
2647        startProcessLocked(app, hostingType, hostingNameStr);
2648        return (app.pid != 0) ? app : null;
2649    }
2650
2651    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2652        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2653    }
2654
2655    private final void startProcessLocked(ProcessRecord app,
2656            String hostingType, String hostingNameStr) {
2657        if (app.pid > 0 && app.pid != MY_PID) {
2658            synchronized (mPidsSelfLocked) {
2659                mPidsSelfLocked.remove(app.pid);
2660                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2661            }
2662            app.setPid(0);
2663        }
2664
2665        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2666                "startProcessLocked removing on hold: " + app);
2667        mProcessesOnHold.remove(app);
2668
2669        updateCpuStats();
2670
2671        try {
2672            int uid = app.uid;
2673
2674            int[] gids = null;
2675            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2676            if (!app.isolated) {
2677                int[] permGids = null;
2678                try {
2679                    final PackageManager pm = mContext.getPackageManager();
2680                    permGids = pm.getPackageGids(app.info.packageName);
2681
2682                    if (Environment.isExternalStorageEmulated()) {
2683                        if (pm.checkPermission(
2684                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2685                                app.info.packageName) == PERMISSION_GRANTED) {
2686                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2687                        } else {
2688                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2689                        }
2690                    }
2691                } catch (PackageManager.NameNotFoundException e) {
2692                    Slog.w(TAG, "Unable to retrieve gids", e);
2693                }
2694
2695                /*
2696                 * Add shared application GID so applications can share some
2697                 * resources like shared libraries
2698                 */
2699                if (permGids == null) {
2700                    gids = new int[1];
2701                } else {
2702                    gids = new int[permGids.length + 1];
2703                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2704                }
2705                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2706            }
2707            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2708                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2709                        && mTopComponent != null
2710                        && app.processName.equals(mTopComponent.getPackageName())) {
2711                    uid = 0;
2712                }
2713                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2714                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2715                    uid = 0;
2716                }
2717            }
2718            int debugFlags = 0;
2719            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2720                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2721                // Also turn on CheckJNI for debuggable apps. It's quite
2722                // awkward to turn on otherwise.
2723                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2724            }
2725            // Run the app in safe mode if its manifest requests so or the
2726            // system is booted in safe mode.
2727            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2728                mSafeMode == true) {
2729                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2730            }
2731            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2732                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2733            }
2734            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2735                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2736            }
2737            if ("1".equals(SystemProperties.get("debug.assert"))) {
2738                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2739            }
2740
2741            String requiredAbi = app.info.requiredCpuAbi;
2742            if (requiredAbi == null) {
2743                requiredAbi = Build.SUPPORTED_ABIS[0];
2744            }
2745
2746            // Start the process.  It will either succeed and return a result containing
2747            // the PID of the new process, or else throw a RuntimeException.
2748            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2749                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2750                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2751
2752            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2753            synchronized (bs) {
2754                if (bs.isOnBattery()) {
2755                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2756                }
2757            }
2758
2759            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2760                    UserHandle.getUserId(uid), startResult.pid, uid,
2761                    app.processName, hostingType,
2762                    hostingNameStr != null ? hostingNameStr : "");
2763
2764            if (app.persistent) {
2765                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2766            }
2767
2768            StringBuilder buf = mStringBuilder;
2769            buf.setLength(0);
2770            buf.append("Start proc ");
2771            buf.append(app.processName);
2772            buf.append(" for ");
2773            buf.append(hostingType);
2774            if (hostingNameStr != null) {
2775                buf.append(" ");
2776                buf.append(hostingNameStr);
2777            }
2778            buf.append(": pid=");
2779            buf.append(startResult.pid);
2780            buf.append(" uid=");
2781            buf.append(uid);
2782            buf.append(" gids={");
2783            if (gids != null) {
2784                for (int gi=0; gi<gids.length; gi++) {
2785                    if (gi != 0) buf.append(", ");
2786                    buf.append(gids[gi]);
2787
2788                }
2789            }
2790            buf.append("}");
2791            Slog.i(TAG, buf.toString());
2792            app.setPid(startResult.pid);
2793            app.usingWrapper = startResult.usingWrapper;
2794            app.removed = false;
2795            synchronized (mPidsSelfLocked) {
2796                this.mPidsSelfLocked.put(startResult.pid, app);
2797                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2798                msg.obj = app;
2799                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2800                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2801            }
2802        } catch (RuntimeException e) {
2803            // XXX do better error recovery.
2804            app.setPid(0);
2805            Slog.e(TAG, "Failure starting process " + app.processName, e);
2806        }
2807    }
2808
2809    void updateUsageStats(ActivityRecord component, boolean resumed) {
2810        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2811        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2812        if (resumed) {
2813            mUsageStatsService.noteResumeComponent(component.realActivity);
2814            synchronized (stats) {
2815                stats.noteActivityResumedLocked(component.app.uid);
2816            }
2817        } else {
2818            mUsageStatsService.notePauseComponent(component.realActivity);
2819            synchronized (stats) {
2820                stats.noteActivityPausedLocked(component.app.uid);
2821            }
2822        }
2823    }
2824
2825    Intent getHomeIntent() {
2826        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2827        intent.setComponent(mTopComponent);
2828        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2829            intent.addCategory(Intent.CATEGORY_HOME);
2830        }
2831        return intent;
2832    }
2833
2834    boolean startHomeActivityLocked(int userId) {
2835        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2836                && mTopAction == null) {
2837            // We are running in factory test mode, but unable to find
2838            // the factory test app, so just sit around displaying the
2839            // error message and don't try to start anything.
2840            return false;
2841        }
2842        Intent intent = getHomeIntent();
2843        ActivityInfo aInfo =
2844            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2845        if (aInfo != null) {
2846            intent.setComponent(new ComponentName(
2847                    aInfo.applicationInfo.packageName, aInfo.name));
2848            // Don't do this if the home app is currently being
2849            // instrumented.
2850            aInfo = new ActivityInfo(aInfo);
2851            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2852            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2853                    aInfo.applicationInfo.uid, true);
2854            if (app == null || app.instrumentationClass == null) {
2855                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2856                mStackSupervisor.startHomeActivity(intent, aInfo);
2857            }
2858        }
2859
2860        return true;
2861    }
2862
2863    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2864        ActivityInfo ai = null;
2865        ComponentName comp = intent.getComponent();
2866        try {
2867            if (comp != null) {
2868                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2869            } else {
2870                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2871                        intent,
2872                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2873                            flags, userId);
2874
2875                if (info != null) {
2876                    ai = info.activityInfo;
2877                }
2878            }
2879        } catch (RemoteException e) {
2880            // ignore
2881        }
2882
2883        return ai;
2884    }
2885
2886    /**
2887     * Starts the "new version setup screen" if appropriate.
2888     */
2889    void startSetupActivityLocked() {
2890        // Only do this once per boot.
2891        if (mCheckedForSetup) {
2892            return;
2893        }
2894
2895        // We will show this screen if the current one is a different
2896        // version than the last one shown, and we are not running in
2897        // low-level factory test mode.
2898        final ContentResolver resolver = mContext.getContentResolver();
2899        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2900                Settings.Global.getInt(resolver,
2901                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2902            mCheckedForSetup = true;
2903
2904            // See if we should be showing the platform update setup UI.
2905            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2906            List<ResolveInfo> ris = mContext.getPackageManager()
2907                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2908
2909            // We don't allow third party apps to replace this.
2910            ResolveInfo ri = null;
2911            for (int i=0; ris != null && i<ris.size(); i++) {
2912                if ((ris.get(i).activityInfo.applicationInfo.flags
2913                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2914                    ri = ris.get(i);
2915                    break;
2916                }
2917            }
2918
2919            if (ri != null) {
2920                String vers = ri.activityInfo.metaData != null
2921                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2922                        : null;
2923                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2924                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2925                            Intent.METADATA_SETUP_VERSION);
2926                }
2927                String lastVers = Settings.Secure.getString(
2928                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2929                if (vers != null && !vers.equals(lastVers)) {
2930                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2931                    intent.setComponent(new ComponentName(
2932                            ri.activityInfo.packageName, ri.activityInfo.name));
2933                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2934                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2935                }
2936            }
2937        }
2938    }
2939
2940    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2941        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2942    }
2943
2944    void enforceNotIsolatedCaller(String caller) {
2945        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2946            throw new SecurityException("Isolated process not allowed to call " + caller);
2947        }
2948    }
2949
2950    @Override
2951    public int getFrontActivityScreenCompatMode() {
2952        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2953        synchronized (this) {
2954            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2955        }
2956    }
2957
2958    @Override
2959    public void setFrontActivityScreenCompatMode(int mode) {
2960        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2961                "setFrontActivityScreenCompatMode");
2962        synchronized (this) {
2963            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2964        }
2965    }
2966
2967    @Override
2968    public int getPackageScreenCompatMode(String packageName) {
2969        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2970        synchronized (this) {
2971            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2972        }
2973    }
2974
2975    @Override
2976    public void setPackageScreenCompatMode(String packageName, int mode) {
2977        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2978                "setPackageScreenCompatMode");
2979        synchronized (this) {
2980            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2981        }
2982    }
2983
2984    @Override
2985    public boolean getPackageAskScreenCompat(String packageName) {
2986        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2987        synchronized (this) {
2988            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2989        }
2990    }
2991
2992    @Override
2993    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2994        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2995                "setPackageAskScreenCompat");
2996        synchronized (this) {
2997            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2998        }
2999    }
3000
3001    private void dispatchProcessesChanged() {
3002        int N;
3003        synchronized (this) {
3004            N = mPendingProcessChanges.size();
3005            if (mActiveProcessChanges.length < N) {
3006                mActiveProcessChanges = new ProcessChangeItem[N];
3007            }
3008            mPendingProcessChanges.toArray(mActiveProcessChanges);
3009            mAvailProcessChanges.addAll(mPendingProcessChanges);
3010            mPendingProcessChanges.clear();
3011            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3012        }
3013
3014        int i = mProcessObservers.beginBroadcast();
3015        while (i > 0) {
3016            i--;
3017            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3018            if (observer != null) {
3019                try {
3020                    for (int j=0; j<N; j++) {
3021                        ProcessChangeItem item = mActiveProcessChanges[j];
3022                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3023                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3024                                    + item.pid + " uid=" + item.uid + ": "
3025                                    + item.foregroundActivities);
3026                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3027                                    item.foregroundActivities);
3028                        }
3029                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3030                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3031                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3032                            observer.onImportanceChanged(item.pid, item.uid,
3033                                    item.importance);
3034                        }
3035                    }
3036                } catch (RemoteException e) {
3037                }
3038            }
3039        }
3040        mProcessObservers.finishBroadcast();
3041    }
3042
3043    private void dispatchProcessDied(int pid, int uid) {
3044        int i = mProcessObservers.beginBroadcast();
3045        while (i > 0) {
3046            i--;
3047            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3048            if (observer != null) {
3049                try {
3050                    observer.onProcessDied(pid, uid);
3051                } catch (RemoteException e) {
3052                }
3053            }
3054        }
3055        mProcessObservers.finishBroadcast();
3056    }
3057
3058    final void doPendingActivityLaunchesLocked(boolean doResume) {
3059        final int N = mPendingActivityLaunches.size();
3060        if (N <= 0) {
3061            return;
3062        }
3063        for (int i=0; i<N; i++) {
3064            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3065            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3066                    doResume && i == (N-1), null);
3067        }
3068        mPendingActivityLaunches.clear();
3069    }
3070
3071    @Override
3072    public final int startActivity(IApplicationThread caller, String callingPackage,
3073            Intent intent, String resolvedType, IBinder resultTo,
3074            String resultWho, int requestCode, int startFlags,
3075            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3076        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3077                resultWho, requestCode,
3078                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3079    }
3080
3081    @Override
3082    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3083            Intent intent, String resolvedType, IBinder resultTo,
3084            String resultWho, int requestCode, int startFlags,
3085            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3086        enforceNotIsolatedCaller("startActivity");
3087        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3088                false, true, "startActivity", null);
3089        // TODO: Switch to user app stacks here.
3090        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3091                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3092                null, null, options, userId, null);
3093    }
3094
3095    @Override
3096    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3097            Intent intent, String resolvedType, IBinder resultTo,
3098            String resultWho, int requestCode, int startFlags, String profileFile,
3099            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3100        enforceNotIsolatedCaller("startActivityAndWait");
3101        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3102                false, true, "startActivityAndWait", null);
3103        WaitResult res = new WaitResult();
3104        // TODO: Switch to user app stacks here.
3105        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3106                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3107                res, null, options, UserHandle.getCallingUserId(), null);
3108        return res;
3109    }
3110
3111    @Override
3112    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3113            Intent intent, String resolvedType, IBinder resultTo,
3114            String resultWho, int requestCode, int startFlags, Configuration config,
3115            Bundle options, int userId) {
3116        enforceNotIsolatedCaller("startActivityWithConfig");
3117        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3118                false, true, "startActivityWithConfig", null);
3119        // TODO: Switch to user app stacks here.
3120        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3121                resolvedType, resultTo, resultWho, requestCode, startFlags,
3122                null, null, null, config, options, userId, null);
3123        return ret;
3124    }
3125
3126    @Override
3127    public int startActivityIntentSender(IApplicationThread caller,
3128            IntentSender intent, Intent fillInIntent, String resolvedType,
3129            IBinder resultTo, String resultWho, int requestCode,
3130            int flagsMask, int flagsValues, Bundle options) {
3131        enforceNotIsolatedCaller("startActivityIntentSender");
3132        // Refuse possible leaked file descriptors
3133        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3134            throw new IllegalArgumentException("File descriptors passed in Intent");
3135        }
3136
3137        IIntentSender sender = intent.getTarget();
3138        if (!(sender instanceof PendingIntentRecord)) {
3139            throw new IllegalArgumentException("Bad PendingIntent object");
3140        }
3141
3142        PendingIntentRecord pir = (PendingIntentRecord)sender;
3143
3144        synchronized (this) {
3145            // If this is coming from the currently resumed activity, it is
3146            // effectively saying that app switches are allowed at this point.
3147            final ActivityStack stack = getFocusedStack();
3148            if (stack.mResumedActivity != null &&
3149                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3150                mAppSwitchesAllowedTime = 0;
3151            }
3152        }
3153        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3154                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3155        return ret;
3156    }
3157
3158    @Override
3159    public boolean startNextMatchingActivity(IBinder callingActivity,
3160            Intent intent, Bundle options) {
3161        // Refuse possible leaked file descriptors
3162        if (intent != null && intent.hasFileDescriptors() == true) {
3163            throw new IllegalArgumentException("File descriptors passed in Intent");
3164        }
3165
3166        synchronized (this) {
3167            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3168            if (r == null) {
3169                ActivityOptions.abort(options);
3170                return false;
3171            }
3172            if (r.app == null || r.app.thread == null) {
3173                // The caller is not running...  d'oh!
3174                ActivityOptions.abort(options);
3175                return false;
3176            }
3177            intent = new Intent(intent);
3178            // The caller is not allowed to change the data.
3179            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3180            // And we are resetting to find the next component...
3181            intent.setComponent(null);
3182
3183            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3184
3185            ActivityInfo aInfo = null;
3186            try {
3187                List<ResolveInfo> resolves =
3188                    AppGlobals.getPackageManager().queryIntentActivities(
3189                            intent, r.resolvedType,
3190                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3191                            UserHandle.getCallingUserId());
3192
3193                // Look for the original activity in the list...
3194                final int N = resolves != null ? resolves.size() : 0;
3195                for (int i=0; i<N; i++) {
3196                    ResolveInfo rInfo = resolves.get(i);
3197                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3198                            && rInfo.activityInfo.name.equals(r.info.name)) {
3199                        // We found the current one...  the next matching is
3200                        // after it.
3201                        i++;
3202                        if (i<N) {
3203                            aInfo = resolves.get(i).activityInfo;
3204                        }
3205                        if (debug) {
3206                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3207                                    + "/" + r.info.name);
3208                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3209                                    + "/" + aInfo.name);
3210                        }
3211                        break;
3212                    }
3213                }
3214            } catch (RemoteException e) {
3215            }
3216
3217            if (aInfo == null) {
3218                // Nobody who is next!
3219                ActivityOptions.abort(options);
3220                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3221                return false;
3222            }
3223
3224            intent.setComponent(new ComponentName(
3225                    aInfo.applicationInfo.packageName, aInfo.name));
3226            intent.setFlags(intent.getFlags()&~(
3227                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3228                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3229                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3230                    Intent.FLAG_ACTIVITY_NEW_TASK));
3231
3232            // Okay now we need to start the new activity, replacing the
3233            // currently running activity.  This is a little tricky because
3234            // we want to start the new one as if the current one is finished,
3235            // but not finish the current one first so that there is no flicker.
3236            // And thus...
3237            final boolean wasFinishing = r.finishing;
3238            r.finishing = true;
3239
3240            // Propagate reply information over to the new activity.
3241            final ActivityRecord resultTo = r.resultTo;
3242            final String resultWho = r.resultWho;
3243            final int requestCode = r.requestCode;
3244            r.resultTo = null;
3245            if (resultTo != null) {
3246                resultTo.removeResultsLocked(r, resultWho, requestCode);
3247            }
3248
3249            final long origId = Binder.clearCallingIdentity();
3250            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3251                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3252                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3253                    options, false, null, null);
3254            Binder.restoreCallingIdentity(origId);
3255
3256            r.finishing = wasFinishing;
3257            if (res != ActivityManager.START_SUCCESS) {
3258                return false;
3259            }
3260            return true;
3261        }
3262    }
3263
3264    final int startActivityInPackage(int uid, String callingPackage,
3265            Intent intent, String resolvedType, IBinder resultTo,
3266            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3267                    IActivityContainer container) {
3268
3269        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3270                false, true, "startActivityInPackage", null);
3271
3272        // TODO: Switch to user app stacks here.
3273        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3274                resultTo, resultWho, requestCode, startFlags,
3275                null, null, null, null, options, userId, container);
3276        return ret;
3277    }
3278
3279    @Override
3280    public final int startActivities(IApplicationThread caller, String callingPackage,
3281            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3282            int userId) {
3283        enforceNotIsolatedCaller("startActivities");
3284        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3285                false, true, "startActivity", null);
3286        // TODO: Switch to user app stacks here.
3287        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3288                resolvedTypes, resultTo, options, userId);
3289        return ret;
3290    }
3291
3292    final int startActivitiesInPackage(int uid, String callingPackage,
3293            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3294            Bundle options, int userId) {
3295
3296        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3297                false, true, "startActivityInPackage", null);
3298        // TODO: Switch to user app stacks here.
3299        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3300                resultTo, options, userId);
3301        return ret;
3302    }
3303
3304    final void addRecentTaskLocked(TaskRecord task) {
3305        int N = mRecentTasks.size();
3306        // Quick case: check if the top-most recent task is the same.
3307        if (N > 0 && mRecentTasks.get(0) == task) {
3308            return;
3309        }
3310        // Remove any existing entries that are the same kind of task.
3311        for (int i=0; i<N; i++) {
3312            TaskRecord tr = mRecentTasks.get(i);
3313            if (task.userId == tr.userId
3314                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3315                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3316                tr.disposeThumbnail();
3317                mRecentTasks.remove(i);
3318                i--;
3319                N--;
3320                if (task.intent == null) {
3321                    // If the new recent task we are adding is not fully
3322                    // specified, then replace it with the existing recent task.
3323                    task = tr;
3324                }
3325            }
3326        }
3327        if (N >= MAX_RECENT_TASKS) {
3328            mRecentTasks.remove(N-1).disposeThumbnail();
3329        }
3330        mRecentTasks.add(0, task);
3331    }
3332
3333    @Override
3334    public void reportActivityFullyDrawn(IBinder token) {
3335        synchronized (this) {
3336            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3337            if (r == null) {
3338                return;
3339            }
3340            r.reportFullyDrawnLocked();
3341        }
3342    }
3343
3344    @Override
3345    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3346        synchronized (this) {
3347            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3348            if (r == null) {
3349                return;
3350            }
3351            final long origId = Binder.clearCallingIdentity();
3352            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3353            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3354                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3355            if (config != null) {
3356                r.frozenBeforeDestroy = true;
3357                if (!updateConfigurationLocked(config, r, false, false)) {
3358                    mStackSupervisor.resumeTopActivitiesLocked();
3359                }
3360            }
3361            Binder.restoreCallingIdentity(origId);
3362        }
3363    }
3364
3365    @Override
3366    public int getRequestedOrientation(IBinder token) {
3367        synchronized (this) {
3368            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3369            if (r == null) {
3370                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3371            }
3372            return mWindowManager.getAppOrientation(r.appToken);
3373        }
3374    }
3375
3376    /**
3377     * This is the internal entry point for handling Activity.finish().
3378     *
3379     * @param token The Binder token referencing the Activity we want to finish.
3380     * @param resultCode Result code, if any, from this Activity.
3381     * @param resultData Result data (Intent), if any, from this Activity.
3382     *
3383     * @return Returns true if the activity successfully finished, or false if it is still running.
3384     */
3385    @Override
3386    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3387        // Refuse possible leaked file descriptors
3388        if (resultData != null && resultData.hasFileDescriptors() == true) {
3389            throw new IllegalArgumentException("File descriptors passed in Intent");
3390        }
3391
3392        synchronized(this) {
3393            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3394            if (r == null) {
3395                return true;
3396            }
3397            if (mController != null) {
3398                // Find the first activity that is not finishing.
3399                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3400                if (next != null) {
3401                    // ask watcher if this is allowed
3402                    boolean resumeOK = true;
3403                    try {
3404                        resumeOK = mController.activityResuming(next.packageName);
3405                    } catch (RemoteException e) {
3406                        mController = null;
3407                        Watchdog.getInstance().setActivityController(null);
3408                    }
3409
3410                    if (!resumeOK) {
3411                        return false;
3412                    }
3413                }
3414            }
3415            final long origId = Binder.clearCallingIdentity();
3416            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3417                    resultData, "app-request", true);
3418            Binder.restoreCallingIdentity(origId);
3419            return res;
3420        }
3421    }
3422
3423    @Override
3424    public final void finishHeavyWeightApp() {
3425        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3426                != PackageManager.PERMISSION_GRANTED) {
3427            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3428                    + Binder.getCallingPid()
3429                    + ", uid=" + Binder.getCallingUid()
3430                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3431            Slog.w(TAG, msg);
3432            throw new SecurityException(msg);
3433        }
3434
3435        synchronized(this) {
3436            if (mHeavyWeightProcess == null) {
3437                return;
3438            }
3439
3440            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3441                    mHeavyWeightProcess.activities);
3442            for (int i=0; i<activities.size(); i++) {
3443                ActivityRecord r = activities.get(i);
3444                if (!r.finishing) {
3445                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3446                            null, "finish-heavy", true);
3447                }
3448            }
3449
3450            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3451                    mHeavyWeightProcess.userId, 0));
3452            mHeavyWeightProcess = null;
3453        }
3454    }
3455
3456    @Override
3457    public void crashApplication(int uid, int initialPid, String packageName,
3458            String message) {
3459        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3460                != PackageManager.PERMISSION_GRANTED) {
3461            String msg = "Permission Denial: crashApplication() from pid="
3462                    + Binder.getCallingPid()
3463                    + ", uid=" + Binder.getCallingUid()
3464                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3465            Slog.w(TAG, msg);
3466            throw new SecurityException(msg);
3467        }
3468
3469        synchronized(this) {
3470            ProcessRecord proc = null;
3471
3472            // Figure out which process to kill.  We don't trust that initialPid
3473            // still has any relation to current pids, so must scan through the
3474            // list.
3475            synchronized (mPidsSelfLocked) {
3476                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3477                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3478                    if (p.uid != uid) {
3479                        continue;
3480                    }
3481                    if (p.pid == initialPid) {
3482                        proc = p;
3483                        break;
3484                    }
3485                    if (p.pkgList.containsKey(packageName)) {
3486                        proc = p;
3487                    }
3488                }
3489            }
3490
3491            if (proc == null) {
3492                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3493                        + " initialPid=" + initialPid
3494                        + " packageName=" + packageName);
3495                return;
3496            }
3497
3498            if (proc.thread != null) {
3499                if (proc.pid == Process.myPid()) {
3500                    Log.w(TAG, "crashApplication: trying to crash self!");
3501                    return;
3502                }
3503                long ident = Binder.clearCallingIdentity();
3504                try {
3505                    proc.thread.scheduleCrash(message);
3506                } catch (RemoteException e) {
3507                }
3508                Binder.restoreCallingIdentity(ident);
3509            }
3510        }
3511    }
3512
3513    @Override
3514    public final void finishSubActivity(IBinder token, String resultWho,
3515            int requestCode) {
3516        synchronized(this) {
3517            final long origId = Binder.clearCallingIdentity();
3518            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3519            if (r != null) {
3520                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3521            }
3522            Binder.restoreCallingIdentity(origId);
3523        }
3524    }
3525
3526    @Override
3527    public boolean finishActivityAffinity(IBinder token) {
3528        synchronized(this) {
3529            final long origId = Binder.clearCallingIdentity();
3530            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3531            boolean res = false;
3532            if (r != null) {
3533                res = r.task.stack.finishActivityAffinityLocked(r);
3534            }
3535            Binder.restoreCallingIdentity(origId);
3536            return res;
3537        }
3538    }
3539
3540    @Override
3541    public boolean willActivityBeVisible(IBinder token) {
3542        synchronized(this) {
3543            ActivityStack stack = ActivityRecord.getStackLocked(token);
3544            if (stack != null) {
3545                return stack.willActivityBeVisibleLocked(token);
3546            }
3547            return false;
3548        }
3549    }
3550
3551    @Override
3552    public void overridePendingTransition(IBinder token, String packageName,
3553            int enterAnim, int exitAnim) {
3554        synchronized(this) {
3555            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3556            if (self == null) {
3557                return;
3558            }
3559
3560            final long origId = Binder.clearCallingIdentity();
3561
3562            if (self.state == ActivityState.RESUMED
3563                    || self.state == ActivityState.PAUSING) {
3564                mWindowManager.overridePendingAppTransition(packageName,
3565                        enterAnim, exitAnim, null);
3566            }
3567
3568            Binder.restoreCallingIdentity(origId);
3569        }
3570    }
3571
3572    /**
3573     * Main function for removing an existing process from the activity manager
3574     * as a result of that process going away.  Clears out all connections
3575     * to the process.
3576     */
3577    private final void handleAppDiedLocked(ProcessRecord app,
3578            boolean restarting, boolean allowRestart) {
3579        int pid = app.pid;
3580        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3581        if (!restarting) {
3582            removeLruProcessLocked(app);
3583            if (pid > 0) {
3584                ProcessList.remove(pid);
3585            }
3586        }
3587
3588        if (mProfileProc == app) {
3589            clearProfilerLocked();
3590        }
3591
3592        // Remove this application's activities from active lists.
3593        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3594
3595        app.activities.clear();
3596
3597        if (app.instrumentationClass != null) {
3598            Slog.w(TAG, "Crash of app " + app.processName
3599                  + " running instrumentation " + app.instrumentationClass);
3600            Bundle info = new Bundle();
3601            info.putString("shortMsg", "Process crashed.");
3602            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3603        }
3604
3605        if (!restarting) {
3606            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3607                // If there was nothing to resume, and we are not already
3608                // restarting this process, but there is a visible activity that
3609                // is hosted by the process...  then make sure all visible
3610                // activities are running, taking care of restarting this
3611                // process.
3612                if (hasVisibleActivities) {
3613                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3614                }
3615            }
3616        }
3617    }
3618
3619    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3620        IBinder threadBinder = thread.asBinder();
3621        // Find the application record.
3622        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3623            ProcessRecord rec = mLruProcesses.get(i);
3624            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3625                return i;
3626            }
3627        }
3628        return -1;
3629    }
3630
3631    final ProcessRecord getRecordForAppLocked(
3632            IApplicationThread thread) {
3633        if (thread == null) {
3634            return null;
3635        }
3636
3637        int appIndex = getLRURecordIndexForAppLocked(thread);
3638        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3639    }
3640
3641    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3642        // If there are no longer any background processes running,
3643        // and the app that died was not running instrumentation,
3644        // then tell everyone we are now low on memory.
3645        boolean haveBg = false;
3646        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3647            ProcessRecord rec = mLruProcesses.get(i);
3648            if (rec.thread != null
3649                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3650                haveBg = true;
3651                break;
3652            }
3653        }
3654
3655        if (!haveBg) {
3656            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3657            if (doReport) {
3658                long now = SystemClock.uptimeMillis();
3659                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3660                    doReport = false;
3661                } else {
3662                    mLastMemUsageReportTime = now;
3663                }
3664            }
3665            final ArrayList<ProcessMemInfo> memInfos
3666                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3667            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3668            long now = SystemClock.uptimeMillis();
3669            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3670                ProcessRecord rec = mLruProcesses.get(i);
3671                if (rec == dyingProc || rec.thread == null) {
3672                    continue;
3673                }
3674                if (doReport) {
3675                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3676                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3677                }
3678                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3679                    // The low memory report is overriding any current
3680                    // state for a GC request.  Make sure to do
3681                    // heavy/important/visible/foreground processes first.
3682                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3683                        rec.lastRequestedGc = 0;
3684                    } else {
3685                        rec.lastRequestedGc = rec.lastLowMemory;
3686                    }
3687                    rec.reportLowMemory = true;
3688                    rec.lastLowMemory = now;
3689                    mProcessesToGc.remove(rec);
3690                    addProcessToGcListLocked(rec);
3691                }
3692            }
3693            if (doReport) {
3694                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3695                mHandler.sendMessage(msg);
3696            }
3697            scheduleAppGcsLocked();
3698        }
3699    }
3700
3701    final void appDiedLocked(ProcessRecord app, int pid,
3702            IApplicationThread thread) {
3703
3704        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3705        synchronized (stats) {
3706            stats.noteProcessDiedLocked(app.info.uid, pid);
3707        }
3708
3709        // Clean up already done if the process has been re-started.
3710        if (app.pid == pid && app.thread != null &&
3711                app.thread.asBinder() == thread.asBinder()) {
3712            boolean doLowMem = app.instrumentationClass == null;
3713            boolean doOomAdj = doLowMem;
3714            if (!app.killedByAm) {
3715                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3716                        + ") has died.");
3717                mAllowLowerMemLevel = true;
3718            } else {
3719                // Note that we always want to do oom adj to update our state with the
3720                // new number of procs.
3721                mAllowLowerMemLevel = false;
3722                doLowMem = false;
3723            }
3724            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3725            if (DEBUG_CLEANUP) Slog.v(
3726                TAG, "Dying app: " + app + ", pid: " + pid
3727                + ", thread: " + thread.asBinder());
3728            handleAppDiedLocked(app, false, true);
3729
3730            if (doOomAdj) {
3731                updateOomAdjLocked();
3732            }
3733            if (doLowMem) {
3734                doLowMemReportIfNeededLocked(app);
3735            }
3736        } else if (app.pid != pid) {
3737            // A new process has already been started.
3738            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3739                    + ") has died and restarted (pid " + app.pid + ").");
3740            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3741        } else if (DEBUG_PROCESSES) {
3742            Slog.d(TAG, "Received spurious death notification for thread "
3743                    + thread.asBinder());
3744        }
3745    }
3746
3747    /**
3748     * If a stack trace dump file is configured, dump process stack traces.
3749     * @param clearTraces causes the dump file to be erased prior to the new
3750     *    traces being written, if true; when false, the new traces will be
3751     *    appended to any existing file content.
3752     * @param firstPids of dalvik VM processes to dump stack traces for first
3753     * @param lastPids of dalvik VM processes to dump stack traces for last
3754     * @param nativeProcs optional list of native process names to dump stack crawls
3755     * @return file containing stack traces, or null if no dump file is configured
3756     */
3757    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3758            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3759        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3760        if (tracesPath == null || tracesPath.length() == 0) {
3761            return null;
3762        }
3763
3764        File tracesFile = new File(tracesPath);
3765        try {
3766            File tracesDir = tracesFile.getParentFile();
3767            if (!tracesDir.exists()) {
3768                tracesFile.mkdirs();
3769                if (!SELinux.restorecon(tracesDir)) {
3770                    return null;
3771                }
3772            }
3773            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3774
3775            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3776            tracesFile.createNewFile();
3777            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3778        } catch (IOException e) {
3779            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3780            return null;
3781        }
3782
3783        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3784        return tracesFile;
3785    }
3786
3787    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3788            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3789        // Use a FileObserver to detect when traces finish writing.
3790        // The order of traces is considered important to maintain for legibility.
3791        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3792            @Override
3793            public synchronized void onEvent(int event, String path) { notify(); }
3794        };
3795
3796        try {
3797            observer.startWatching();
3798
3799            // First collect all of the stacks of the most important pids.
3800            if (firstPids != null) {
3801                try {
3802                    int num = firstPids.size();
3803                    for (int i = 0; i < num; i++) {
3804                        synchronized (observer) {
3805                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3806                            observer.wait(200);  // Wait for write-close, give up after 200msec
3807                        }
3808                    }
3809                } catch (InterruptedException e) {
3810                    Log.wtf(TAG, e);
3811                }
3812            }
3813
3814            // Next collect the stacks of the native pids
3815            if (nativeProcs != null) {
3816                int[] pids = Process.getPidsForCommands(nativeProcs);
3817                if (pids != null) {
3818                    for (int pid : pids) {
3819                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3820                    }
3821                }
3822            }
3823
3824            // Lastly, measure CPU usage.
3825            if (processCpuTracker != null) {
3826                processCpuTracker.init();
3827                System.gc();
3828                processCpuTracker.update();
3829                try {
3830                    synchronized (processCpuTracker) {
3831                        processCpuTracker.wait(500); // measure over 1/2 second.
3832                    }
3833                } catch (InterruptedException e) {
3834                }
3835                processCpuTracker.update();
3836
3837                // We'll take the stack crawls of just the top apps using CPU.
3838                final int N = processCpuTracker.countWorkingStats();
3839                int numProcs = 0;
3840                for (int i=0; i<N && numProcs<5; i++) {
3841                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3842                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3843                        numProcs++;
3844                        try {
3845                            synchronized (observer) {
3846                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3847                                observer.wait(200);  // Wait for write-close, give up after 200msec
3848                            }
3849                        } catch (InterruptedException e) {
3850                            Log.wtf(TAG, e);
3851                        }
3852
3853                    }
3854                }
3855            }
3856        } finally {
3857            observer.stopWatching();
3858        }
3859    }
3860
3861    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3862        if (true || IS_USER_BUILD) {
3863            return;
3864        }
3865        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3866        if (tracesPath == null || tracesPath.length() == 0) {
3867            return;
3868        }
3869
3870        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3871        StrictMode.allowThreadDiskWrites();
3872        try {
3873            final File tracesFile = new File(tracesPath);
3874            final File tracesDir = tracesFile.getParentFile();
3875            final File tracesTmp = new File(tracesDir, "__tmp__");
3876            try {
3877                if (!tracesDir.exists()) {
3878                    tracesFile.mkdirs();
3879                    if (!SELinux.restorecon(tracesDir.getPath())) {
3880                        return;
3881                    }
3882                }
3883                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3884
3885                if (tracesFile.exists()) {
3886                    tracesTmp.delete();
3887                    tracesFile.renameTo(tracesTmp);
3888                }
3889                StringBuilder sb = new StringBuilder();
3890                Time tobj = new Time();
3891                tobj.set(System.currentTimeMillis());
3892                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3893                sb.append(": ");
3894                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3895                sb.append(" since ");
3896                sb.append(msg);
3897                FileOutputStream fos = new FileOutputStream(tracesFile);
3898                fos.write(sb.toString().getBytes());
3899                if (app == null) {
3900                    fos.write("\n*** No application process!".getBytes());
3901                }
3902                fos.close();
3903                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3904            } catch (IOException e) {
3905                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3906                return;
3907            }
3908
3909            if (app != null) {
3910                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3911                firstPids.add(app.pid);
3912                dumpStackTraces(tracesPath, firstPids, null, null, null);
3913            }
3914
3915            File lastTracesFile = null;
3916            File curTracesFile = null;
3917            for (int i=9; i>=0; i--) {
3918                String name = String.format(Locale.US, "slow%02d.txt", i);
3919                curTracesFile = new File(tracesDir, name);
3920                if (curTracesFile.exists()) {
3921                    if (lastTracesFile != null) {
3922                        curTracesFile.renameTo(lastTracesFile);
3923                    } else {
3924                        curTracesFile.delete();
3925                    }
3926                }
3927                lastTracesFile = curTracesFile;
3928            }
3929            tracesFile.renameTo(curTracesFile);
3930            if (tracesTmp.exists()) {
3931                tracesTmp.renameTo(tracesFile);
3932            }
3933        } finally {
3934            StrictMode.setThreadPolicy(oldPolicy);
3935        }
3936    }
3937
3938    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3939            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3940        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3941        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3942
3943        if (mController != null) {
3944            try {
3945                // 0 == continue, -1 = kill process immediately
3946                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3947                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3948            } catch (RemoteException e) {
3949                mController = null;
3950                Watchdog.getInstance().setActivityController(null);
3951            }
3952        }
3953
3954        long anrTime = SystemClock.uptimeMillis();
3955        if (MONITOR_CPU_USAGE) {
3956            updateCpuStatsNow();
3957        }
3958
3959        synchronized (this) {
3960            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3961            if (mShuttingDown) {
3962                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3963                return;
3964            } else if (app.notResponding) {
3965                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3966                return;
3967            } else if (app.crashing) {
3968                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3969                return;
3970            }
3971
3972            // In case we come through here for the same app before completing
3973            // this one, mark as anring now so we will bail out.
3974            app.notResponding = true;
3975
3976            // Log the ANR to the event log.
3977            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3978                    app.processName, app.info.flags, annotation);
3979
3980            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3981            firstPids.add(app.pid);
3982
3983            int parentPid = app.pid;
3984            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3985            if (parentPid != app.pid) firstPids.add(parentPid);
3986
3987            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3988
3989            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3990                ProcessRecord r = mLruProcesses.get(i);
3991                if (r != null && r.thread != null) {
3992                    int pid = r.pid;
3993                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3994                        if (r.persistent) {
3995                            firstPids.add(pid);
3996                        } else {
3997                            lastPids.put(pid, Boolean.TRUE);
3998                        }
3999                    }
4000                }
4001            }
4002        }
4003
4004        // Log the ANR to the main log.
4005        StringBuilder info = new StringBuilder();
4006        info.setLength(0);
4007        info.append("ANR in ").append(app.processName);
4008        if (activity != null && activity.shortComponentName != null) {
4009            info.append(" (").append(activity.shortComponentName).append(")");
4010        }
4011        info.append("\n");
4012        info.append("PID: ").append(app.pid).append("\n");
4013        if (annotation != null) {
4014            info.append("Reason: ").append(annotation).append("\n");
4015        }
4016        if (parent != null && parent != activity) {
4017            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4018        }
4019
4020        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4021
4022        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4023                NATIVE_STACKS_OF_INTEREST);
4024
4025        String cpuInfo = null;
4026        if (MONITOR_CPU_USAGE) {
4027            updateCpuStatsNow();
4028            synchronized (mProcessCpuThread) {
4029                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4030            }
4031            info.append(processCpuTracker.printCurrentLoad());
4032            info.append(cpuInfo);
4033        }
4034
4035        info.append(processCpuTracker.printCurrentState(anrTime));
4036
4037        Slog.e(TAG, info.toString());
4038        if (tracesFile == null) {
4039            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4040            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4041        }
4042
4043        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4044                cpuInfo, tracesFile, null);
4045
4046        if (mController != null) {
4047            try {
4048                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4049                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4050                if (res != 0) {
4051                    if (res < 0 && app.pid != MY_PID) {
4052                        Process.killProcess(app.pid);
4053                    } else {
4054                        synchronized (this) {
4055                            mServices.scheduleServiceTimeoutLocked(app);
4056                        }
4057                    }
4058                    return;
4059                }
4060            } catch (RemoteException e) {
4061                mController = null;
4062                Watchdog.getInstance().setActivityController(null);
4063            }
4064        }
4065
4066        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4067        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4068                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4069
4070        synchronized (this) {
4071            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4072                killUnneededProcessLocked(app, "background ANR");
4073                return;
4074            }
4075
4076            // Set the app's notResponding state, and look up the errorReportReceiver
4077            makeAppNotRespondingLocked(app,
4078                    activity != null ? activity.shortComponentName : null,
4079                    annotation != null ? "ANR " + annotation : "ANR",
4080                    info.toString());
4081
4082            // Bring up the infamous App Not Responding dialog
4083            Message msg = Message.obtain();
4084            HashMap<String, Object> map = new HashMap<String, Object>();
4085            msg.what = SHOW_NOT_RESPONDING_MSG;
4086            msg.obj = map;
4087            msg.arg1 = aboveSystem ? 1 : 0;
4088            map.put("app", app);
4089            if (activity != null) {
4090                map.put("activity", activity);
4091            }
4092
4093            mHandler.sendMessage(msg);
4094        }
4095    }
4096
4097    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4098        if (!mLaunchWarningShown) {
4099            mLaunchWarningShown = true;
4100            mHandler.post(new Runnable() {
4101                @Override
4102                public void run() {
4103                    synchronized (ActivityManagerService.this) {
4104                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4105                        d.show();
4106                        mHandler.postDelayed(new Runnable() {
4107                            @Override
4108                            public void run() {
4109                                synchronized (ActivityManagerService.this) {
4110                                    d.dismiss();
4111                                    mLaunchWarningShown = false;
4112                                }
4113                            }
4114                        }, 4000);
4115                    }
4116                }
4117            });
4118        }
4119    }
4120
4121    @Override
4122    public boolean clearApplicationUserData(final String packageName,
4123            final IPackageDataObserver observer, int userId) {
4124        enforceNotIsolatedCaller("clearApplicationUserData");
4125        int uid = Binder.getCallingUid();
4126        int pid = Binder.getCallingPid();
4127        userId = handleIncomingUser(pid, uid,
4128                userId, false, true, "clearApplicationUserData", null);
4129        long callingId = Binder.clearCallingIdentity();
4130        try {
4131            IPackageManager pm = AppGlobals.getPackageManager();
4132            int pkgUid = -1;
4133            synchronized(this) {
4134                try {
4135                    pkgUid = pm.getPackageUid(packageName, userId);
4136                } catch (RemoteException e) {
4137                }
4138                if (pkgUid == -1) {
4139                    Slog.w(TAG, "Invalid packageName: " + packageName);
4140                    if (observer != null) {
4141                        try {
4142                            observer.onRemoveCompleted(packageName, false);
4143                        } catch (RemoteException e) {
4144                            Slog.i(TAG, "Observer no longer exists.");
4145                        }
4146                    }
4147                    return false;
4148                }
4149                if (uid == pkgUid || checkComponentPermission(
4150                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4151                        pid, uid, -1, true)
4152                        == PackageManager.PERMISSION_GRANTED) {
4153                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4154                } else {
4155                    throw new SecurityException("PID " + pid + " does not have permission "
4156                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4157                                    + " of package " + packageName);
4158                }
4159            }
4160
4161            try {
4162                // Clear application user data
4163                pm.clearApplicationUserData(packageName, observer, userId);
4164
4165                // Remove all permissions granted from/to this package
4166                removeUriPermissionsForPackageLocked(packageName, userId, true);
4167
4168                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4169                        Uri.fromParts("package", packageName, null));
4170                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4171                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4172                        null, null, 0, null, null, null, false, false, userId);
4173            } catch (RemoteException e) {
4174            }
4175        } finally {
4176            Binder.restoreCallingIdentity(callingId);
4177        }
4178        return true;
4179    }
4180
4181    @Override
4182    public void killBackgroundProcesses(final String packageName, int userId) {
4183        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4184                != PackageManager.PERMISSION_GRANTED &&
4185                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4186                        != PackageManager.PERMISSION_GRANTED) {
4187            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4188                    + Binder.getCallingPid()
4189                    + ", uid=" + Binder.getCallingUid()
4190                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4191            Slog.w(TAG, msg);
4192            throw new SecurityException(msg);
4193        }
4194
4195        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4196                userId, true, true, "killBackgroundProcesses", null);
4197        long callingId = Binder.clearCallingIdentity();
4198        try {
4199            IPackageManager pm = AppGlobals.getPackageManager();
4200            synchronized(this) {
4201                int appId = -1;
4202                try {
4203                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4204                } catch (RemoteException e) {
4205                }
4206                if (appId == -1) {
4207                    Slog.w(TAG, "Invalid packageName: " + packageName);
4208                    return;
4209                }
4210                killPackageProcessesLocked(packageName, appId, userId,
4211                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4212            }
4213        } finally {
4214            Binder.restoreCallingIdentity(callingId);
4215        }
4216    }
4217
4218    @Override
4219    public void killAllBackgroundProcesses() {
4220        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4221                != PackageManager.PERMISSION_GRANTED) {
4222            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4223                    + Binder.getCallingPid()
4224                    + ", uid=" + Binder.getCallingUid()
4225                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4226            Slog.w(TAG, msg);
4227            throw new SecurityException(msg);
4228        }
4229
4230        long callingId = Binder.clearCallingIdentity();
4231        try {
4232            synchronized(this) {
4233                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4234                final int NP = mProcessNames.getMap().size();
4235                for (int ip=0; ip<NP; ip++) {
4236                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4237                    final int NA = apps.size();
4238                    for (int ia=0; ia<NA; ia++) {
4239                        ProcessRecord app = apps.valueAt(ia);
4240                        if (app.persistent) {
4241                            // we don't kill persistent processes
4242                            continue;
4243                        }
4244                        if (app.removed) {
4245                            procs.add(app);
4246                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4247                            app.removed = true;
4248                            procs.add(app);
4249                        }
4250                    }
4251                }
4252
4253                int N = procs.size();
4254                for (int i=0; i<N; i++) {
4255                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4256                }
4257                mAllowLowerMemLevel = true;
4258                updateOomAdjLocked();
4259                doLowMemReportIfNeededLocked(null);
4260            }
4261        } finally {
4262            Binder.restoreCallingIdentity(callingId);
4263        }
4264    }
4265
4266    @Override
4267    public void forceStopPackage(final String packageName, int userId) {
4268        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4269                != PackageManager.PERMISSION_GRANTED) {
4270            String msg = "Permission Denial: forceStopPackage() from pid="
4271                    + Binder.getCallingPid()
4272                    + ", uid=" + Binder.getCallingUid()
4273                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4274            Slog.w(TAG, msg);
4275            throw new SecurityException(msg);
4276        }
4277        final int callingPid = Binder.getCallingPid();
4278        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4279                userId, true, true, "forceStopPackage", null);
4280        long callingId = Binder.clearCallingIdentity();
4281        try {
4282            IPackageManager pm = AppGlobals.getPackageManager();
4283            synchronized(this) {
4284                int[] users = userId == UserHandle.USER_ALL
4285                        ? getUsersLocked() : new int[] { userId };
4286                for (int user : users) {
4287                    int pkgUid = -1;
4288                    try {
4289                        pkgUid = pm.getPackageUid(packageName, user);
4290                    } catch (RemoteException e) {
4291                    }
4292                    if (pkgUid == -1) {
4293                        Slog.w(TAG, "Invalid packageName: " + packageName);
4294                        continue;
4295                    }
4296                    try {
4297                        pm.setPackageStoppedState(packageName, true, user);
4298                    } catch (RemoteException e) {
4299                    } catch (IllegalArgumentException e) {
4300                        Slog.w(TAG, "Failed trying to unstop package "
4301                                + packageName + ": " + e);
4302                    }
4303                    if (isUserRunningLocked(user, false)) {
4304                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4305                    }
4306                }
4307            }
4308        } finally {
4309            Binder.restoreCallingIdentity(callingId);
4310        }
4311    }
4312
4313    /*
4314     * The pkg name and app id have to be specified.
4315     */
4316    @Override
4317    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4318        if (pkg == null) {
4319            return;
4320        }
4321        // Make sure the uid is valid.
4322        if (appid < 0) {
4323            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4324            return;
4325        }
4326        int callerUid = Binder.getCallingUid();
4327        // Only the system server can kill an application
4328        if (callerUid == Process.SYSTEM_UID) {
4329            // Post an aysnc message to kill the application
4330            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4331            msg.arg1 = appid;
4332            msg.arg2 = 0;
4333            Bundle bundle = new Bundle();
4334            bundle.putString("pkg", pkg);
4335            bundle.putString("reason", reason);
4336            msg.obj = bundle;
4337            mHandler.sendMessage(msg);
4338        } else {
4339            throw new SecurityException(callerUid + " cannot kill pkg: " +
4340                    pkg);
4341        }
4342    }
4343
4344    @Override
4345    public void closeSystemDialogs(String reason) {
4346        enforceNotIsolatedCaller("closeSystemDialogs");
4347
4348        final int pid = Binder.getCallingPid();
4349        final int uid = Binder.getCallingUid();
4350        final long origId = Binder.clearCallingIdentity();
4351        try {
4352            synchronized (this) {
4353                // Only allow this from foreground processes, so that background
4354                // applications can't abuse it to prevent system UI from being shown.
4355                if (uid >= Process.FIRST_APPLICATION_UID) {
4356                    ProcessRecord proc;
4357                    synchronized (mPidsSelfLocked) {
4358                        proc = mPidsSelfLocked.get(pid);
4359                    }
4360                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4361                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4362                                + " from background process " + proc);
4363                        return;
4364                    }
4365                }
4366                closeSystemDialogsLocked(reason);
4367            }
4368        } finally {
4369            Binder.restoreCallingIdentity(origId);
4370        }
4371    }
4372
4373    void closeSystemDialogsLocked(String reason) {
4374        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4375        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4376                | Intent.FLAG_RECEIVER_FOREGROUND);
4377        if (reason != null) {
4378            intent.putExtra("reason", reason);
4379        }
4380        mWindowManager.closeSystemDialogs(reason);
4381
4382        mStackSupervisor.closeSystemDialogsLocked();
4383
4384        broadcastIntentLocked(null, null, intent, null,
4385                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4386                Process.SYSTEM_UID, UserHandle.USER_ALL);
4387    }
4388
4389    @Override
4390    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4391        enforceNotIsolatedCaller("getProcessMemoryInfo");
4392        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4393        for (int i=pids.length-1; i>=0; i--) {
4394            ProcessRecord proc;
4395            int oomAdj;
4396            synchronized (this) {
4397                synchronized (mPidsSelfLocked) {
4398                    proc = mPidsSelfLocked.get(pids[i]);
4399                    oomAdj = proc != null ? proc.setAdj : 0;
4400                }
4401            }
4402            infos[i] = new Debug.MemoryInfo();
4403            Debug.getMemoryInfo(pids[i], infos[i]);
4404            if (proc != null) {
4405                synchronized (this) {
4406                    if (proc.thread != null && proc.setAdj == oomAdj) {
4407                        // Record this for posterity if the process has been stable.
4408                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4409                                infos[i].getTotalUss(), false, proc.pkgList);
4410                    }
4411                }
4412            }
4413        }
4414        return infos;
4415    }
4416
4417    @Override
4418    public long[] getProcessPss(int[] pids) {
4419        enforceNotIsolatedCaller("getProcessPss");
4420        long[] pss = new long[pids.length];
4421        for (int i=pids.length-1; i>=0; i--) {
4422            ProcessRecord proc;
4423            int oomAdj;
4424            synchronized (this) {
4425                synchronized (mPidsSelfLocked) {
4426                    proc = mPidsSelfLocked.get(pids[i]);
4427                    oomAdj = proc != null ? proc.setAdj : 0;
4428                }
4429            }
4430            long[] tmpUss = new long[1];
4431            pss[i] = Debug.getPss(pids[i], tmpUss);
4432            if (proc != null) {
4433                synchronized (this) {
4434                    if (proc.thread != null && proc.setAdj == oomAdj) {
4435                        // Record this for posterity if the process has been stable.
4436                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4437                    }
4438                }
4439            }
4440        }
4441        return pss;
4442    }
4443
4444    @Override
4445    public void killApplicationProcess(String processName, int uid) {
4446        if (processName == null) {
4447            return;
4448        }
4449
4450        int callerUid = Binder.getCallingUid();
4451        // Only the system server can kill an application
4452        if (callerUid == Process.SYSTEM_UID) {
4453            synchronized (this) {
4454                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4455                if (app != null && app.thread != null) {
4456                    try {
4457                        app.thread.scheduleSuicide();
4458                    } catch (RemoteException e) {
4459                        // If the other end already died, then our work here is done.
4460                    }
4461                } else {
4462                    Slog.w(TAG, "Process/uid not found attempting kill of "
4463                            + processName + " / " + uid);
4464                }
4465            }
4466        } else {
4467            throw new SecurityException(callerUid + " cannot kill app process: " +
4468                    processName);
4469        }
4470    }
4471
4472    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4473        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4474                false, true, false, UserHandle.getUserId(uid), reason);
4475        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4476                Uri.fromParts("package", packageName, null));
4477        if (!mProcessesReady) {
4478            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4479                    | Intent.FLAG_RECEIVER_FOREGROUND);
4480        }
4481        intent.putExtra(Intent.EXTRA_UID, uid);
4482        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4483        broadcastIntentLocked(null, null, intent,
4484                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4485                false, false,
4486                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4487    }
4488
4489    private void forceStopUserLocked(int userId, String reason) {
4490        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
4491        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4492        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4493                | Intent.FLAG_RECEIVER_FOREGROUND);
4494        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4495        broadcastIntentLocked(null, null, intent,
4496                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4497                false, false,
4498                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4499    }
4500
4501    private final boolean killPackageProcessesLocked(String packageName, int appId,
4502            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4503            boolean doit, boolean evenPersistent, String reason) {
4504        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4505
4506        // Remove all processes this package may have touched: all with the
4507        // same UID (except for the system or root user), and all whose name
4508        // matches the package name.
4509        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4510        final int NP = mProcessNames.getMap().size();
4511        for (int ip=0; ip<NP; ip++) {
4512            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4513            final int NA = apps.size();
4514            for (int ia=0; ia<NA; ia++) {
4515                ProcessRecord app = apps.valueAt(ia);
4516                if (app.persistent && !evenPersistent) {
4517                    // we don't kill persistent processes
4518                    continue;
4519                }
4520                if (app.removed) {
4521                    if (doit) {
4522                        procs.add(app);
4523                    }
4524                    continue;
4525                }
4526
4527                // Skip process if it doesn't meet our oom adj requirement.
4528                if (app.setAdj < minOomAdj) {
4529                    continue;
4530                }
4531
4532                // If no package is specified, we call all processes under the
4533                // give user id.
4534                if (packageName == null) {
4535                    if (app.userId != userId) {
4536                        continue;
4537                    }
4538                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4539                        continue;
4540                    }
4541                // Package has been specified, we want to hit all processes
4542                // that match it.  We need to qualify this by the processes
4543                // that are running under the specified app and user ID.
4544                } else {
4545                    if (UserHandle.getAppId(app.uid) != appId) {
4546                        continue;
4547                    }
4548                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4549                        continue;
4550                    }
4551                    if (!app.pkgList.containsKey(packageName)) {
4552                        continue;
4553                    }
4554                }
4555
4556                // Process has passed all conditions, kill it!
4557                if (!doit) {
4558                    return true;
4559                }
4560                app.removed = true;
4561                procs.add(app);
4562            }
4563        }
4564
4565        int N = procs.size();
4566        for (int i=0; i<N; i++) {
4567            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4568        }
4569        updateOomAdjLocked();
4570        return N > 0;
4571    }
4572
4573    private final boolean forceStopPackageLocked(String name, int appId,
4574            boolean callerWillRestart, boolean purgeCache, boolean doit,
4575            boolean evenPersistent, int userId, String reason) {
4576        int i;
4577        int N;
4578
4579        if (userId == UserHandle.USER_ALL && name == null) {
4580            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4581        }
4582
4583        if (appId < 0 && name != null) {
4584            try {
4585                appId = UserHandle.getAppId(
4586                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4587            } catch (RemoteException e) {
4588            }
4589        }
4590
4591        if (doit) {
4592            if (name != null) {
4593                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4594                        + " user=" + userId + ": " + reason);
4595            } else {
4596                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4597            }
4598
4599            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4600            for (int ip=pmap.size()-1; ip>=0; ip--) {
4601                SparseArray<Long> ba = pmap.valueAt(ip);
4602                for (i=ba.size()-1; i>=0; i--) {
4603                    boolean remove = false;
4604                    final int entUid = ba.keyAt(i);
4605                    if (name != null) {
4606                        if (userId == UserHandle.USER_ALL) {
4607                            if (UserHandle.getAppId(entUid) == appId) {
4608                                remove = true;
4609                            }
4610                        } else {
4611                            if (entUid == UserHandle.getUid(userId, appId)) {
4612                                remove = true;
4613                            }
4614                        }
4615                    } else if (UserHandle.getUserId(entUid) == userId) {
4616                        remove = true;
4617                    }
4618                    if (remove) {
4619                        ba.removeAt(i);
4620                    }
4621                }
4622                if (ba.size() == 0) {
4623                    pmap.removeAt(ip);
4624                }
4625            }
4626        }
4627
4628        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4629                -100, callerWillRestart, true, doit, evenPersistent,
4630                name == null ? ("stop user " + userId) : ("stop " + name));
4631
4632        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4633            if (!doit) {
4634                return true;
4635            }
4636            didSomething = true;
4637        }
4638
4639        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4640            if (!doit) {
4641                return true;
4642            }
4643            didSomething = true;
4644        }
4645
4646        if (name == null) {
4647            // Remove all sticky broadcasts from this user.
4648            mStickyBroadcasts.remove(userId);
4649        }
4650
4651        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4652        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4653                userId, providers)) {
4654            if (!doit) {
4655                return true;
4656            }
4657            didSomething = true;
4658        }
4659        N = providers.size();
4660        for (i=0; i<N; i++) {
4661            removeDyingProviderLocked(null, providers.get(i), true);
4662        }
4663
4664        // Remove transient permissions granted from/to this package/user
4665        removeUriPermissionsForPackageLocked(name, userId, false);
4666
4667        if (name == null) {
4668            // Remove pending intents.  For now we only do this when force
4669            // stopping users, because we have some problems when doing this
4670            // for packages -- app widgets are not currently cleaned up for
4671            // such packages, so they can be left with bad pending intents.
4672            if (mIntentSenderRecords.size() > 0) {
4673                Iterator<WeakReference<PendingIntentRecord>> it
4674                        = mIntentSenderRecords.values().iterator();
4675                while (it.hasNext()) {
4676                    WeakReference<PendingIntentRecord> wpir = it.next();
4677                    if (wpir == null) {
4678                        it.remove();
4679                        continue;
4680                    }
4681                    PendingIntentRecord pir = wpir.get();
4682                    if (pir == null) {
4683                        it.remove();
4684                        continue;
4685                    }
4686                    if (name == null) {
4687                        // Stopping user, remove all objects for the user.
4688                        if (pir.key.userId != userId) {
4689                            // Not the same user, skip it.
4690                            continue;
4691                        }
4692                    } else {
4693                        if (UserHandle.getAppId(pir.uid) != appId) {
4694                            // Different app id, skip it.
4695                            continue;
4696                        }
4697                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4698                            // Different user, skip it.
4699                            continue;
4700                        }
4701                        if (!pir.key.packageName.equals(name)) {
4702                            // Different package, skip it.
4703                            continue;
4704                        }
4705                    }
4706                    if (!doit) {
4707                        return true;
4708                    }
4709                    didSomething = true;
4710                    it.remove();
4711                    pir.canceled = true;
4712                    if (pir.key.activity != null) {
4713                        pir.key.activity.pendingResults.remove(pir.ref);
4714                    }
4715                }
4716            }
4717        }
4718
4719        if (doit) {
4720            if (purgeCache && name != null) {
4721                AttributeCache ac = AttributeCache.instance();
4722                if (ac != null) {
4723                    ac.removePackage(name);
4724                }
4725            }
4726            if (mBooted) {
4727                mStackSupervisor.resumeTopActivitiesLocked();
4728                mStackSupervisor.scheduleIdleLocked();
4729            }
4730        }
4731
4732        return didSomething;
4733    }
4734
4735    private final boolean removeProcessLocked(ProcessRecord app,
4736            boolean callerWillRestart, boolean allowRestart, String reason) {
4737        final String name = app.processName;
4738        final int uid = app.uid;
4739        if (DEBUG_PROCESSES) Slog.d(
4740            TAG, "Force removing proc " + app.toShortString() + " (" + name
4741            + "/" + uid + ")");
4742
4743        mProcessNames.remove(name, uid);
4744        mIsolatedProcesses.remove(app.uid);
4745        if (mHeavyWeightProcess == app) {
4746            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4747                    mHeavyWeightProcess.userId, 0));
4748            mHeavyWeightProcess = null;
4749        }
4750        boolean needRestart = false;
4751        if (app.pid > 0 && app.pid != MY_PID) {
4752            int pid = app.pid;
4753            synchronized (mPidsSelfLocked) {
4754                mPidsSelfLocked.remove(pid);
4755                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4756            }
4757            killUnneededProcessLocked(app, reason);
4758            handleAppDiedLocked(app, true, allowRestart);
4759            removeLruProcessLocked(app);
4760
4761            if (app.persistent && !app.isolated) {
4762                if (!callerWillRestart) {
4763                    addAppLocked(app.info, false);
4764                } else {
4765                    needRestart = true;
4766                }
4767            }
4768        } else {
4769            mRemovedProcesses.add(app);
4770        }
4771
4772        return needRestart;
4773    }
4774
4775    private final void processStartTimedOutLocked(ProcessRecord app) {
4776        final int pid = app.pid;
4777        boolean gone = false;
4778        synchronized (mPidsSelfLocked) {
4779            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4780            if (knownApp != null && knownApp.thread == null) {
4781                mPidsSelfLocked.remove(pid);
4782                gone = true;
4783            }
4784        }
4785
4786        if (gone) {
4787            Slog.w(TAG, "Process " + app + " failed to attach");
4788            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4789                    pid, app.uid, app.processName);
4790            mProcessNames.remove(app.processName, app.uid);
4791            mIsolatedProcesses.remove(app.uid);
4792            if (mHeavyWeightProcess == app) {
4793                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4794                        mHeavyWeightProcess.userId, 0));
4795                mHeavyWeightProcess = null;
4796            }
4797            // Take care of any launching providers waiting for this process.
4798            checkAppInLaunchingProvidersLocked(app, true);
4799            // Take care of any services that are waiting for the process.
4800            mServices.processStartTimedOutLocked(app);
4801            killUnneededProcessLocked(app, "start timeout");
4802            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4803                Slog.w(TAG, "Unattached app died before backup, skipping");
4804                try {
4805                    IBackupManager bm = IBackupManager.Stub.asInterface(
4806                            ServiceManager.getService(Context.BACKUP_SERVICE));
4807                    bm.agentDisconnected(app.info.packageName);
4808                } catch (RemoteException e) {
4809                    // Can't happen; the backup manager is local
4810                }
4811            }
4812            if (isPendingBroadcastProcessLocked(pid)) {
4813                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4814                skipPendingBroadcastLocked(pid);
4815            }
4816        } else {
4817            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4818        }
4819    }
4820
4821    private final boolean attachApplicationLocked(IApplicationThread thread,
4822            int pid) {
4823
4824        // Find the application record that is being attached...  either via
4825        // the pid if we are running in multiple processes, or just pull the
4826        // next app record if we are emulating process with anonymous threads.
4827        ProcessRecord app;
4828        if (pid != MY_PID && pid >= 0) {
4829            synchronized (mPidsSelfLocked) {
4830                app = mPidsSelfLocked.get(pid);
4831            }
4832        } else {
4833            app = null;
4834        }
4835
4836        if (app == null) {
4837            Slog.w(TAG, "No pending application record for pid " + pid
4838                    + " (IApplicationThread " + thread + "); dropping process");
4839            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4840            if (pid > 0 && pid != MY_PID) {
4841                Process.killProcessQuiet(pid);
4842            } else {
4843                try {
4844                    thread.scheduleExit();
4845                } catch (Exception e) {
4846                    // Ignore exceptions.
4847                }
4848            }
4849            return false;
4850        }
4851
4852        // If this application record is still attached to a previous
4853        // process, clean it up now.
4854        if (app.thread != null) {
4855            handleAppDiedLocked(app, true, true);
4856        }
4857
4858        // Tell the process all about itself.
4859
4860        if (localLOGV) Slog.v(
4861                TAG, "Binding process pid " + pid + " to record " + app);
4862
4863        final String processName = app.processName;
4864        try {
4865            AppDeathRecipient adr = new AppDeathRecipient(
4866                    app, pid, thread);
4867            thread.asBinder().linkToDeath(adr, 0);
4868            app.deathRecipient = adr;
4869        } catch (RemoteException e) {
4870            app.resetPackageList(mProcessStats);
4871            startProcessLocked(app, "link fail", processName);
4872            return false;
4873        }
4874
4875        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4876
4877        app.makeActive(thread, mProcessStats);
4878        app.curAdj = app.setAdj = -100;
4879        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4880        app.forcingToForeground = null;
4881        app.foregroundServices = false;
4882        app.hasShownUi = false;
4883        app.debugging = false;
4884        app.cached = false;
4885
4886        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4887
4888        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4889        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4890
4891        if (!normalMode) {
4892            Slog.i(TAG, "Launching preboot mode app: " + app);
4893        }
4894
4895        if (localLOGV) Slog.v(
4896            TAG, "New app record " + app
4897            + " thread=" + thread.asBinder() + " pid=" + pid);
4898        try {
4899            int testMode = IApplicationThread.DEBUG_OFF;
4900            if (mDebugApp != null && mDebugApp.equals(processName)) {
4901                testMode = mWaitForDebugger
4902                    ? IApplicationThread.DEBUG_WAIT
4903                    : IApplicationThread.DEBUG_ON;
4904                app.debugging = true;
4905                if (mDebugTransient) {
4906                    mDebugApp = mOrigDebugApp;
4907                    mWaitForDebugger = mOrigWaitForDebugger;
4908                }
4909            }
4910            String profileFile = app.instrumentationProfileFile;
4911            ParcelFileDescriptor profileFd = null;
4912            boolean profileAutoStop = false;
4913            if (mProfileApp != null && mProfileApp.equals(processName)) {
4914                mProfileProc = app;
4915                profileFile = mProfileFile;
4916                profileFd = mProfileFd;
4917                profileAutoStop = mAutoStopProfiler;
4918            }
4919            boolean enableOpenGlTrace = false;
4920            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4921                enableOpenGlTrace = true;
4922                mOpenGlTraceApp = null;
4923            }
4924
4925            // If the app is being launched for restore or full backup, set it up specially
4926            boolean isRestrictedBackupMode = false;
4927            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4928                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4929                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4930                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4931            }
4932
4933            ensurePackageDexOpt(app.instrumentationInfo != null
4934                    ? app.instrumentationInfo.packageName
4935                    : app.info.packageName);
4936            if (app.instrumentationClass != null) {
4937                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4938            }
4939            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4940                    + processName + " with config " + mConfiguration);
4941            ApplicationInfo appInfo = app.instrumentationInfo != null
4942                    ? app.instrumentationInfo : app.info;
4943            app.compat = compatibilityInfoForPackageLocked(appInfo);
4944            if (profileFd != null) {
4945                profileFd = profileFd.dup();
4946            }
4947            thread.bindApplication(processName, appInfo, providers,
4948                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4949                    app.instrumentationArguments, app.instrumentationWatcher,
4950                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4951                    isRestrictedBackupMode || !normalMode, app.persistent,
4952                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4953                    mCoreSettingsObserver.getCoreSettingsLocked());
4954            updateLruProcessLocked(app, false, null);
4955            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4956        } catch (Exception e) {
4957            // todo: Yikes!  What should we do?  For now we will try to
4958            // start another process, but that could easily get us in
4959            // an infinite loop of restarting processes...
4960            Slog.w(TAG, "Exception thrown during bind!", e);
4961
4962            app.resetPackageList(mProcessStats);
4963            app.unlinkDeathRecipient();
4964            startProcessLocked(app, "bind fail", processName);
4965            return false;
4966        }
4967
4968        // Remove this record from the list of starting applications.
4969        mPersistentStartingProcesses.remove(app);
4970        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4971                "Attach application locked removing on hold: " + app);
4972        mProcessesOnHold.remove(app);
4973
4974        boolean badApp = false;
4975        boolean didSomething = false;
4976
4977        // See if the top visible activity is waiting to run in this process...
4978        if (normalMode) {
4979            try {
4980                if (mStackSupervisor.attachApplicationLocked(app)) {
4981                    didSomething = true;
4982                }
4983            } catch (Exception e) {
4984                badApp = true;
4985            }
4986        }
4987
4988        // Find any services that should be running in this process...
4989        if (!badApp) {
4990            try {
4991                didSomething |= mServices.attachApplicationLocked(app, processName);
4992            } catch (Exception e) {
4993                badApp = true;
4994            }
4995        }
4996
4997        // Check if a next-broadcast receiver is in this process...
4998        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4999            try {
5000                didSomething |= sendPendingBroadcastsLocked(app);
5001            } catch (Exception e) {
5002                // If the app died trying to launch the receiver we declare it 'bad'
5003                badApp = true;
5004            }
5005        }
5006
5007        // Check whether the next backup agent is in this process...
5008        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5009            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5010            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5011            try {
5012                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5013                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5014                        mBackupTarget.backupMode);
5015            } catch (Exception e) {
5016                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5017                e.printStackTrace();
5018            }
5019        }
5020
5021        if (badApp) {
5022            // todo: Also need to kill application to deal with all
5023            // kinds of exceptions.
5024            handleAppDiedLocked(app, false, true);
5025            return false;
5026        }
5027
5028        if (!didSomething) {
5029            updateOomAdjLocked();
5030        }
5031
5032        return true;
5033    }
5034
5035    @Override
5036    public final void attachApplication(IApplicationThread thread) {
5037        synchronized (this) {
5038            int callingPid = Binder.getCallingPid();
5039            final long origId = Binder.clearCallingIdentity();
5040            attachApplicationLocked(thread, callingPid);
5041            Binder.restoreCallingIdentity(origId);
5042        }
5043    }
5044
5045    @Override
5046    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5047        final long origId = Binder.clearCallingIdentity();
5048        synchronized (this) {
5049            ActivityStack stack = ActivityRecord.getStackLocked(token);
5050            if (stack != null) {
5051                ActivityRecord r =
5052                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5053                if (stopProfiling) {
5054                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5055                        try {
5056                            mProfileFd.close();
5057                        } catch (IOException e) {
5058                        }
5059                        clearProfilerLocked();
5060                    }
5061                }
5062            }
5063        }
5064        Binder.restoreCallingIdentity(origId);
5065    }
5066
5067    void enableScreenAfterBoot() {
5068        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5069                SystemClock.uptimeMillis());
5070        mWindowManager.enableScreenAfterBoot();
5071
5072        synchronized (this) {
5073            updateEventDispatchingLocked();
5074        }
5075    }
5076
5077    @Override
5078    public void showBootMessage(final CharSequence msg, final boolean always) {
5079        enforceNotIsolatedCaller("showBootMessage");
5080        mWindowManager.showBootMessage(msg, always);
5081    }
5082
5083    @Override
5084    public void dismissKeyguardOnNextActivity() {
5085        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5086        final long token = Binder.clearCallingIdentity();
5087        try {
5088            synchronized (this) {
5089                if (DEBUG_LOCKSCREEN) logLockScreen("");
5090                if (mLockScreenShown) {
5091                    mLockScreenShown = false;
5092                    comeOutOfSleepIfNeededLocked();
5093                }
5094                mStackSupervisor.setDismissKeyguard(true);
5095            }
5096        } finally {
5097            Binder.restoreCallingIdentity(token);
5098        }
5099    }
5100
5101    final void finishBooting() {
5102        IntentFilter pkgFilter = new IntentFilter();
5103        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5104        pkgFilter.addDataScheme("package");
5105        mContext.registerReceiver(new BroadcastReceiver() {
5106            @Override
5107            public void onReceive(Context context, Intent intent) {
5108                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5109                if (pkgs != null) {
5110                    for (String pkg : pkgs) {
5111                        synchronized (ActivityManagerService.this) {
5112                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
5113                                    "finished booting")) {
5114                                setResultCode(Activity.RESULT_OK);
5115                                return;
5116                            }
5117                        }
5118                    }
5119                }
5120            }
5121        }, pkgFilter);
5122
5123        synchronized (this) {
5124            // Ensure that any processes we had put on hold are now started
5125            // up.
5126            final int NP = mProcessesOnHold.size();
5127            if (NP > 0) {
5128                ArrayList<ProcessRecord> procs =
5129                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5130                for (int ip=0; ip<NP; ip++) {
5131                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5132                            + procs.get(ip));
5133                    startProcessLocked(procs.get(ip), "on-hold", null);
5134                }
5135            }
5136
5137            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5138                // Start looking for apps that are abusing wake locks.
5139                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5140                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5141                // Tell anyone interested that we are done booting!
5142                SystemProperties.set("sys.boot_completed", "1");
5143                SystemProperties.set("dev.bootcomplete", "1");
5144                for (int i=0; i<mStartedUsers.size(); i++) {
5145                    UserStartedState uss = mStartedUsers.valueAt(i);
5146                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5147                        uss.mState = UserStartedState.STATE_RUNNING;
5148                        final int userId = mStartedUsers.keyAt(i);
5149                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5150                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5151                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5152                        broadcastIntentLocked(null, null, intent, null,
5153                                new IIntentReceiver.Stub() {
5154                                    @Override
5155                                    public void performReceive(Intent intent, int resultCode,
5156                                            String data, Bundle extras, boolean ordered,
5157                                            boolean sticky, int sendingUser) {
5158                                        synchronized (ActivityManagerService.this) {
5159                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5160                                                    true, false);
5161                                        }
5162                                    }
5163                                },
5164                                0, null, null,
5165                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5166                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5167                                userId);
5168                    }
5169                }
5170            }
5171        }
5172    }
5173
5174    final void ensureBootCompleted() {
5175        boolean booting;
5176        boolean enableScreen;
5177        synchronized (this) {
5178            booting = mBooting;
5179            mBooting = false;
5180            enableScreen = !mBooted;
5181            mBooted = true;
5182        }
5183
5184        if (booting) {
5185            finishBooting();
5186        }
5187
5188        if (enableScreen) {
5189            enableScreenAfterBoot();
5190        }
5191    }
5192
5193    @Override
5194    public final void activityResumed(IBinder token) {
5195        final long origId = Binder.clearCallingIdentity();
5196        synchronized(this) {
5197            ActivityStack stack = ActivityRecord.getStackLocked(token);
5198            if (stack != null) {
5199                ActivityRecord.activityResumedLocked(token);
5200            }
5201        }
5202        Binder.restoreCallingIdentity(origId);
5203    }
5204
5205    @Override
5206    public final void activityPaused(IBinder token) {
5207        final long origId = Binder.clearCallingIdentity();
5208        synchronized(this) {
5209            ActivityStack stack = ActivityRecord.getStackLocked(token);
5210            if (stack != null) {
5211                stack.activityPausedLocked(token, false);
5212            }
5213        }
5214        Binder.restoreCallingIdentity(origId);
5215    }
5216
5217    @Override
5218    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5219            CharSequence description) {
5220        if (localLOGV) Slog.v(
5221            TAG, "Activity stopped: token=" + token);
5222
5223        // Refuse possible leaked file descriptors
5224        if (icicle != null && icicle.hasFileDescriptors()) {
5225            throw new IllegalArgumentException("File descriptors passed in Bundle");
5226        }
5227
5228        ActivityRecord r = null;
5229
5230        final long origId = Binder.clearCallingIdentity();
5231
5232        synchronized (this) {
5233            r = ActivityRecord.isInStackLocked(token);
5234            if (r != null) {
5235                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5236            }
5237        }
5238
5239        if (r != null) {
5240            sendPendingThumbnail(r, null, null, null, false);
5241        }
5242
5243        trimApplications();
5244
5245        Binder.restoreCallingIdentity(origId);
5246    }
5247
5248    @Override
5249    public final void activityDestroyed(IBinder token) {
5250        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5251        synchronized (this) {
5252            ActivityStack stack = ActivityRecord.getStackLocked(token);
5253            if (stack != null) {
5254                stack.activityDestroyedLocked(token);
5255            }
5256        }
5257    }
5258
5259    @Override
5260    public String getCallingPackage(IBinder token) {
5261        synchronized (this) {
5262            ActivityRecord r = getCallingRecordLocked(token);
5263            return r != null ? r.info.packageName : null;
5264        }
5265    }
5266
5267    @Override
5268    public ComponentName getCallingActivity(IBinder token) {
5269        synchronized (this) {
5270            ActivityRecord r = getCallingRecordLocked(token);
5271            return r != null ? r.intent.getComponent() : null;
5272        }
5273    }
5274
5275    private ActivityRecord getCallingRecordLocked(IBinder token) {
5276        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5277        if (r == null) {
5278            return null;
5279        }
5280        return r.resultTo;
5281    }
5282
5283    @Override
5284    public ComponentName getActivityClassForToken(IBinder token) {
5285        synchronized(this) {
5286            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5287            if (r == null) {
5288                return null;
5289            }
5290            return r.intent.getComponent();
5291        }
5292    }
5293
5294    @Override
5295    public String getPackageForToken(IBinder token) {
5296        synchronized(this) {
5297            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5298            if (r == null) {
5299                return null;
5300            }
5301            return r.packageName;
5302        }
5303    }
5304
5305    @Override
5306    public IIntentSender getIntentSender(int type,
5307            String packageName, IBinder token, String resultWho,
5308            int requestCode, Intent[] intents, String[] resolvedTypes,
5309            int flags, Bundle options, int userId) {
5310        enforceNotIsolatedCaller("getIntentSender");
5311        // Refuse possible leaked file descriptors
5312        if (intents != null) {
5313            if (intents.length < 1) {
5314                throw new IllegalArgumentException("Intents array length must be >= 1");
5315            }
5316            for (int i=0; i<intents.length; i++) {
5317                Intent intent = intents[i];
5318                if (intent != null) {
5319                    if (intent.hasFileDescriptors()) {
5320                        throw new IllegalArgumentException("File descriptors passed in Intent");
5321                    }
5322                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5323                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5324                        throw new IllegalArgumentException(
5325                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5326                    }
5327                    intents[i] = new Intent(intent);
5328                }
5329            }
5330            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5331                throw new IllegalArgumentException(
5332                        "Intent array length does not match resolvedTypes length");
5333            }
5334        }
5335        if (options != null) {
5336            if (options.hasFileDescriptors()) {
5337                throw new IllegalArgumentException("File descriptors passed in options");
5338            }
5339        }
5340
5341        synchronized(this) {
5342            int callingUid = Binder.getCallingUid();
5343            int origUserId = userId;
5344            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5345                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5346                    "getIntentSender", null);
5347            if (origUserId == UserHandle.USER_CURRENT) {
5348                // We don't want to evaluate this until the pending intent is
5349                // actually executed.  However, we do want to always do the
5350                // security checking for it above.
5351                userId = UserHandle.USER_CURRENT;
5352            }
5353            try {
5354                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5355                    int uid = AppGlobals.getPackageManager()
5356                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5357                    if (!UserHandle.isSameApp(callingUid, uid)) {
5358                        String msg = "Permission Denial: getIntentSender() from pid="
5359                            + Binder.getCallingPid()
5360                            + ", uid=" + Binder.getCallingUid()
5361                            + ", (need uid=" + uid + ")"
5362                            + " is not allowed to send as package " + packageName;
5363                        Slog.w(TAG, msg);
5364                        throw new SecurityException(msg);
5365                    }
5366                }
5367
5368                return getIntentSenderLocked(type, packageName, callingUid, userId,
5369                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5370
5371            } catch (RemoteException e) {
5372                throw new SecurityException(e);
5373            }
5374        }
5375    }
5376
5377    IIntentSender getIntentSenderLocked(int type, String packageName,
5378            int callingUid, int userId, IBinder token, String resultWho,
5379            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5380            Bundle options) {
5381        if (DEBUG_MU)
5382            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5383        ActivityRecord activity = null;
5384        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5385            activity = ActivityRecord.isInStackLocked(token);
5386            if (activity == null) {
5387                return null;
5388            }
5389            if (activity.finishing) {
5390                return null;
5391            }
5392        }
5393
5394        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5395        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5396        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5397        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5398                |PendingIntent.FLAG_UPDATE_CURRENT);
5399
5400        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5401                type, packageName, activity, resultWho,
5402                requestCode, intents, resolvedTypes, flags, options, userId);
5403        WeakReference<PendingIntentRecord> ref;
5404        ref = mIntentSenderRecords.get(key);
5405        PendingIntentRecord rec = ref != null ? ref.get() : null;
5406        if (rec != null) {
5407            if (!cancelCurrent) {
5408                if (updateCurrent) {
5409                    if (rec.key.requestIntent != null) {
5410                        rec.key.requestIntent.replaceExtras(intents != null ?
5411                                intents[intents.length - 1] : null);
5412                    }
5413                    if (intents != null) {
5414                        intents[intents.length-1] = rec.key.requestIntent;
5415                        rec.key.allIntents = intents;
5416                        rec.key.allResolvedTypes = resolvedTypes;
5417                    } else {
5418                        rec.key.allIntents = null;
5419                        rec.key.allResolvedTypes = null;
5420                    }
5421                }
5422                return rec;
5423            }
5424            rec.canceled = true;
5425            mIntentSenderRecords.remove(key);
5426        }
5427        if (noCreate) {
5428            return rec;
5429        }
5430        rec = new PendingIntentRecord(this, key, callingUid);
5431        mIntentSenderRecords.put(key, rec.ref);
5432        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5433            if (activity.pendingResults == null) {
5434                activity.pendingResults
5435                        = new HashSet<WeakReference<PendingIntentRecord>>();
5436            }
5437            activity.pendingResults.add(rec.ref);
5438        }
5439        return rec;
5440    }
5441
5442    @Override
5443    public void cancelIntentSender(IIntentSender sender) {
5444        if (!(sender instanceof PendingIntentRecord)) {
5445            return;
5446        }
5447        synchronized(this) {
5448            PendingIntentRecord rec = (PendingIntentRecord)sender;
5449            try {
5450                int uid = AppGlobals.getPackageManager()
5451                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5452                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5453                    String msg = "Permission Denial: cancelIntentSender() from pid="
5454                        + Binder.getCallingPid()
5455                        + ", uid=" + Binder.getCallingUid()
5456                        + " is not allowed to cancel packges "
5457                        + rec.key.packageName;
5458                    Slog.w(TAG, msg);
5459                    throw new SecurityException(msg);
5460                }
5461            } catch (RemoteException e) {
5462                throw new SecurityException(e);
5463            }
5464            cancelIntentSenderLocked(rec, true);
5465        }
5466    }
5467
5468    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5469        rec.canceled = true;
5470        mIntentSenderRecords.remove(rec.key);
5471        if (cleanActivity && rec.key.activity != null) {
5472            rec.key.activity.pendingResults.remove(rec.ref);
5473        }
5474    }
5475
5476    @Override
5477    public String getPackageForIntentSender(IIntentSender pendingResult) {
5478        if (!(pendingResult instanceof PendingIntentRecord)) {
5479            return null;
5480        }
5481        try {
5482            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5483            return res.key.packageName;
5484        } catch (ClassCastException e) {
5485        }
5486        return null;
5487    }
5488
5489    @Override
5490    public int getUidForIntentSender(IIntentSender sender) {
5491        if (sender instanceof PendingIntentRecord) {
5492            try {
5493                PendingIntentRecord res = (PendingIntentRecord)sender;
5494                return res.uid;
5495            } catch (ClassCastException e) {
5496            }
5497        }
5498        return -1;
5499    }
5500
5501    @Override
5502    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5503        if (!(pendingResult instanceof PendingIntentRecord)) {
5504            return false;
5505        }
5506        try {
5507            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5508            if (res.key.allIntents == null) {
5509                return false;
5510            }
5511            for (int i=0; i<res.key.allIntents.length; i++) {
5512                Intent intent = res.key.allIntents[i];
5513                if (intent.getPackage() != null && intent.getComponent() != null) {
5514                    return false;
5515                }
5516            }
5517            return true;
5518        } catch (ClassCastException e) {
5519        }
5520        return false;
5521    }
5522
5523    @Override
5524    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5525        if (!(pendingResult instanceof PendingIntentRecord)) {
5526            return false;
5527        }
5528        try {
5529            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5530            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5531                return true;
5532            }
5533            return false;
5534        } catch (ClassCastException e) {
5535        }
5536        return false;
5537    }
5538
5539    @Override
5540    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5541        if (!(pendingResult instanceof PendingIntentRecord)) {
5542            return null;
5543        }
5544        try {
5545            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5546            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5547        } catch (ClassCastException e) {
5548        }
5549        return null;
5550    }
5551
5552    @Override
5553    public void setProcessLimit(int max) {
5554        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5555                "setProcessLimit()");
5556        synchronized (this) {
5557            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5558            mProcessLimitOverride = max;
5559        }
5560        trimApplications();
5561    }
5562
5563    @Override
5564    public int getProcessLimit() {
5565        synchronized (this) {
5566            return mProcessLimitOverride;
5567        }
5568    }
5569
5570    void foregroundTokenDied(ForegroundToken token) {
5571        synchronized (ActivityManagerService.this) {
5572            synchronized (mPidsSelfLocked) {
5573                ForegroundToken cur
5574                    = mForegroundProcesses.get(token.pid);
5575                if (cur != token) {
5576                    return;
5577                }
5578                mForegroundProcesses.remove(token.pid);
5579                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5580                if (pr == null) {
5581                    return;
5582                }
5583                pr.forcingToForeground = null;
5584                pr.foregroundServices = false;
5585            }
5586            updateOomAdjLocked();
5587        }
5588    }
5589
5590    @Override
5591    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5592        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5593                "setProcessForeground()");
5594        synchronized(this) {
5595            boolean changed = false;
5596
5597            synchronized (mPidsSelfLocked) {
5598                ProcessRecord pr = mPidsSelfLocked.get(pid);
5599                if (pr == null && isForeground) {
5600                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5601                    return;
5602                }
5603                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5604                if (oldToken != null) {
5605                    oldToken.token.unlinkToDeath(oldToken, 0);
5606                    mForegroundProcesses.remove(pid);
5607                    if (pr != null) {
5608                        pr.forcingToForeground = null;
5609                    }
5610                    changed = true;
5611                }
5612                if (isForeground && token != null) {
5613                    ForegroundToken newToken = new ForegroundToken() {
5614                        @Override
5615                        public void binderDied() {
5616                            foregroundTokenDied(this);
5617                        }
5618                    };
5619                    newToken.pid = pid;
5620                    newToken.token = token;
5621                    try {
5622                        token.linkToDeath(newToken, 0);
5623                        mForegroundProcesses.put(pid, newToken);
5624                        pr.forcingToForeground = token;
5625                        changed = true;
5626                    } catch (RemoteException e) {
5627                        // If the process died while doing this, we will later
5628                        // do the cleanup with the process death link.
5629                    }
5630                }
5631            }
5632
5633            if (changed) {
5634                updateOomAdjLocked();
5635            }
5636        }
5637    }
5638
5639    // =========================================================
5640    // PERMISSIONS
5641    // =========================================================
5642
5643    static class PermissionController extends IPermissionController.Stub {
5644        ActivityManagerService mActivityManagerService;
5645        PermissionController(ActivityManagerService activityManagerService) {
5646            mActivityManagerService = activityManagerService;
5647        }
5648
5649        @Override
5650        public boolean checkPermission(String permission, int pid, int uid) {
5651            return mActivityManagerService.checkPermission(permission, pid,
5652                    uid) == PackageManager.PERMISSION_GRANTED;
5653        }
5654    }
5655
5656    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5657        @Override
5658        public int checkComponentPermission(String permission, int pid, int uid,
5659                int owningUid, boolean exported) {
5660            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5661                    owningUid, exported);
5662        }
5663
5664        @Override
5665        public Object getAMSLock() {
5666            return ActivityManagerService.this;
5667        }
5668    }
5669
5670    /**
5671     * This can be called with or without the global lock held.
5672     */
5673    int checkComponentPermission(String permission, int pid, int uid,
5674            int owningUid, boolean exported) {
5675        // We might be performing an operation on behalf of an indirect binder
5676        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5677        // client identity accordingly before proceeding.
5678        Identity tlsIdentity = sCallerIdentity.get();
5679        if (tlsIdentity != null) {
5680            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5681                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5682            uid = tlsIdentity.uid;
5683            pid = tlsIdentity.pid;
5684        }
5685
5686        if (pid == MY_PID) {
5687            return PackageManager.PERMISSION_GRANTED;
5688        }
5689
5690        return ActivityManager.checkComponentPermission(permission, uid,
5691                owningUid, exported);
5692    }
5693
5694    /**
5695     * As the only public entry point for permissions checking, this method
5696     * can enforce the semantic that requesting a check on a null global
5697     * permission is automatically denied.  (Internally a null permission
5698     * string is used when calling {@link #checkComponentPermission} in cases
5699     * when only uid-based security is needed.)
5700     *
5701     * This can be called with or without the global lock held.
5702     */
5703    @Override
5704    public int checkPermission(String permission, int pid, int uid) {
5705        if (permission == null) {
5706            return PackageManager.PERMISSION_DENIED;
5707        }
5708        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5709    }
5710
5711    /**
5712     * Binder IPC calls go through the public entry point.
5713     * This can be called with or without the global lock held.
5714     */
5715    int checkCallingPermission(String permission) {
5716        return checkPermission(permission,
5717                Binder.getCallingPid(),
5718                UserHandle.getAppId(Binder.getCallingUid()));
5719    }
5720
5721    /**
5722     * This can be called with or without the global lock held.
5723     */
5724    void enforceCallingPermission(String permission, String func) {
5725        if (checkCallingPermission(permission)
5726                == PackageManager.PERMISSION_GRANTED) {
5727            return;
5728        }
5729
5730        String msg = "Permission Denial: " + func + " from pid="
5731                + Binder.getCallingPid()
5732                + ", uid=" + Binder.getCallingUid()
5733                + " requires " + permission;
5734        Slog.w(TAG, msg);
5735        throw new SecurityException(msg);
5736    }
5737
5738    /**
5739     * Determine if UID is holding permissions required to access {@link Uri} in
5740     * the given {@link ProviderInfo}. Final permission checking is always done
5741     * in {@link ContentProvider}.
5742     */
5743    private final boolean checkHoldingPermissionsLocked(
5744            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5745        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5746                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5747
5748        if (pi.applicationInfo.uid == uid) {
5749            return true;
5750        } else if (!pi.exported) {
5751            return false;
5752        }
5753
5754        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5755        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5756        try {
5757            // check if target holds top-level <provider> permissions
5758            if (!readMet && pi.readPermission != null
5759                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5760                readMet = true;
5761            }
5762            if (!writeMet && pi.writePermission != null
5763                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5764                writeMet = true;
5765            }
5766
5767            // track if unprotected read/write is allowed; any denied
5768            // <path-permission> below removes this ability
5769            boolean allowDefaultRead = pi.readPermission == null;
5770            boolean allowDefaultWrite = pi.writePermission == null;
5771
5772            // check if target holds any <path-permission> that match uri
5773            final PathPermission[] pps = pi.pathPermissions;
5774            if (pps != null) {
5775                final String path = uri.getPath();
5776                int i = pps.length;
5777                while (i > 0 && (!readMet || !writeMet)) {
5778                    i--;
5779                    PathPermission pp = pps[i];
5780                    if (pp.match(path)) {
5781                        if (!readMet) {
5782                            final String pprperm = pp.getReadPermission();
5783                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5784                                    + pprperm + " for " + pp.getPath()
5785                                    + ": match=" + pp.match(path)
5786                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5787                            if (pprperm != null) {
5788                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5789                                    readMet = true;
5790                                } else {
5791                                    allowDefaultRead = false;
5792                                }
5793                            }
5794                        }
5795                        if (!writeMet) {
5796                            final String ppwperm = pp.getWritePermission();
5797                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5798                                    + ppwperm + " for " + pp.getPath()
5799                                    + ": match=" + pp.match(path)
5800                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5801                            if (ppwperm != null) {
5802                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5803                                    writeMet = true;
5804                                } else {
5805                                    allowDefaultWrite = false;
5806                                }
5807                            }
5808                        }
5809                    }
5810                }
5811            }
5812
5813            // grant unprotected <provider> read/write, if not blocked by
5814            // <path-permission> above
5815            if (allowDefaultRead) readMet = true;
5816            if (allowDefaultWrite) writeMet = true;
5817
5818        } catch (RemoteException e) {
5819            return false;
5820        }
5821
5822        return readMet && writeMet;
5823    }
5824
5825    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5826        ProviderInfo pi = null;
5827        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5828        if (cpr != null) {
5829            pi = cpr.info;
5830        } else {
5831            try {
5832                pi = AppGlobals.getPackageManager().resolveContentProvider(
5833                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5834            } catch (RemoteException ex) {
5835            }
5836        }
5837        return pi;
5838    }
5839
5840    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5841        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5842        if (targetUris != null) {
5843            return targetUris.get(uri);
5844        } else {
5845            return null;
5846        }
5847    }
5848
5849    private UriPermission findOrCreateUriPermissionLocked(
5850            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5851        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5852        if (targetUris == null) {
5853            targetUris = Maps.newArrayMap();
5854            mGrantedUriPermissions.put(targetUid, targetUris);
5855        }
5856
5857        UriPermission perm = targetUris.get(uri);
5858        if (perm == null) {
5859            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5860            targetUris.put(uri, perm);
5861        }
5862
5863        return perm;
5864    }
5865
5866    private final boolean checkUriPermissionLocked(
5867            Uri uri, int uid, int modeFlags, int minStrength) {
5868        // Root gets to do everything.
5869        if (uid == 0) {
5870            return true;
5871        }
5872        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5873        if (perms == null) return false;
5874        UriPermission perm = perms.get(uri);
5875        if (perm == null) return false;
5876        return perm.getStrength(modeFlags) >= minStrength;
5877    }
5878
5879    @Override
5880    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5881        enforceNotIsolatedCaller("checkUriPermission");
5882
5883        // Another redirected-binder-call permissions check as in
5884        // {@link checkComponentPermission}.
5885        Identity tlsIdentity = sCallerIdentity.get();
5886        if (tlsIdentity != null) {
5887            uid = tlsIdentity.uid;
5888            pid = tlsIdentity.pid;
5889        }
5890
5891        // Our own process gets to do everything.
5892        if (pid == MY_PID) {
5893            return PackageManager.PERMISSION_GRANTED;
5894        }
5895        synchronized(this) {
5896            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5897                    ? PackageManager.PERMISSION_GRANTED
5898                    : PackageManager.PERMISSION_DENIED;
5899        }
5900    }
5901
5902    /**
5903     * Check if the targetPkg can be granted permission to access uri by
5904     * the callingUid using the given modeFlags.  Throws a security exception
5905     * if callingUid is not allowed to do this.  Returns the uid of the target
5906     * if the URI permission grant should be performed; returns -1 if it is not
5907     * needed (for example targetPkg already has permission to access the URI).
5908     * If you already know the uid of the target, you can supply it in
5909     * lastTargetUid else set that to -1.
5910     */
5911    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5912            Uri uri, int modeFlags, int lastTargetUid) {
5913        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5914        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5915                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5916        if (modeFlags == 0) {
5917            return -1;
5918        }
5919
5920        if (targetPkg != null) {
5921            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5922                    "Checking grant " + targetPkg + " permission to " + uri);
5923        }
5924
5925        final IPackageManager pm = AppGlobals.getPackageManager();
5926
5927        // If this is not a content: uri, we can't do anything with it.
5928        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5929            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5930                    "Can't grant URI permission for non-content URI: " + uri);
5931            return -1;
5932        }
5933
5934        final String authority = uri.getAuthority();
5935        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5936        if (pi == null) {
5937            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5938            return -1;
5939        }
5940
5941        int targetUid = lastTargetUid;
5942        if (targetUid < 0 && targetPkg != null) {
5943            try {
5944                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5945                if (targetUid < 0) {
5946                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5947                            "Can't grant URI permission no uid for: " + targetPkg);
5948                    return -1;
5949                }
5950            } catch (RemoteException ex) {
5951                return -1;
5952            }
5953        }
5954
5955        if (targetUid >= 0) {
5956            // First...  does the target actually need this permission?
5957            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5958                // No need to grant the target this permission.
5959                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5960                        "Target " + targetPkg + " already has full permission to " + uri);
5961                return -1;
5962            }
5963        } else {
5964            // First...  there is no target package, so can anyone access it?
5965            boolean allowed = pi.exported;
5966            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5967                if (pi.readPermission != null) {
5968                    allowed = false;
5969                }
5970            }
5971            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5972                if (pi.writePermission != null) {
5973                    allowed = false;
5974                }
5975            }
5976            if (allowed) {
5977                return -1;
5978            }
5979        }
5980
5981        // Second...  is the provider allowing granting of URI permissions?
5982        if (!pi.grantUriPermissions) {
5983            throw new SecurityException("Provider " + pi.packageName
5984                    + "/" + pi.name
5985                    + " does not allow granting of Uri permissions (uri "
5986                    + uri + ")");
5987        }
5988        if (pi.uriPermissionPatterns != null) {
5989            final int N = pi.uriPermissionPatterns.length;
5990            boolean allowed = false;
5991            for (int i=0; i<N; i++) {
5992                if (pi.uriPermissionPatterns[i] != null
5993                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5994                    allowed = true;
5995                    break;
5996                }
5997            }
5998            if (!allowed) {
5999                throw new SecurityException("Provider " + pi.packageName
6000                        + "/" + pi.name
6001                        + " does not allow granting of permission to path of Uri "
6002                        + uri);
6003            }
6004        }
6005
6006        // Third...  does the caller itself have permission to access
6007        // this uri?
6008        if (callingUid != Process.myUid()) {
6009            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6010                // Require they hold a strong enough Uri permission
6011                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6012                        : UriPermission.STRENGTH_OWNED;
6013                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6014                    throw new SecurityException("Uid " + callingUid
6015                            + " does not have permission to uri " + uri);
6016                }
6017            }
6018        }
6019
6020        return targetUid;
6021    }
6022
6023    @Override
6024    public int checkGrantUriPermission(int callingUid, String targetPkg,
6025            Uri uri, int modeFlags) {
6026        enforceNotIsolatedCaller("checkGrantUriPermission");
6027        synchronized(this) {
6028            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6029        }
6030    }
6031
6032    void grantUriPermissionUncheckedLocked(
6033            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6034        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6035        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6036                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6037        if (modeFlags == 0) {
6038            return;
6039        }
6040
6041        // So here we are: the caller has the assumed permission
6042        // to the uri, and the target doesn't.  Let's now give this to
6043        // the target.
6044
6045        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6046                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6047
6048        final String authority = uri.getAuthority();
6049        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6050        if (pi == null) {
6051            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6052            return;
6053        }
6054
6055        final UriPermission perm = findOrCreateUriPermissionLocked(
6056                pi.packageName, targetPkg, targetUid, uri);
6057        perm.grantModes(modeFlags, persistable, owner);
6058    }
6059
6060    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6061            int modeFlags, UriPermissionOwner owner) {
6062        if (targetPkg == null) {
6063            throw new NullPointerException("targetPkg");
6064        }
6065
6066        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6067        if (targetUid < 0) {
6068            return;
6069        }
6070
6071        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6072    }
6073
6074    static class NeededUriGrants extends ArrayList<Uri> {
6075        final String targetPkg;
6076        final int targetUid;
6077        final int flags;
6078
6079        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6080            this.targetPkg = targetPkg;
6081            this.targetUid = targetUid;
6082            this.flags = flags;
6083        }
6084    }
6085
6086    /**
6087     * Like checkGrantUriPermissionLocked, but takes an Intent.
6088     */
6089    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6090            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6091        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6092                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6093                + " clip=" + (intent != null ? intent.getClipData() : null)
6094                + " from " + intent + "; flags=0x"
6095                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6096
6097        if (targetPkg == null) {
6098            throw new NullPointerException("targetPkg");
6099        }
6100
6101        if (intent == null) {
6102            return null;
6103        }
6104        Uri data = intent.getData();
6105        ClipData clip = intent.getClipData();
6106        if (data == null && clip == null) {
6107            return null;
6108        }
6109
6110        if (data != null) {
6111            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6112                mode, needed != null ? needed.targetUid : -1);
6113            if (targetUid > 0) {
6114                if (needed == null) {
6115                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6116                }
6117                needed.add(data);
6118            }
6119        }
6120        if (clip != null) {
6121            for (int i=0; i<clip.getItemCount(); i++) {
6122                Uri uri = clip.getItemAt(i).getUri();
6123                if (uri != null) {
6124                    int targetUid = -1;
6125                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6126                            mode, needed != null ? needed.targetUid : -1);
6127                    if (targetUid > 0) {
6128                        if (needed == null) {
6129                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6130                        }
6131                        needed.add(uri);
6132                    }
6133                } else {
6134                    Intent clipIntent = clip.getItemAt(i).getIntent();
6135                    if (clipIntent != null) {
6136                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6137                                callingUid, targetPkg, clipIntent, mode, needed);
6138                        if (newNeeded != null) {
6139                            needed = newNeeded;
6140                        }
6141                    }
6142                }
6143            }
6144        }
6145
6146        return needed;
6147    }
6148
6149    /**
6150     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6151     */
6152    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6153            UriPermissionOwner owner) {
6154        if (needed != null) {
6155            for (int i=0; i<needed.size(); i++) {
6156                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6157                        needed.get(i), needed.flags, owner);
6158            }
6159        }
6160    }
6161
6162    void grantUriPermissionFromIntentLocked(int callingUid,
6163            String targetPkg, Intent intent, UriPermissionOwner owner) {
6164        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6165                intent, intent != null ? intent.getFlags() : 0, null);
6166        if (needed == null) {
6167            return;
6168        }
6169
6170        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6171    }
6172
6173    @Override
6174    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6175            Uri uri, int modeFlags) {
6176        enforceNotIsolatedCaller("grantUriPermission");
6177        synchronized(this) {
6178            final ProcessRecord r = getRecordForAppLocked(caller);
6179            if (r == null) {
6180                throw new SecurityException("Unable to find app for caller "
6181                        + caller
6182                        + " when granting permission to uri " + uri);
6183            }
6184            if (targetPkg == null) {
6185                throw new IllegalArgumentException("null target");
6186            }
6187            if (uri == null) {
6188                throw new IllegalArgumentException("null uri");
6189            }
6190
6191            // Persistable only supported through Intents
6192            Preconditions.checkFlagsArgument(modeFlags,
6193                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6194
6195            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6196                    null);
6197        }
6198    }
6199
6200    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6201        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6202                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6203            ArrayMap<Uri, UriPermission> perms
6204                    = mGrantedUriPermissions.get(perm.targetUid);
6205            if (perms != null) {
6206                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6207                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6208                perms.remove(perm.uri);
6209                if (perms.size() == 0) {
6210                    mGrantedUriPermissions.remove(perm.targetUid);
6211                }
6212            }
6213        }
6214    }
6215
6216    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6217        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6218
6219        final IPackageManager pm = AppGlobals.getPackageManager();
6220        final String authority = uri.getAuthority();
6221        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6222        if (pi == null) {
6223            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6224            return;
6225        }
6226
6227        // Does the caller have this permission on the URI?
6228        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6229            // Right now, if you are not the original owner of the permission,
6230            // you are not allowed to revoke it.
6231            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6232                throw new SecurityException("Uid " + callingUid
6233                        + " does not have permission to uri " + uri);
6234            //}
6235        }
6236
6237        boolean persistChanged = false;
6238
6239        // Go through all of the permissions and remove any that match.
6240        final List<String> SEGMENTS = uri.getPathSegments();
6241        if (SEGMENTS != null) {
6242            final int NS = SEGMENTS.size();
6243            int N = mGrantedUriPermissions.size();
6244            for (int i=0; i<N; i++) {
6245                ArrayMap<Uri, UriPermission> perms
6246                        = mGrantedUriPermissions.valueAt(i);
6247                Iterator<UriPermission> it = perms.values().iterator();
6248            toploop:
6249                while (it.hasNext()) {
6250                    UriPermission perm = it.next();
6251                    Uri targetUri = perm.uri;
6252                    if (!authority.equals(targetUri.getAuthority())) {
6253                        continue;
6254                    }
6255                    List<String> targetSegments = targetUri.getPathSegments();
6256                    if (targetSegments == null) {
6257                        continue;
6258                    }
6259                    if (targetSegments.size() < NS) {
6260                        continue;
6261                    }
6262                    for (int j=0; j<NS; j++) {
6263                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6264                            continue toploop;
6265                        }
6266                    }
6267                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6268                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6269                    persistChanged |= perm.clearModes(modeFlags, true);
6270                    if (perm.modeFlags == 0) {
6271                        it.remove();
6272                    }
6273                }
6274                if (perms.size() == 0) {
6275                    mGrantedUriPermissions.remove(
6276                            mGrantedUriPermissions.keyAt(i));
6277                    N--;
6278                    i--;
6279                }
6280            }
6281        }
6282
6283        if (persistChanged) {
6284            schedulePersistUriGrants();
6285        }
6286    }
6287
6288    @Override
6289    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6290            int modeFlags) {
6291        enforceNotIsolatedCaller("revokeUriPermission");
6292        synchronized(this) {
6293            final ProcessRecord r = getRecordForAppLocked(caller);
6294            if (r == null) {
6295                throw new SecurityException("Unable to find app for caller "
6296                        + caller
6297                        + " when revoking permission to uri " + uri);
6298            }
6299            if (uri == null) {
6300                Slog.w(TAG, "revokeUriPermission: null uri");
6301                return;
6302            }
6303
6304            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6305                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6306            if (modeFlags == 0) {
6307                return;
6308            }
6309
6310            final IPackageManager pm = AppGlobals.getPackageManager();
6311            final String authority = uri.getAuthority();
6312            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6313            if (pi == null) {
6314                Slog.w(TAG, "No content provider found for permission revoke: "
6315                        + uri.toSafeString());
6316                return;
6317            }
6318
6319            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6320        }
6321    }
6322
6323    /**
6324     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6325     * given package.
6326     *
6327     * @param packageName Package name to match, or {@code null} to apply to all
6328     *            packages.
6329     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6330     *            to all users.
6331     * @param persistable If persistable grants should be removed.
6332     */
6333    private void removeUriPermissionsForPackageLocked(
6334            String packageName, int userHandle, boolean persistable) {
6335        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6336            throw new IllegalArgumentException("Must narrow by either package or user");
6337        }
6338
6339        boolean persistChanged = false;
6340
6341        final int size = mGrantedUriPermissions.size();
6342        for (int i = 0; i < size; i++) {
6343            // Only inspect grants matching user
6344            if (userHandle == UserHandle.USER_ALL
6345                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6346                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6347                        .values().iterator();
6348                while (it.hasNext()) {
6349                    final UriPermission perm = it.next();
6350
6351                    // Only inspect grants matching package
6352                    if (packageName == null || perm.sourcePkg.equals(packageName)
6353                            || perm.targetPkg.equals(packageName)) {
6354                        persistChanged |= perm.clearModes(~0, persistable);
6355
6356                        // Only remove when no modes remain; any persisted grants
6357                        // will keep this alive.
6358                        if (perm.modeFlags == 0) {
6359                            it.remove();
6360                        }
6361                    }
6362                }
6363            }
6364        }
6365
6366        if (persistChanged) {
6367            schedulePersistUriGrants();
6368        }
6369    }
6370
6371    @Override
6372    public IBinder newUriPermissionOwner(String name) {
6373        enforceNotIsolatedCaller("newUriPermissionOwner");
6374        synchronized(this) {
6375            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6376            return owner.getExternalTokenLocked();
6377        }
6378    }
6379
6380    @Override
6381    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6382            Uri uri, int modeFlags) {
6383        synchronized(this) {
6384            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6385            if (owner == null) {
6386                throw new IllegalArgumentException("Unknown owner: " + token);
6387            }
6388            if (fromUid != Binder.getCallingUid()) {
6389                if (Binder.getCallingUid() != Process.myUid()) {
6390                    // Only system code can grant URI permissions on behalf
6391                    // of other users.
6392                    throw new SecurityException("nice try");
6393                }
6394            }
6395            if (targetPkg == null) {
6396                throw new IllegalArgumentException("null target");
6397            }
6398            if (uri == null) {
6399                throw new IllegalArgumentException("null uri");
6400            }
6401
6402            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6403        }
6404    }
6405
6406    @Override
6407    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6408        synchronized(this) {
6409            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6410            if (owner == null) {
6411                throw new IllegalArgumentException("Unknown owner: " + token);
6412            }
6413
6414            if (uri == null) {
6415                owner.removeUriPermissionsLocked(mode);
6416            } else {
6417                owner.removeUriPermissionLocked(uri, mode);
6418            }
6419        }
6420    }
6421
6422    private void schedulePersistUriGrants() {
6423        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6424            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6425                    10 * DateUtils.SECOND_IN_MILLIS);
6426        }
6427    }
6428
6429    private void writeGrantedUriPermissions() {
6430        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6431
6432        // Snapshot permissions so we can persist without lock
6433        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6434        synchronized (this) {
6435            final int size = mGrantedUriPermissions.size();
6436            for (int i = 0 ; i < size; i++) {
6437                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6438                    if (perm.persistedModeFlags != 0) {
6439                        persist.add(perm.snapshot());
6440                    }
6441                }
6442            }
6443        }
6444
6445        FileOutputStream fos = null;
6446        try {
6447            fos = mGrantFile.startWrite();
6448
6449            XmlSerializer out = new FastXmlSerializer();
6450            out.setOutput(fos, "utf-8");
6451            out.startDocument(null, true);
6452            out.startTag(null, TAG_URI_GRANTS);
6453            for (UriPermission.Snapshot perm : persist) {
6454                out.startTag(null, TAG_URI_GRANT);
6455                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6456                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6457                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6458                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6459                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6460                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6461                out.endTag(null, TAG_URI_GRANT);
6462            }
6463            out.endTag(null, TAG_URI_GRANTS);
6464            out.endDocument();
6465
6466            mGrantFile.finishWrite(fos);
6467        } catch (IOException e) {
6468            if (fos != null) {
6469                mGrantFile.failWrite(fos);
6470            }
6471        }
6472    }
6473
6474    private void readGrantedUriPermissionsLocked() {
6475        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6476
6477        final long now = System.currentTimeMillis();
6478
6479        FileInputStream fis = null;
6480        try {
6481            fis = mGrantFile.openRead();
6482            final XmlPullParser in = Xml.newPullParser();
6483            in.setInput(fis, null);
6484
6485            int type;
6486            while ((type = in.next()) != END_DOCUMENT) {
6487                final String tag = in.getName();
6488                if (type == START_TAG) {
6489                    if (TAG_URI_GRANT.equals(tag)) {
6490                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6491                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6492                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6493                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6494                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6495                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6496
6497                        // Sanity check that provider still belongs to source package
6498                        final ProviderInfo pi = getProviderInfoLocked(
6499                                uri.getAuthority(), userHandle);
6500                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6501                            int targetUid = -1;
6502                            try {
6503                                targetUid = AppGlobals.getPackageManager()
6504                                        .getPackageUid(targetPkg, userHandle);
6505                            } catch (RemoteException e) {
6506                            }
6507                            if (targetUid != -1) {
6508                                final UriPermission perm = findOrCreateUriPermissionLocked(
6509                                        sourcePkg, targetPkg, targetUid, uri);
6510                                perm.initPersistedModes(modeFlags, createdTime);
6511                            }
6512                        } else {
6513                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6514                                    + " but instead found " + pi);
6515                        }
6516                    }
6517                }
6518            }
6519        } catch (FileNotFoundException e) {
6520            // Missing grants is okay
6521        } catch (IOException e) {
6522            Log.wtf(TAG, "Failed reading Uri grants", e);
6523        } catch (XmlPullParserException e) {
6524            Log.wtf(TAG, "Failed reading Uri grants", e);
6525        } finally {
6526            IoUtils.closeQuietly(fis);
6527        }
6528    }
6529
6530    @Override
6531    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6532        enforceNotIsolatedCaller("takePersistableUriPermission");
6533
6534        Preconditions.checkFlagsArgument(modeFlags,
6535                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6536
6537        synchronized (this) {
6538            final int callingUid = Binder.getCallingUid();
6539            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6540            if (perm == null) {
6541                throw new SecurityException("No permission grant found for UID " + callingUid
6542                        + " and Uri " + uri.toSafeString());
6543            }
6544
6545            boolean persistChanged = perm.takePersistableModes(modeFlags);
6546            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6547
6548            if (persistChanged) {
6549                schedulePersistUriGrants();
6550            }
6551        }
6552    }
6553
6554    @Override
6555    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6556        enforceNotIsolatedCaller("releasePersistableUriPermission");
6557
6558        Preconditions.checkFlagsArgument(modeFlags,
6559                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6560
6561        synchronized (this) {
6562            final int callingUid = Binder.getCallingUid();
6563
6564            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6565            if (perm == null) {
6566                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6567                        + uri.toSafeString());
6568                return;
6569            }
6570
6571            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6572            removeUriPermissionIfNeededLocked(perm);
6573            if (persistChanged) {
6574                schedulePersistUriGrants();
6575            }
6576        }
6577    }
6578
6579    /**
6580     * Prune any older {@link UriPermission} for the given UID until outstanding
6581     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6582     *
6583     * @return if any mutations occured that require persisting.
6584     */
6585    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6586        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6587        if (perms == null) return false;
6588        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6589
6590        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6591        for (UriPermission perm : perms.values()) {
6592            if (perm.persistedModeFlags != 0) {
6593                persisted.add(perm);
6594            }
6595        }
6596
6597        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6598        if (trimCount <= 0) return false;
6599
6600        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6601        for (int i = 0; i < trimCount; i++) {
6602            final UriPermission perm = persisted.get(i);
6603
6604            if (DEBUG_URI_PERMISSION) {
6605                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6606            }
6607
6608            perm.releasePersistableModes(~0);
6609            removeUriPermissionIfNeededLocked(perm);
6610        }
6611
6612        return true;
6613    }
6614
6615    @Override
6616    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6617            String packageName, boolean incoming) {
6618        enforceNotIsolatedCaller("getPersistedUriPermissions");
6619        Preconditions.checkNotNull(packageName, "packageName");
6620
6621        final int callingUid = Binder.getCallingUid();
6622        final IPackageManager pm = AppGlobals.getPackageManager();
6623        try {
6624            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6625            if (packageUid != callingUid) {
6626                throw new SecurityException(
6627                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6628            }
6629        } catch (RemoteException e) {
6630            throw new SecurityException("Failed to verify package name ownership");
6631        }
6632
6633        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6634        synchronized (this) {
6635            if (incoming) {
6636                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6637                if (perms == null) {
6638                    Slog.w(TAG, "No permission grants found for " + packageName);
6639                } else {
6640                    final int size = perms.size();
6641                    for (int i = 0; i < size; i++) {
6642                        final UriPermission perm = perms.valueAt(i);
6643                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6644                            result.add(perm.buildPersistedPublicApiObject());
6645                        }
6646                    }
6647                }
6648            } else {
6649                final int size = mGrantedUriPermissions.size();
6650                for (int i = 0; i < size; i++) {
6651                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6652                    final int permsSize = perms.size();
6653                    for (int j = 0; j < permsSize; j++) {
6654                        final UriPermission perm = perms.valueAt(j);
6655                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6656                            result.add(perm.buildPersistedPublicApiObject());
6657                        }
6658                    }
6659                }
6660            }
6661        }
6662        return new ParceledListSlice<android.content.UriPermission>(result);
6663    }
6664
6665    @Override
6666    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6667        synchronized (this) {
6668            ProcessRecord app =
6669                who != null ? getRecordForAppLocked(who) : null;
6670            if (app == null) return;
6671
6672            Message msg = Message.obtain();
6673            msg.what = WAIT_FOR_DEBUGGER_MSG;
6674            msg.obj = app;
6675            msg.arg1 = waiting ? 1 : 0;
6676            mHandler.sendMessage(msg);
6677        }
6678    }
6679
6680    @Override
6681    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6682        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6683        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6684        outInfo.availMem = Process.getFreeMemory();
6685        outInfo.totalMem = Process.getTotalMemory();
6686        outInfo.threshold = homeAppMem;
6687        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6688        outInfo.hiddenAppThreshold = cachedAppMem;
6689        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6690                ProcessList.SERVICE_ADJ);
6691        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6692                ProcessList.VISIBLE_APP_ADJ);
6693        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6694                ProcessList.FOREGROUND_APP_ADJ);
6695    }
6696
6697    // =========================================================
6698    // TASK MANAGEMENT
6699    // =========================================================
6700
6701    @Override
6702    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6703                         IThumbnailReceiver receiver) {
6704        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6705
6706        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6707        ActivityRecord topRecord = null;
6708
6709        synchronized(this) {
6710            if (localLOGV) Slog.v(
6711                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6712                + ", receiver=" + receiver);
6713
6714            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6715                    != PackageManager.PERMISSION_GRANTED) {
6716                if (receiver != null) {
6717                    // If the caller wants to wait for pending thumbnails,
6718                    // it ain't gonna get them.
6719                    try {
6720                        receiver.finished();
6721                    } catch (RemoteException ex) {
6722                    }
6723                }
6724                String msg = "Permission Denial: getTasks() from pid="
6725                        + Binder.getCallingPid()
6726                        + ", uid=" + Binder.getCallingUid()
6727                        + " requires " + android.Manifest.permission.GET_TASKS;
6728                Slog.w(TAG, msg);
6729                throw new SecurityException(msg);
6730            }
6731
6732            // TODO: Improve with MRU list from all ActivityStacks.
6733            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6734
6735            if (!pending.pendingRecords.isEmpty()) {
6736                mPendingThumbnails.add(pending);
6737            }
6738        }
6739
6740        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6741
6742        if (topRecord != null) {
6743            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6744            try {
6745                IApplicationThread topThumbnail = topRecord.app.thread;
6746                topThumbnail.requestThumbnail(topRecord.appToken);
6747            } catch (Exception e) {
6748                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6749                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6750            }
6751        }
6752
6753        if (pending == null && receiver != null) {
6754            // In this case all thumbnails were available and the client
6755            // is being asked to be told when the remaining ones come in...
6756            // which is unusually, since the top-most currently running
6757            // activity should never have a canned thumbnail!  Oh well.
6758            try {
6759                receiver.finished();
6760            } catch (RemoteException ex) {
6761            }
6762        }
6763
6764        return list;
6765    }
6766
6767    TaskRecord getMostRecentTask() {
6768        return mRecentTasks.get(0);
6769    }
6770
6771    @Override
6772    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6773            int flags, int userId) {
6774        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6775                false, true, "getRecentTasks", null);
6776
6777        synchronized (this) {
6778            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6779                    "getRecentTasks()");
6780            final boolean detailed = checkCallingPermission(
6781                    android.Manifest.permission.GET_DETAILED_TASKS)
6782                    == PackageManager.PERMISSION_GRANTED;
6783
6784            IPackageManager pm = AppGlobals.getPackageManager();
6785
6786            final int N = mRecentTasks.size();
6787            ArrayList<ActivityManager.RecentTaskInfo> res
6788                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6789                            maxNum < N ? maxNum : N);
6790            for (int i=0; i<N && maxNum > 0; i++) {
6791                TaskRecord tr = mRecentTasks.get(i);
6792                // Only add calling user's recent tasks
6793                if (tr.userId != userId) continue;
6794                // Return the entry if desired by the caller.  We always return
6795                // the first entry, because callers always expect this to be the
6796                // foreground app.  We may filter others if the caller has
6797                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6798                // we should exclude the entry.
6799
6800                if (i == 0
6801                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6802                        || (tr.intent == null)
6803                        || ((tr.intent.getFlags()
6804                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6805                    ActivityManager.RecentTaskInfo rti
6806                            = new ActivityManager.RecentTaskInfo();
6807                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6808                    rti.persistentId = tr.taskId;
6809                    rti.baseIntent = new Intent(
6810                            tr.intent != null ? tr.intent : tr.affinityIntent);
6811                    if (!detailed) {
6812                        rti.baseIntent.replaceExtras((Bundle)null);
6813                    }
6814                    rti.origActivity = tr.origActivity;
6815                    rti.description = tr.lastDescription;
6816                    rti.stackId = tr.stack.mStackId;
6817
6818                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6819                        // Check whether this activity is currently available.
6820                        try {
6821                            if (rti.origActivity != null) {
6822                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6823                                        == null) {
6824                                    continue;
6825                                }
6826                            } else if (rti.baseIntent != null) {
6827                                if (pm.queryIntentActivities(rti.baseIntent,
6828                                        null, 0, userId) == null) {
6829                                    continue;
6830                                }
6831                            }
6832                        } catch (RemoteException e) {
6833                            // Will never happen.
6834                        }
6835                    }
6836
6837                    res.add(rti);
6838                    maxNum--;
6839                }
6840            }
6841            return res;
6842        }
6843    }
6844
6845    private TaskRecord recentTaskForIdLocked(int id) {
6846        final int N = mRecentTasks.size();
6847            for (int i=0; i<N; i++) {
6848                TaskRecord tr = mRecentTasks.get(i);
6849                if (tr.taskId == id) {
6850                    return tr;
6851                }
6852            }
6853            return null;
6854    }
6855
6856    @Override
6857    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6858        synchronized (this) {
6859            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6860                    "getTaskThumbnails()");
6861            TaskRecord tr = recentTaskForIdLocked(id);
6862            if (tr != null) {
6863                return tr.getTaskThumbnailsLocked();
6864            }
6865        }
6866        return null;
6867    }
6868
6869    @Override
6870    public Bitmap getTaskTopThumbnail(int id) {
6871        synchronized (this) {
6872            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6873                    "getTaskTopThumbnail()");
6874            TaskRecord tr = recentTaskForIdLocked(id);
6875            if (tr != null) {
6876                return tr.getTaskTopThumbnailLocked();
6877            }
6878        }
6879        return null;
6880    }
6881
6882    @Override
6883    public boolean removeSubTask(int taskId, int subTaskIndex) {
6884        synchronized (this) {
6885            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6886                    "removeSubTask()");
6887            long ident = Binder.clearCallingIdentity();
6888            try {
6889                TaskRecord tr = recentTaskForIdLocked(taskId);
6890                if (tr != null) {
6891                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6892                }
6893                return false;
6894            } finally {
6895                Binder.restoreCallingIdentity(ident);
6896            }
6897        }
6898    }
6899
6900    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6901        if (!pr.killedByAm) {
6902            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6903            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6904                    pr.processName, pr.setAdj, reason);
6905            pr.killedByAm = true;
6906            Process.killProcessQuiet(pr.pid);
6907        }
6908    }
6909
6910    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6911        tr.disposeThumbnail();
6912        mRecentTasks.remove(tr);
6913        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6914        Intent baseIntent = new Intent(
6915                tr.intent != null ? tr.intent : tr.affinityIntent);
6916        ComponentName component = baseIntent.getComponent();
6917        if (component == null) {
6918            Slog.w(TAG, "Now component for base intent of task: " + tr);
6919            return;
6920        }
6921
6922        // Find any running services associated with this app.
6923        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6924
6925        if (killProcesses) {
6926            // Find any running processes associated with this app.
6927            final String pkg = component.getPackageName();
6928            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6929            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6930            for (int i=0; i<pmap.size(); i++) {
6931                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6932                for (int j=0; j<uids.size(); j++) {
6933                    ProcessRecord proc = uids.valueAt(j);
6934                    if (proc.userId != tr.userId) {
6935                        continue;
6936                    }
6937                    if (!proc.pkgList.containsKey(pkg)) {
6938                        continue;
6939                    }
6940                    procs.add(proc);
6941                }
6942            }
6943
6944            // Kill the running processes.
6945            for (int i=0; i<procs.size(); i++) {
6946                ProcessRecord pr = procs.get(i);
6947                if (pr == mHomeProcess) {
6948                    // Don't kill the home process along with tasks from the same package.
6949                    continue;
6950                }
6951                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6952                    killUnneededProcessLocked(pr, "remove task");
6953                } else {
6954                    pr.waitingToKill = "remove task";
6955                }
6956            }
6957        }
6958    }
6959
6960    @Override
6961    public boolean removeTask(int taskId, int flags) {
6962        synchronized (this) {
6963            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6964                    "removeTask()");
6965            long ident = Binder.clearCallingIdentity();
6966            try {
6967                TaskRecord tr = recentTaskForIdLocked(taskId);
6968                if (tr != null) {
6969                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6970                    if (r != null) {
6971                        cleanUpRemovedTaskLocked(tr, flags);
6972                        return true;
6973                    }
6974                    if (tr.mActivities.size() == 0) {
6975                        // Caller is just removing a recent task that is
6976                        // not actively running.  That is easy!
6977                        cleanUpRemovedTaskLocked(tr, flags);
6978                        return true;
6979                    }
6980                    Slog.w(TAG, "removeTask: task " + taskId
6981                            + " does not have activities to remove, "
6982                            + " but numActivities=" + tr.numActivities
6983                            + ": " + tr);
6984                }
6985            } finally {
6986                Binder.restoreCallingIdentity(ident);
6987            }
6988        }
6989        return false;
6990    }
6991
6992    /**
6993     * TODO: Add mController hook
6994     */
6995    @Override
6996    public void moveTaskToFront(int task, int flags, Bundle options) {
6997        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6998                "moveTaskToFront()");
6999
7000        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
7001        synchronized(this) {
7002            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7003                    Binder.getCallingUid(), "Task to front")) {
7004                ActivityOptions.abort(options);
7005                return;
7006            }
7007            final long origId = Binder.clearCallingIdentity();
7008            try {
7009                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7010            } finally {
7011                Binder.restoreCallingIdentity(origId);
7012            }
7013            ActivityOptions.abort(options);
7014        }
7015    }
7016
7017    @Override
7018    public void moveTaskToBack(int taskId) {
7019        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7020                "moveTaskToBack()");
7021
7022        synchronized(this) {
7023            TaskRecord tr = recentTaskForIdLocked(taskId);
7024            if (tr != null) {
7025                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7026                ActivityStack stack = tr.stack;
7027                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7028                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7029                            Binder.getCallingUid(), "Task to back")) {
7030                        return;
7031                    }
7032                }
7033                final long origId = Binder.clearCallingIdentity();
7034                try {
7035                    stack.moveTaskToBackLocked(taskId, null);
7036                } finally {
7037                    Binder.restoreCallingIdentity(origId);
7038                }
7039            }
7040        }
7041    }
7042
7043    /**
7044     * Moves an activity, and all of the other activities within the same task, to the bottom
7045     * of the history stack.  The activity's order within the task is unchanged.
7046     *
7047     * @param token A reference to the activity we wish to move
7048     * @param nonRoot If false then this only works if the activity is the root
7049     *                of a task; if true it will work for any activity in a task.
7050     * @return Returns true if the move completed, false if not.
7051     */
7052    @Override
7053    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7054        enforceNotIsolatedCaller("moveActivityTaskToBack");
7055        synchronized(this) {
7056            final long origId = Binder.clearCallingIdentity();
7057            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7058            if (taskId >= 0) {
7059                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7060            }
7061            Binder.restoreCallingIdentity(origId);
7062        }
7063        return false;
7064    }
7065
7066    @Override
7067    public void moveTaskBackwards(int task) {
7068        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7069                "moveTaskBackwards()");
7070
7071        synchronized(this) {
7072            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7073                    Binder.getCallingUid(), "Task backwards")) {
7074                return;
7075            }
7076            final long origId = Binder.clearCallingIdentity();
7077            moveTaskBackwardsLocked(task);
7078            Binder.restoreCallingIdentity(origId);
7079        }
7080    }
7081
7082    private final void moveTaskBackwardsLocked(int task) {
7083        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7084    }
7085
7086    @Override
7087    public IBinder getHomeActivityToken() throws RemoteException {
7088        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7089                "getHomeActivityToken()");
7090        synchronized (this) {
7091            return mStackSupervisor.getHomeActivityToken();
7092        }
7093    }
7094
7095    @Override
7096    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7097            IActivityContainerCallback callback) throws RemoteException {
7098        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7099                "createActivityContainer()");
7100        synchronized (this) {
7101            if (parentActivityToken == null) {
7102                throw new IllegalArgumentException("parent token must not be null");
7103            }
7104            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7105            if (r == null) {
7106                return null;
7107            }
7108            return mStackSupervisor.createActivityContainer(r, callback);
7109        }
7110    }
7111
7112    @Override
7113    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7114        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7115                "deleteActivityContainer()");
7116        synchronized (this) {
7117            mStackSupervisor.deleteActivityContainer(container);
7118        }
7119    }
7120
7121    @Override
7122    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7123            throws RemoteException {
7124        synchronized (this) {
7125            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7126            if (stack != null) {
7127                return stack.mActivityContainer;
7128            }
7129            return null;
7130        }
7131    }
7132
7133    @Override
7134    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7135        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7136                "moveTaskToStack()");
7137        if (stackId == HOME_STACK_ID) {
7138            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7139                    new RuntimeException("here").fillInStackTrace());
7140        }
7141        synchronized (this) {
7142            long ident = Binder.clearCallingIdentity();
7143            try {
7144                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7145                        + stackId + " toTop=" + toTop);
7146                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7147            } finally {
7148                Binder.restoreCallingIdentity(ident);
7149            }
7150        }
7151    }
7152
7153    @Override
7154    public void resizeStack(int stackBoxId, Rect bounds) {
7155        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7156                "resizeStackBox()");
7157        long ident = Binder.clearCallingIdentity();
7158        try {
7159            mWindowManager.resizeStack(stackBoxId, bounds);
7160        } finally {
7161            Binder.restoreCallingIdentity(ident);
7162        }
7163    }
7164
7165    @Override
7166    public List<StackInfo> getAllStackInfos() {
7167        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7168                "getAllStackInfos()");
7169        long ident = Binder.clearCallingIdentity();
7170        try {
7171            synchronized (this) {
7172                return mStackSupervisor.getAllStackInfosLocked();
7173            }
7174        } finally {
7175            Binder.restoreCallingIdentity(ident);
7176        }
7177    }
7178
7179    @Override
7180    public StackInfo getStackInfo(int stackId) {
7181        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7182                "getStackInfo()");
7183        long ident = Binder.clearCallingIdentity();
7184        try {
7185            synchronized (this) {
7186                return mStackSupervisor.getStackInfoLocked(stackId);
7187            }
7188        } finally {
7189            Binder.restoreCallingIdentity(ident);
7190        }
7191    }
7192
7193    @Override
7194    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7195        synchronized(this) {
7196            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7197        }
7198    }
7199
7200    // =========================================================
7201    // THUMBNAILS
7202    // =========================================================
7203
7204    public void reportThumbnail(IBinder token,
7205            Bitmap thumbnail, CharSequence description) {
7206        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7207        final long origId = Binder.clearCallingIdentity();
7208        sendPendingThumbnail(null, token, thumbnail, description, true);
7209        Binder.restoreCallingIdentity(origId);
7210    }
7211
7212    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7213            Bitmap thumbnail, CharSequence description, boolean always) {
7214        TaskRecord task;
7215        ArrayList<PendingThumbnailsRecord> receivers = null;
7216
7217        //System.out.println("Send pending thumbnail: " + r);
7218
7219        synchronized(this) {
7220            if (r == null) {
7221                r = ActivityRecord.isInStackLocked(token);
7222                if (r == null) {
7223                    return;
7224                }
7225            }
7226            if (thumbnail == null && r.thumbHolder != null) {
7227                thumbnail = r.thumbHolder.lastThumbnail;
7228                description = r.thumbHolder.lastDescription;
7229            }
7230            if (thumbnail == null && !always) {
7231                // If there is no thumbnail, and this entry is not actually
7232                // going away, then abort for now and pick up the next
7233                // thumbnail we get.
7234                return;
7235            }
7236            task = r.task;
7237
7238            int N = mPendingThumbnails.size();
7239            int i=0;
7240            while (i<N) {
7241                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7242                //System.out.println("Looking in " + pr.pendingRecords);
7243                if (pr.pendingRecords.remove(r)) {
7244                    if (receivers == null) {
7245                        receivers = new ArrayList<PendingThumbnailsRecord>();
7246                    }
7247                    receivers.add(pr);
7248                    if (pr.pendingRecords.size() == 0) {
7249                        pr.finished = true;
7250                        mPendingThumbnails.remove(i);
7251                        N--;
7252                        continue;
7253                    }
7254                }
7255                i++;
7256            }
7257        }
7258
7259        if (receivers != null) {
7260            final int N = receivers.size();
7261            for (int i=0; i<N; i++) {
7262                try {
7263                    PendingThumbnailsRecord pr = receivers.get(i);
7264                    pr.receiver.newThumbnail(
7265                        task != null ? task.taskId : -1, thumbnail, description);
7266                    if (pr.finished) {
7267                        pr.receiver.finished();
7268                    }
7269                } catch (Exception e) {
7270                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7271                }
7272            }
7273        }
7274    }
7275
7276    // =========================================================
7277    // CONTENT PROVIDERS
7278    // =========================================================
7279
7280    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7281        List<ProviderInfo> providers = null;
7282        try {
7283            providers = AppGlobals.getPackageManager().
7284                queryContentProviders(app.processName, app.uid,
7285                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7286        } catch (RemoteException ex) {
7287        }
7288        if (DEBUG_MU)
7289            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7290        int userId = app.userId;
7291        if (providers != null) {
7292            int N = providers.size();
7293            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7294            for (int i=0; i<N; i++) {
7295                ProviderInfo cpi =
7296                    (ProviderInfo)providers.get(i);
7297                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7298                        cpi.name, cpi.flags);
7299                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7300                    // This is a singleton provider, but a user besides the
7301                    // default user is asking to initialize a process it runs
7302                    // in...  well, no, it doesn't actually run in this process,
7303                    // it runs in the process of the default user.  Get rid of it.
7304                    providers.remove(i);
7305                    N--;
7306                    i--;
7307                    continue;
7308                }
7309
7310                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7311                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7312                if (cpr == null) {
7313                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7314                    mProviderMap.putProviderByClass(comp, cpr);
7315                }
7316                if (DEBUG_MU)
7317                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7318                app.pubProviders.put(cpi.name, cpr);
7319                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7320                    // Don't add this if it is a platform component that is marked
7321                    // to run in multiple processes, because this is actually
7322                    // part of the framework so doesn't make sense to track as a
7323                    // separate apk in the process.
7324                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7325                }
7326                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7327            }
7328        }
7329        return providers;
7330    }
7331
7332    /**
7333     * Check if {@link ProcessRecord} has a possible chance at accessing the
7334     * given {@link ProviderInfo}. Final permission checking is always done
7335     * in {@link ContentProvider}.
7336     */
7337    private final String checkContentProviderPermissionLocked(
7338            ProviderInfo cpi, ProcessRecord r) {
7339        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7340        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7341        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7342                cpi.applicationInfo.uid, cpi.exported)
7343                == PackageManager.PERMISSION_GRANTED) {
7344            return null;
7345        }
7346        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7347                cpi.applicationInfo.uid, cpi.exported)
7348                == PackageManager.PERMISSION_GRANTED) {
7349            return null;
7350        }
7351
7352        PathPermission[] pps = cpi.pathPermissions;
7353        if (pps != null) {
7354            int i = pps.length;
7355            while (i > 0) {
7356                i--;
7357                PathPermission pp = pps[i];
7358                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7359                        cpi.applicationInfo.uid, cpi.exported)
7360                        == PackageManager.PERMISSION_GRANTED) {
7361                    return null;
7362                }
7363                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7364                        cpi.applicationInfo.uid, cpi.exported)
7365                        == PackageManager.PERMISSION_GRANTED) {
7366                    return null;
7367                }
7368            }
7369        }
7370
7371        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7372        if (perms != null) {
7373            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7374                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7375                    return null;
7376                }
7377            }
7378        }
7379
7380        String msg;
7381        if (!cpi.exported) {
7382            msg = "Permission Denial: opening provider " + cpi.name
7383                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7384                    + ", uid=" + callingUid + ") that is not exported from uid "
7385                    + cpi.applicationInfo.uid;
7386        } else {
7387            msg = "Permission Denial: opening provider " + cpi.name
7388                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7389                    + ", uid=" + callingUid + ") requires "
7390                    + cpi.readPermission + " or " + cpi.writePermission;
7391        }
7392        Slog.w(TAG, msg);
7393        return msg;
7394    }
7395
7396    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7397            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7398        if (r != null) {
7399            for (int i=0; i<r.conProviders.size(); i++) {
7400                ContentProviderConnection conn = r.conProviders.get(i);
7401                if (conn.provider == cpr) {
7402                    if (DEBUG_PROVIDER) Slog.v(TAG,
7403                            "Adding provider requested by "
7404                            + r.processName + " from process "
7405                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7406                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7407                    if (stable) {
7408                        conn.stableCount++;
7409                        conn.numStableIncs++;
7410                    } else {
7411                        conn.unstableCount++;
7412                        conn.numUnstableIncs++;
7413                    }
7414                    return conn;
7415                }
7416            }
7417            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7418            if (stable) {
7419                conn.stableCount = 1;
7420                conn.numStableIncs = 1;
7421            } else {
7422                conn.unstableCount = 1;
7423                conn.numUnstableIncs = 1;
7424            }
7425            cpr.connections.add(conn);
7426            r.conProviders.add(conn);
7427            return conn;
7428        }
7429        cpr.addExternalProcessHandleLocked(externalProcessToken);
7430        return null;
7431    }
7432
7433    boolean decProviderCountLocked(ContentProviderConnection conn,
7434            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7435        if (conn != null) {
7436            cpr = conn.provider;
7437            if (DEBUG_PROVIDER) Slog.v(TAG,
7438                    "Removing provider requested by "
7439                    + conn.client.processName + " from process "
7440                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7441                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7442            if (stable) {
7443                conn.stableCount--;
7444            } else {
7445                conn.unstableCount--;
7446            }
7447            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7448                cpr.connections.remove(conn);
7449                conn.client.conProviders.remove(conn);
7450                return true;
7451            }
7452            return false;
7453        }
7454        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7455        return false;
7456    }
7457
7458    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7459            String name, IBinder token, boolean stable, int userId) {
7460        ContentProviderRecord cpr;
7461        ContentProviderConnection conn = null;
7462        ProviderInfo cpi = null;
7463
7464        synchronized(this) {
7465            ProcessRecord r = null;
7466            if (caller != null) {
7467                r = getRecordForAppLocked(caller);
7468                if (r == null) {
7469                    throw new SecurityException(
7470                            "Unable to find app for caller " + caller
7471                          + " (pid=" + Binder.getCallingPid()
7472                          + ") when getting content provider " + name);
7473                }
7474            }
7475
7476            // First check if this content provider has been published...
7477            cpr = mProviderMap.getProviderByName(name, userId);
7478            boolean providerRunning = cpr != null;
7479            if (providerRunning) {
7480                cpi = cpr.info;
7481                String msg;
7482                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7483                    throw new SecurityException(msg);
7484                }
7485
7486                if (r != null && cpr.canRunHere(r)) {
7487                    // This provider has been published or is in the process
7488                    // of being published...  but it is also allowed to run
7489                    // in the caller's process, so don't make a connection
7490                    // and just let the caller instantiate its own instance.
7491                    ContentProviderHolder holder = cpr.newHolder(null);
7492                    // don't give caller the provider object, it needs
7493                    // to make its own.
7494                    holder.provider = null;
7495                    return holder;
7496                }
7497
7498                final long origId = Binder.clearCallingIdentity();
7499
7500                // In this case the provider instance already exists, so we can
7501                // return it right away.
7502                conn = incProviderCountLocked(r, cpr, token, stable);
7503                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7504                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7505                        // If this is a perceptible app accessing the provider,
7506                        // make sure to count it as being accessed and thus
7507                        // back up on the LRU list.  This is good because
7508                        // content providers are often expensive to start.
7509                        updateLruProcessLocked(cpr.proc, false, null);
7510                    }
7511                }
7512
7513                if (cpr.proc != null) {
7514                    if (false) {
7515                        if (cpr.name.flattenToShortString().equals(
7516                                "com.android.providers.calendar/.CalendarProvider2")) {
7517                            Slog.v(TAG, "****************** KILLING "
7518                                + cpr.name.flattenToShortString());
7519                            Process.killProcess(cpr.proc.pid);
7520                        }
7521                    }
7522                    boolean success = updateOomAdjLocked(cpr.proc);
7523                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7524                    // NOTE: there is still a race here where a signal could be
7525                    // pending on the process even though we managed to update its
7526                    // adj level.  Not sure what to do about this, but at least
7527                    // the race is now smaller.
7528                    if (!success) {
7529                        // Uh oh...  it looks like the provider's process
7530                        // has been killed on us.  We need to wait for a new
7531                        // process to be started, and make sure its death
7532                        // doesn't kill our process.
7533                        Slog.i(TAG,
7534                                "Existing provider " + cpr.name.flattenToShortString()
7535                                + " is crashing; detaching " + r);
7536                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7537                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7538                        if (!lastRef) {
7539                            // This wasn't the last ref our process had on
7540                            // the provider...  we have now been killed, bail.
7541                            return null;
7542                        }
7543                        providerRunning = false;
7544                        conn = null;
7545                    }
7546                }
7547
7548                Binder.restoreCallingIdentity(origId);
7549            }
7550
7551            boolean singleton;
7552            if (!providerRunning) {
7553                try {
7554                    cpi = AppGlobals.getPackageManager().
7555                        resolveContentProvider(name,
7556                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7557                } catch (RemoteException ex) {
7558                }
7559                if (cpi == null) {
7560                    return null;
7561                }
7562                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7563                        cpi.name, cpi.flags);
7564                if (singleton) {
7565                    userId = 0;
7566                }
7567                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7568
7569                String msg;
7570                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7571                    throw new SecurityException(msg);
7572                }
7573
7574                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7575                        && !cpi.processName.equals("system")) {
7576                    // If this content provider does not run in the system
7577                    // process, and the system is not yet ready to run other
7578                    // processes, then fail fast instead of hanging.
7579                    throw new IllegalArgumentException(
7580                            "Attempt to launch content provider before system ready");
7581                }
7582
7583                // Make sure that the user who owns this provider is started.  If not,
7584                // we don't want to allow it to run.
7585                if (mStartedUsers.get(userId) == null) {
7586                    Slog.w(TAG, "Unable to launch app "
7587                            + cpi.applicationInfo.packageName + "/"
7588                            + cpi.applicationInfo.uid + " for provider "
7589                            + name + ": user " + userId + " is stopped");
7590                    return null;
7591                }
7592
7593                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7594                cpr = mProviderMap.getProviderByClass(comp, userId);
7595                final boolean firstClass = cpr == null;
7596                if (firstClass) {
7597                    try {
7598                        ApplicationInfo ai =
7599                            AppGlobals.getPackageManager().
7600                                getApplicationInfo(
7601                                        cpi.applicationInfo.packageName,
7602                                        STOCK_PM_FLAGS, userId);
7603                        if (ai == null) {
7604                            Slog.w(TAG, "No package info for content provider "
7605                                    + cpi.name);
7606                            return null;
7607                        }
7608                        ai = getAppInfoForUser(ai, userId);
7609                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7610                    } catch (RemoteException ex) {
7611                        // pm is in same process, this will never happen.
7612                    }
7613                }
7614
7615                if (r != null && cpr.canRunHere(r)) {
7616                    // If this is a multiprocess provider, then just return its
7617                    // info and allow the caller to instantiate it.  Only do
7618                    // this if the provider is the same user as the caller's
7619                    // process, or can run as root (so can be in any process).
7620                    return cpr.newHolder(null);
7621                }
7622
7623                if (DEBUG_PROVIDER) {
7624                    RuntimeException e = new RuntimeException("here");
7625                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7626                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7627                }
7628
7629                // This is single process, and our app is now connecting to it.
7630                // See if we are already in the process of launching this
7631                // provider.
7632                final int N = mLaunchingProviders.size();
7633                int i;
7634                for (i=0; i<N; i++) {
7635                    if (mLaunchingProviders.get(i) == cpr) {
7636                        break;
7637                    }
7638                }
7639
7640                // If the provider is not already being launched, then get it
7641                // started.
7642                if (i >= N) {
7643                    final long origId = Binder.clearCallingIdentity();
7644
7645                    try {
7646                        // Content provider is now in use, its package can't be stopped.
7647                        try {
7648                            AppGlobals.getPackageManager().setPackageStoppedState(
7649                                    cpr.appInfo.packageName, false, userId);
7650                        } catch (RemoteException e) {
7651                        } catch (IllegalArgumentException e) {
7652                            Slog.w(TAG, "Failed trying to unstop package "
7653                                    + cpr.appInfo.packageName + ": " + e);
7654                        }
7655
7656                        // Use existing process if already started
7657                        ProcessRecord proc = getProcessRecordLocked(
7658                                cpi.processName, cpr.appInfo.uid, false);
7659                        if (proc != null && proc.thread != null) {
7660                            if (DEBUG_PROVIDER) {
7661                                Slog.d(TAG, "Installing in existing process " + proc);
7662                            }
7663                            proc.pubProviders.put(cpi.name, cpr);
7664                            try {
7665                                proc.thread.scheduleInstallProvider(cpi);
7666                            } catch (RemoteException e) {
7667                            }
7668                        } else {
7669                            proc = startProcessLocked(cpi.processName,
7670                                    cpr.appInfo, false, 0, "content provider",
7671                                    new ComponentName(cpi.applicationInfo.packageName,
7672                                            cpi.name), false, false, false);
7673                            if (proc == null) {
7674                                Slog.w(TAG, "Unable to launch app "
7675                                        + cpi.applicationInfo.packageName + "/"
7676                                        + cpi.applicationInfo.uid + " for provider "
7677                                        + name + ": process is bad");
7678                                return null;
7679                            }
7680                        }
7681                        cpr.launchingApp = proc;
7682                        mLaunchingProviders.add(cpr);
7683                    } finally {
7684                        Binder.restoreCallingIdentity(origId);
7685                    }
7686                }
7687
7688                // Make sure the provider is published (the same provider class
7689                // may be published under multiple names).
7690                if (firstClass) {
7691                    mProviderMap.putProviderByClass(comp, cpr);
7692                }
7693
7694                mProviderMap.putProviderByName(name, cpr);
7695                conn = incProviderCountLocked(r, cpr, token, stable);
7696                if (conn != null) {
7697                    conn.waiting = true;
7698                }
7699            }
7700        }
7701
7702        // Wait for the provider to be published...
7703        synchronized (cpr) {
7704            while (cpr.provider == null) {
7705                if (cpr.launchingApp == null) {
7706                    Slog.w(TAG, "Unable to launch app "
7707                            + cpi.applicationInfo.packageName + "/"
7708                            + cpi.applicationInfo.uid + " for provider "
7709                            + name + ": launching app became null");
7710                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7711                            UserHandle.getUserId(cpi.applicationInfo.uid),
7712                            cpi.applicationInfo.packageName,
7713                            cpi.applicationInfo.uid, name);
7714                    return null;
7715                }
7716                try {
7717                    if (DEBUG_MU) {
7718                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7719                                + cpr.launchingApp);
7720                    }
7721                    if (conn != null) {
7722                        conn.waiting = true;
7723                    }
7724                    cpr.wait();
7725                } catch (InterruptedException ex) {
7726                } finally {
7727                    if (conn != null) {
7728                        conn.waiting = false;
7729                    }
7730                }
7731            }
7732        }
7733        return cpr != null ? cpr.newHolder(conn) : null;
7734    }
7735
7736    public final ContentProviderHolder getContentProvider(
7737            IApplicationThread caller, String name, int userId, boolean stable) {
7738        enforceNotIsolatedCaller("getContentProvider");
7739        if (caller == null) {
7740            String msg = "null IApplicationThread when getting content provider "
7741                    + name;
7742            Slog.w(TAG, msg);
7743            throw new SecurityException(msg);
7744        }
7745
7746        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7747                false, true, "getContentProvider", null);
7748        return getContentProviderImpl(caller, name, null, stable, userId);
7749    }
7750
7751    public ContentProviderHolder getContentProviderExternal(
7752            String name, int userId, IBinder token) {
7753        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7754            "Do not have permission in call getContentProviderExternal()");
7755        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7756                false, true, "getContentProvider", null);
7757        return getContentProviderExternalUnchecked(name, token, userId);
7758    }
7759
7760    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7761            IBinder token, int userId) {
7762        return getContentProviderImpl(null, name, token, true, userId);
7763    }
7764
7765    /**
7766     * Drop a content provider from a ProcessRecord's bookkeeping
7767     */
7768    public void removeContentProvider(IBinder connection, boolean stable) {
7769        enforceNotIsolatedCaller("removeContentProvider");
7770        synchronized (this) {
7771            ContentProviderConnection conn;
7772            try {
7773                conn = (ContentProviderConnection)connection;
7774            } catch (ClassCastException e) {
7775                String msg ="removeContentProvider: " + connection
7776                        + " not a ContentProviderConnection";
7777                Slog.w(TAG, msg);
7778                throw new IllegalArgumentException(msg);
7779            }
7780            if (conn == null) {
7781                throw new NullPointerException("connection is null");
7782            }
7783            if (decProviderCountLocked(conn, null, null, stable)) {
7784                updateOomAdjLocked();
7785            }
7786        }
7787    }
7788
7789    public void removeContentProviderExternal(String name, IBinder token) {
7790        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7791            "Do not have permission in call removeContentProviderExternal()");
7792        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7793    }
7794
7795    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7796        synchronized (this) {
7797            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7798            if(cpr == null) {
7799                //remove from mProvidersByClass
7800                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7801                return;
7802            }
7803
7804            //update content provider record entry info
7805            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7806            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7807            if (localCpr.hasExternalProcessHandles()) {
7808                if (localCpr.removeExternalProcessHandleLocked(token)) {
7809                    updateOomAdjLocked();
7810                } else {
7811                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7812                            + " with no external reference for token: "
7813                            + token + ".");
7814                }
7815            } else {
7816                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7817                        + " with no external references.");
7818            }
7819        }
7820    }
7821
7822    public final void publishContentProviders(IApplicationThread caller,
7823            List<ContentProviderHolder> providers) {
7824        if (providers == null) {
7825            return;
7826        }
7827
7828        enforceNotIsolatedCaller("publishContentProviders");
7829        synchronized (this) {
7830            final ProcessRecord r = getRecordForAppLocked(caller);
7831            if (DEBUG_MU)
7832                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7833            if (r == null) {
7834                throw new SecurityException(
7835                        "Unable to find app for caller " + caller
7836                      + " (pid=" + Binder.getCallingPid()
7837                      + ") when publishing content providers");
7838            }
7839
7840            final long origId = Binder.clearCallingIdentity();
7841
7842            final int N = providers.size();
7843            for (int i=0; i<N; i++) {
7844                ContentProviderHolder src = providers.get(i);
7845                if (src == null || src.info == null || src.provider == null) {
7846                    continue;
7847                }
7848                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7849                if (DEBUG_MU)
7850                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7851                if (dst != null) {
7852                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7853                    mProviderMap.putProviderByClass(comp, dst);
7854                    String names[] = dst.info.authority.split(";");
7855                    for (int j = 0; j < names.length; j++) {
7856                        mProviderMap.putProviderByName(names[j], dst);
7857                    }
7858
7859                    int NL = mLaunchingProviders.size();
7860                    int j;
7861                    for (j=0; j<NL; j++) {
7862                        if (mLaunchingProviders.get(j) == dst) {
7863                            mLaunchingProviders.remove(j);
7864                            j--;
7865                            NL--;
7866                        }
7867                    }
7868                    synchronized (dst) {
7869                        dst.provider = src.provider;
7870                        dst.proc = r;
7871                        dst.notifyAll();
7872                    }
7873                    updateOomAdjLocked(r);
7874                }
7875            }
7876
7877            Binder.restoreCallingIdentity(origId);
7878        }
7879    }
7880
7881    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7882        ContentProviderConnection conn;
7883        try {
7884            conn = (ContentProviderConnection)connection;
7885        } catch (ClassCastException e) {
7886            String msg ="refContentProvider: " + connection
7887                    + " not a ContentProviderConnection";
7888            Slog.w(TAG, msg);
7889            throw new IllegalArgumentException(msg);
7890        }
7891        if (conn == null) {
7892            throw new NullPointerException("connection is null");
7893        }
7894
7895        synchronized (this) {
7896            if (stable > 0) {
7897                conn.numStableIncs += stable;
7898            }
7899            stable = conn.stableCount + stable;
7900            if (stable < 0) {
7901                throw new IllegalStateException("stableCount < 0: " + stable);
7902            }
7903
7904            if (unstable > 0) {
7905                conn.numUnstableIncs += unstable;
7906            }
7907            unstable = conn.unstableCount + unstable;
7908            if (unstable < 0) {
7909                throw new IllegalStateException("unstableCount < 0: " + unstable);
7910            }
7911
7912            if ((stable+unstable) <= 0) {
7913                throw new IllegalStateException("ref counts can't go to zero here: stable="
7914                        + stable + " unstable=" + unstable);
7915            }
7916            conn.stableCount = stable;
7917            conn.unstableCount = unstable;
7918            return !conn.dead;
7919        }
7920    }
7921
7922    public void unstableProviderDied(IBinder connection) {
7923        ContentProviderConnection conn;
7924        try {
7925            conn = (ContentProviderConnection)connection;
7926        } catch (ClassCastException e) {
7927            String msg ="refContentProvider: " + connection
7928                    + " not a ContentProviderConnection";
7929            Slog.w(TAG, msg);
7930            throw new IllegalArgumentException(msg);
7931        }
7932        if (conn == null) {
7933            throw new NullPointerException("connection is null");
7934        }
7935
7936        // Safely retrieve the content provider associated with the connection.
7937        IContentProvider provider;
7938        synchronized (this) {
7939            provider = conn.provider.provider;
7940        }
7941
7942        if (provider == null) {
7943            // Um, yeah, we're way ahead of you.
7944            return;
7945        }
7946
7947        // Make sure the caller is being honest with us.
7948        if (provider.asBinder().pingBinder()) {
7949            // Er, no, still looks good to us.
7950            synchronized (this) {
7951                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7952                        + " says " + conn + " died, but we don't agree");
7953                return;
7954            }
7955        }
7956
7957        // Well look at that!  It's dead!
7958        synchronized (this) {
7959            if (conn.provider.provider != provider) {
7960                // But something changed...  good enough.
7961                return;
7962            }
7963
7964            ProcessRecord proc = conn.provider.proc;
7965            if (proc == null || proc.thread == null) {
7966                // Seems like the process is already cleaned up.
7967                return;
7968            }
7969
7970            // As far as we're concerned, this is just like receiving a
7971            // death notification...  just a bit prematurely.
7972            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7973                    + ") early provider death");
7974            final long ident = Binder.clearCallingIdentity();
7975            try {
7976                appDiedLocked(proc, proc.pid, proc.thread);
7977            } finally {
7978                Binder.restoreCallingIdentity(ident);
7979            }
7980        }
7981    }
7982
7983    @Override
7984    public void appNotRespondingViaProvider(IBinder connection) {
7985        enforceCallingPermission(
7986                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7987
7988        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7989        if (conn == null) {
7990            Slog.w(TAG, "ContentProviderConnection is null");
7991            return;
7992        }
7993
7994        final ProcessRecord host = conn.provider.proc;
7995        if (host == null) {
7996            Slog.w(TAG, "Failed to find hosting ProcessRecord");
7997            return;
7998        }
7999
8000        final long token = Binder.clearCallingIdentity();
8001        try {
8002            appNotResponding(host, null, null, false, "ContentProvider not responding");
8003        } finally {
8004            Binder.restoreCallingIdentity(token);
8005        }
8006    }
8007
8008    public final void installSystemProviders() {
8009        List<ProviderInfo> providers;
8010        synchronized (this) {
8011            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8012            providers = generateApplicationProvidersLocked(app);
8013            if (providers != null) {
8014                for (int i=providers.size()-1; i>=0; i--) {
8015                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8016                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8017                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8018                                + ": not system .apk");
8019                        providers.remove(i);
8020                    }
8021                }
8022            }
8023        }
8024        if (providers != null) {
8025            mSystemThread.installSystemProviders(providers);
8026        }
8027
8028        mCoreSettingsObserver = new CoreSettingsObserver(this);
8029
8030        mUsageStatsService.monitorPackages();
8031    }
8032
8033    /**
8034     * Allows app to retrieve the MIME type of a URI without having permission
8035     * to access its content provider.
8036     *
8037     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8038     *
8039     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8040     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8041     */
8042    public String getProviderMimeType(Uri uri, int userId) {
8043        enforceNotIsolatedCaller("getProviderMimeType");
8044        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8045                userId, false, true, "getProviderMimeType", null);
8046        final String name = uri.getAuthority();
8047        final long ident = Binder.clearCallingIdentity();
8048        ContentProviderHolder holder = null;
8049
8050        try {
8051            holder = getContentProviderExternalUnchecked(name, null, userId);
8052            if (holder != null) {
8053                return holder.provider.getType(uri);
8054            }
8055        } catch (RemoteException e) {
8056            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8057            return null;
8058        } finally {
8059            if (holder != null) {
8060                removeContentProviderExternalUnchecked(name, null, userId);
8061            }
8062            Binder.restoreCallingIdentity(ident);
8063        }
8064
8065        return null;
8066    }
8067
8068    // =========================================================
8069    // GLOBAL MANAGEMENT
8070    // =========================================================
8071
8072    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8073            boolean isolated) {
8074        String proc = customProcess != null ? customProcess : info.processName;
8075        BatteryStatsImpl.Uid.Proc ps = null;
8076        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8077        int uid = info.uid;
8078        if (isolated) {
8079            int userId = UserHandle.getUserId(uid);
8080            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8081            while (true) {
8082                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8083                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8084                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8085                }
8086                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8087                mNextIsolatedProcessUid++;
8088                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8089                    // No process for this uid, use it.
8090                    break;
8091                }
8092                stepsLeft--;
8093                if (stepsLeft <= 0) {
8094                    return null;
8095                }
8096            }
8097        }
8098        return new ProcessRecord(stats, info, proc, uid);
8099    }
8100
8101    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8102        ProcessRecord app;
8103        if (!isolated) {
8104            app = getProcessRecordLocked(info.processName, info.uid, true);
8105        } else {
8106            app = null;
8107        }
8108
8109        if (app == null) {
8110            app = newProcessRecordLocked(info, null, isolated);
8111            mProcessNames.put(info.processName, app.uid, app);
8112            if (isolated) {
8113                mIsolatedProcesses.put(app.uid, app);
8114            }
8115            updateLruProcessLocked(app, false, null);
8116            updateOomAdjLocked();
8117        }
8118
8119        // This package really, really can not be stopped.
8120        try {
8121            AppGlobals.getPackageManager().setPackageStoppedState(
8122                    info.packageName, false, UserHandle.getUserId(app.uid));
8123        } catch (RemoteException e) {
8124        } catch (IllegalArgumentException e) {
8125            Slog.w(TAG, "Failed trying to unstop package "
8126                    + info.packageName + ": " + e);
8127        }
8128
8129        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8130                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8131            app.persistent = true;
8132            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8133        }
8134        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8135            mPersistentStartingProcesses.add(app);
8136            startProcessLocked(app, "added application", app.processName);
8137        }
8138
8139        return app;
8140    }
8141
8142    public void unhandledBack() {
8143        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8144                "unhandledBack()");
8145
8146        synchronized(this) {
8147            final long origId = Binder.clearCallingIdentity();
8148            try {
8149                getFocusedStack().unhandledBackLocked();
8150            } finally {
8151                Binder.restoreCallingIdentity(origId);
8152            }
8153        }
8154    }
8155
8156    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8157        enforceNotIsolatedCaller("openContentUri");
8158        final int userId = UserHandle.getCallingUserId();
8159        String name = uri.getAuthority();
8160        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8161        ParcelFileDescriptor pfd = null;
8162        if (cph != null) {
8163            // We record the binder invoker's uid in thread-local storage before
8164            // going to the content provider to open the file.  Later, in the code
8165            // that handles all permissions checks, we look for this uid and use
8166            // that rather than the Activity Manager's own uid.  The effect is that
8167            // we do the check against the caller's permissions even though it looks
8168            // to the content provider like the Activity Manager itself is making
8169            // the request.
8170            sCallerIdentity.set(new Identity(
8171                    Binder.getCallingPid(), Binder.getCallingUid()));
8172            try {
8173                pfd = cph.provider.openFile(null, uri, "r", null);
8174            } catch (FileNotFoundException e) {
8175                // do nothing; pfd will be returned null
8176            } finally {
8177                // Ensure that whatever happens, we clean up the identity state
8178                sCallerIdentity.remove();
8179            }
8180
8181            // We've got the fd now, so we're done with the provider.
8182            removeContentProviderExternalUnchecked(name, null, userId);
8183        } else {
8184            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8185        }
8186        return pfd;
8187    }
8188
8189    // Actually is sleeping or shutting down or whatever else in the future
8190    // is an inactive state.
8191    public boolean isSleepingOrShuttingDown() {
8192        return mSleeping || mShuttingDown;
8193    }
8194
8195    void goingToSleep() {
8196        synchronized(this) {
8197            mWentToSleep = true;
8198            updateEventDispatchingLocked();
8199
8200            if (!mSleeping) {
8201                mSleeping = true;
8202                mStackSupervisor.goingToSleepLocked();
8203
8204                // Initialize the wake times of all processes.
8205                checkExcessivePowerUsageLocked(false);
8206                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8207                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8208                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8209            }
8210        }
8211    }
8212
8213    @Override
8214    public boolean shutdown(int timeout) {
8215        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8216                != PackageManager.PERMISSION_GRANTED) {
8217            throw new SecurityException("Requires permission "
8218                    + android.Manifest.permission.SHUTDOWN);
8219        }
8220
8221        boolean timedout = false;
8222
8223        synchronized(this) {
8224            mShuttingDown = true;
8225            updateEventDispatchingLocked();
8226            timedout = mStackSupervisor.shutdownLocked(timeout);
8227        }
8228
8229        mAppOpsService.shutdown();
8230        mUsageStatsService.shutdown();
8231        mBatteryStatsService.shutdown();
8232        synchronized (this) {
8233            mProcessStats.shutdownLocked();
8234        }
8235
8236        return timedout;
8237    }
8238
8239    public final void activitySlept(IBinder token) {
8240        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8241
8242        final long origId = Binder.clearCallingIdentity();
8243
8244        synchronized (this) {
8245            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8246            if (r != null) {
8247                mStackSupervisor.activitySleptLocked(r);
8248            }
8249        }
8250
8251        Binder.restoreCallingIdentity(origId);
8252    }
8253
8254    void logLockScreen(String msg) {
8255        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8256                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8257                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8258                mStackSupervisor.mDismissKeyguardOnNextActivity);
8259    }
8260
8261    private void comeOutOfSleepIfNeededLocked() {
8262        if (!mWentToSleep && !mLockScreenShown) {
8263            if (mSleeping) {
8264                mSleeping = false;
8265                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8266            }
8267        }
8268    }
8269
8270    void wakingUp() {
8271        synchronized(this) {
8272            mWentToSleep = false;
8273            updateEventDispatchingLocked();
8274            comeOutOfSleepIfNeededLocked();
8275        }
8276    }
8277
8278    private void updateEventDispatchingLocked() {
8279        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8280    }
8281
8282    public void setLockScreenShown(boolean shown) {
8283        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8284                != PackageManager.PERMISSION_GRANTED) {
8285            throw new SecurityException("Requires permission "
8286                    + android.Manifest.permission.DEVICE_POWER);
8287        }
8288
8289        synchronized(this) {
8290            long ident = Binder.clearCallingIdentity();
8291            try {
8292                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8293                mLockScreenShown = shown;
8294                comeOutOfSleepIfNeededLocked();
8295            } finally {
8296                Binder.restoreCallingIdentity(ident);
8297            }
8298        }
8299    }
8300
8301    public void stopAppSwitches() {
8302        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8303                != PackageManager.PERMISSION_GRANTED) {
8304            throw new SecurityException("Requires permission "
8305                    + android.Manifest.permission.STOP_APP_SWITCHES);
8306        }
8307
8308        synchronized(this) {
8309            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8310                    + APP_SWITCH_DELAY_TIME;
8311            mDidAppSwitch = false;
8312            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8313            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8314            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8315        }
8316    }
8317
8318    public void resumeAppSwitches() {
8319        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8320                != PackageManager.PERMISSION_GRANTED) {
8321            throw new SecurityException("Requires permission "
8322                    + android.Manifest.permission.STOP_APP_SWITCHES);
8323        }
8324
8325        synchronized(this) {
8326            // Note that we don't execute any pending app switches... we will
8327            // let those wait until either the timeout, or the next start
8328            // activity request.
8329            mAppSwitchesAllowedTime = 0;
8330        }
8331    }
8332
8333    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8334            String name) {
8335        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8336            return true;
8337        }
8338
8339        final int perm = checkComponentPermission(
8340                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8341                callingUid, -1, true);
8342        if (perm == PackageManager.PERMISSION_GRANTED) {
8343            return true;
8344        }
8345
8346        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8347        return false;
8348    }
8349
8350    public void setDebugApp(String packageName, boolean waitForDebugger,
8351            boolean persistent) {
8352        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8353                "setDebugApp()");
8354
8355        long ident = Binder.clearCallingIdentity();
8356        try {
8357            // Note that this is not really thread safe if there are multiple
8358            // callers into it at the same time, but that's not a situation we
8359            // care about.
8360            if (persistent) {
8361                final ContentResolver resolver = mContext.getContentResolver();
8362                Settings.Global.putString(
8363                    resolver, Settings.Global.DEBUG_APP,
8364                    packageName);
8365                Settings.Global.putInt(
8366                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8367                    waitForDebugger ? 1 : 0);
8368            }
8369
8370            synchronized (this) {
8371                if (!persistent) {
8372                    mOrigDebugApp = mDebugApp;
8373                    mOrigWaitForDebugger = mWaitForDebugger;
8374                }
8375                mDebugApp = packageName;
8376                mWaitForDebugger = waitForDebugger;
8377                mDebugTransient = !persistent;
8378                if (packageName != null) {
8379                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8380                            UserHandle.USER_ALL, "set debug app");
8381                }
8382            }
8383        } finally {
8384            Binder.restoreCallingIdentity(ident);
8385        }
8386    }
8387
8388    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8389        synchronized (this) {
8390            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8391            if (!isDebuggable) {
8392                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8393                    throw new SecurityException("Process not debuggable: " + app.packageName);
8394                }
8395            }
8396
8397            mOpenGlTraceApp = processName;
8398        }
8399    }
8400
8401    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8402            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8403        synchronized (this) {
8404            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8405            if (!isDebuggable) {
8406                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8407                    throw new SecurityException("Process not debuggable: " + app.packageName);
8408                }
8409            }
8410            mProfileApp = processName;
8411            mProfileFile = profileFile;
8412            if (mProfileFd != null) {
8413                try {
8414                    mProfileFd.close();
8415                } catch (IOException e) {
8416                }
8417                mProfileFd = null;
8418            }
8419            mProfileFd = profileFd;
8420            mProfileType = 0;
8421            mAutoStopProfiler = autoStopProfiler;
8422        }
8423    }
8424
8425    @Override
8426    public void setAlwaysFinish(boolean enabled) {
8427        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8428                "setAlwaysFinish()");
8429
8430        Settings.Global.putInt(
8431                mContext.getContentResolver(),
8432                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8433
8434        synchronized (this) {
8435            mAlwaysFinishActivities = enabled;
8436        }
8437    }
8438
8439    @Override
8440    public void setActivityController(IActivityController controller) {
8441        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8442                "setActivityController()");
8443        synchronized (this) {
8444            mController = controller;
8445            Watchdog.getInstance().setActivityController(controller);
8446        }
8447    }
8448
8449    @Override
8450    public void setUserIsMonkey(boolean userIsMonkey) {
8451        synchronized (this) {
8452            synchronized (mPidsSelfLocked) {
8453                final int callingPid = Binder.getCallingPid();
8454                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8455                if (precessRecord == null) {
8456                    throw new SecurityException("Unknown process: " + callingPid);
8457                }
8458                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8459                    throw new SecurityException("Only an instrumentation process "
8460                            + "with a UiAutomation can call setUserIsMonkey");
8461                }
8462            }
8463            mUserIsMonkey = userIsMonkey;
8464        }
8465    }
8466
8467    @Override
8468    public boolean isUserAMonkey() {
8469        synchronized (this) {
8470            // If there is a controller also implies the user is a monkey.
8471            return (mUserIsMonkey || mController != null);
8472        }
8473    }
8474
8475    public void requestBugReport() {
8476        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8477        SystemProperties.set("ctl.start", "bugreport");
8478    }
8479
8480    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8481        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8482    }
8483
8484    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8485        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8486            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8487        }
8488        return KEY_DISPATCHING_TIMEOUT;
8489    }
8490
8491    @Override
8492    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8493        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8494                != PackageManager.PERMISSION_GRANTED) {
8495            throw new SecurityException("Requires permission "
8496                    + android.Manifest.permission.FILTER_EVENTS);
8497        }
8498        ProcessRecord proc;
8499        long timeout;
8500        synchronized (this) {
8501            synchronized (mPidsSelfLocked) {
8502                proc = mPidsSelfLocked.get(pid);
8503            }
8504            timeout = getInputDispatchingTimeoutLocked(proc);
8505        }
8506
8507        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8508            return -1;
8509        }
8510
8511        return timeout;
8512    }
8513
8514    /**
8515     * Handle input dispatching timeouts.
8516     * Returns whether input dispatching should be aborted or not.
8517     */
8518    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8519            final ActivityRecord activity, final ActivityRecord parent,
8520            final boolean aboveSystem, String reason) {
8521        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8522                != PackageManager.PERMISSION_GRANTED) {
8523            throw new SecurityException("Requires permission "
8524                    + android.Manifest.permission.FILTER_EVENTS);
8525        }
8526
8527        final String annotation;
8528        if (reason == null) {
8529            annotation = "Input dispatching timed out";
8530        } else {
8531            annotation = "Input dispatching timed out (" + reason + ")";
8532        }
8533
8534        if (proc != null) {
8535            synchronized (this) {
8536                if (proc.debugging) {
8537                    return false;
8538                }
8539
8540                if (mDidDexOpt) {
8541                    // Give more time since we were dexopting.
8542                    mDidDexOpt = false;
8543                    return false;
8544                }
8545
8546                if (proc.instrumentationClass != null) {
8547                    Bundle info = new Bundle();
8548                    info.putString("shortMsg", "keyDispatchingTimedOut");
8549                    info.putString("longMsg", annotation);
8550                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8551                    return true;
8552                }
8553            }
8554            mHandler.post(new Runnable() {
8555                @Override
8556                public void run() {
8557                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8558                }
8559            });
8560        }
8561
8562        return true;
8563    }
8564
8565    public Bundle getAssistContextExtras(int requestType) {
8566        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8567                "getAssistContextExtras()");
8568        PendingAssistExtras pae;
8569        Bundle extras = new Bundle();
8570        synchronized (this) {
8571            ActivityRecord activity = getFocusedStack().mResumedActivity;
8572            if (activity == null) {
8573                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8574                return null;
8575            }
8576            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8577            if (activity.app == null || activity.app.thread == null) {
8578                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8579                return extras;
8580            }
8581            if (activity.app.pid == Binder.getCallingPid()) {
8582                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8583                return extras;
8584            }
8585            pae = new PendingAssistExtras(activity);
8586            try {
8587                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8588                        requestType);
8589                mPendingAssistExtras.add(pae);
8590                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8591            } catch (RemoteException e) {
8592                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8593                return extras;
8594            }
8595        }
8596        synchronized (pae) {
8597            while (!pae.haveResult) {
8598                try {
8599                    pae.wait();
8600                } catch (InterruptedException e) {
8601                }
8602            }
8603            if (pae.result != null) {
8604                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8605            }
8606        }
8607        synchronized (this) {
8608            mPendingAssistExtras.remove(pae);
8609            mHandler.removeCallbacks(pae);
8610        }
8611        return extras;
8612    }
8613
8614    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8615        PendingAssistExtras pae = (PendingAssistExtras)token;
8616        synchronized (pae) {
8617            pae.result = extras;
8618            pae.haveResult = true;
8619            pae.notifyAll();
8620        }
8621    }
8622
8623    public void registerProcessObserver(IProcessObserver observer) {
8624        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8625                "registerProcessObserver()");
8626        synchronized (this) {
8627            mProcessObservers.register(observer);
8628        }
8629    }
8630
8631    @Override
8632    public void unregisterProcessObserver(IProcessObserver observer) {
8633        synchronized (this) {
8634            mProcessObservers.unregister(observer);
8635        }
8636    }
8637
8638    @Override
8639    public boolean convertFromTranslucent(IBinder token) {
8640        final long origId = Binder.clearCallingIdentity();
8641        try {
8642            synchronized (this) {
8643                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8644                if (r == null) {
8645                    return false;
8646                }
8647                if (r.changeWindowTranslucency(true)) {
8648                    mWindowManager.setAppFullscreen(token, true);
8649                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8650                    return true;
8651                }
8652                return false;
8653            }
8654        } finally {
8655            Binder.restoreCallingIdentity(origId);
8656        }
8657    }
8658
8659    @Override
8660    public boolean convertToTranslucent(IBinder token) {
8661        final long origId = Binder.clearCallingIdentity();
8662        try {
8663            synchronized (this) {
8664                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8665                if (r == null) {
8666                    return false;
8667                }
8668                if (r.changeWindowTranslucency(false)) {
8669                    r.task.stack.convertToTranslucent(r);
8670                    mWindowManager.setAppFullscreen(token, false);
8671                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8672                    return true;
8673                }
8674                return false;
8675            }
8676        } finally {
8677            Binder.restoreCallingIdentity(origId);
8678        }
8679    }
8680
8681    @Override
8682    public void setImmersive(IBinder token, boolean immersive) {
8683        synchronized(this) {
8684            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8685            if (r == null) {
8686                throw new IllegalArgumentException();
8687            }
8688            r.immersive = immersive;
8689
8690            // update associated state if we're frontmost
8691            if (r == mFocusedActivity) {
8692                if (DEBUG_IMMERSIVE) {
8693                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8694                }
8695                applyUpdateLockStateLocked(r);
8696            }
8697        }
8698    }
8699
8700    @Override
8701    public boolean isImmersive(IBinder token) {
8702        synchronized (this) {
8703            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8704            if (r == null) {
8705                throw new IllegalArgumentException();
8706            }
8707            return r.immersive;
8708        }
8709    }
8710
8711    public boolean isTopActivityImmersive() {
8712        enforceNotIsolatedCaller("startActivity");
8713        synchronized (this) {
8714            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8715            return (r != null) ? r.immersive : false;
8716        }
8717    }
8718
8719    public final void enterSafeMode() {
8720        synchronized(this) {
8721            // It only makes sense to do this before the system is ready
8722            // and started launching other packages.
8723            if (!mSystemReady) {
8724                try {
8725                    AppGlobals.getPackageManager().enterSafeMode();
8726                } catch (RemoteException e) {
8727                }
8728            }
8729
8730            mSafeMode = true;
8731        }
8732    }
8733
8734    public final void showSafeModeOverlay() {
8735        View v = LayoutInflater.from(mContext).inflate(
8736                com.android.internal.R.layout.safe_mode, null);
8737        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8738        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8739        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8740        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8741        lp.gravity = Gravity.BOTTOM | Gravity.START;
8742        lp.format = v.getBackground().getOpacity();
8743        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8744                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8745        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8746        ((WindowManager)mContext.getSystemService(
8747                Context.WINDOW_SERVICE)).addView(v, lp);
8748    }
8749
8750    public void noteWakeupAlarm(IIntentSender sender) {
8751        if (!(sender instanceof PendingIntentRecord)) {
8752            return;
8753        }
8754        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8755        synchronized (stats) {
8756            if (mBatteryStatsService.isOnBattery()) {
8757                mBatteryStatsService.enforceCallingPermission();
8758                PendingIntentRecord rec = (PendingIntentRecord)sender;
8759                int MY_UID = Binder.getCallingUid();
8760                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8761                BatteryStatsImpl.Uid.Pkg pkg =
8762                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8763                pkg.incWakeupsLocked();
8764            }
8765        }
8766    }
8767
8768    public boolean killPids(int[] pids, String pReason, boolean secure) {
8769        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8770            throw new SecurityException("killPids only available to the system");
8771        }
8772        String reason = (pReason == null) ? "Unknown" : pReason;
8773        // XXX Note: don't acquire main activity lock here, because the window
8774        // manager calls in with its locks held.
8775
8776        boolean killed = false;
8777        synchronized (mPidsSelfLocked) {
8778            int[] types = new int[pids.length];
8779            int worstType = 0;
8780            for (int i=0; i<pids.length; i++) {
8781                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8782                if (proc != null) {
8783                    int type = proc.setAdj;
8784                    types[i] = type;
8785                    if (type > worstType) {
8786                        worstType = type;
8787                    }
8788                }
8789            }
8790
8791            // If the worst oom_adj is somewhere in the cached proc LRU range,
8792            // then constrain it so we will kill all cached procs.
8793            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8794                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8795                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8796            }
8797
8798            // If this is not a secure call, don't let it kill processes that
8799            // are important.
8800            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8801                worstType = ProcessList.SERVICE_ADJ;
8802            }
8803
8804            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8805            for (int i=0; i<pids.length; i++) {
8806                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8807                if (proc == null) {
8808                    continue;
8809                }
8810                int adj = proc.setAdj;
8811                if (adj >= worstType && !proc.killedByAm) {
8812                    killUnneededProcessLocked(proc, reason);
8813                    killed = true;
8814                }
8815            }
8816        }
8817        return killed;
8818    }
8819
8820    @Override
8821    public void killUid(int uid, String reason) {
8822        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8823            throw new SecurityException("killUid only available to the system");
8824        }
8825        synchronized (this) {
8826            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8827                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8828                    reason != null ? reason : "kill uid");
8829        }
8830    }
8831
8832    @Override
8833    public boolean killProcessesBelowForeground(String reason) {
8834        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8835            throw new SecurityException("killProcessesBelowForeground() only available to system");
8836        }
8837
8838        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8839    }
8840
8841    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8842        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8843            throw new SecurityException("killProcessesBelowAdj() only available to system");
8844        }
8845
8846        boolean killed = false;
8847        synchronized (mPidsSelfLocked) {
8848            final int size = mPidsSelfLocked.size();
8849            for (int i = 0; i < size; i++) {
8850                final int pid = mPidsSelfLocked.keyAt(i);
8851                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8852                if (proc == null) continue;
8853
8854                final int adj = proc.setAdj;
8855                if (adj > belowAdj && !proc.killedByAm) {
8856                    killUnneededProcessLocked(proc, reason);
8857                    killed = true;
8858                }
8859            }
8860        }
8861        return killed;
8862    }
8863
8864    @Override
8865    public void hang(final IBinder who, boolean allowRestart) {
8866        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8867                != PackageManager.PERMISSION_GRANTED) {
8868            throw new SecurityException("Requires permission "
8869                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8870        }
8871
8872        final IBinder.DeathRecipient death = new DeathRecipient() {
8873            @Override
8874            public void binderDied() {
8875                synchronized (this) {
8876                    notifyAll();
8877                }
8878            }
8879        };
8880
8881        try {
8882            who.linkToDeath(death, 0);
8883        } catch (RemoteException e) {
8884            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8885            return;
8886        }
8887
8888        synchronized (this) {
8889            Watchdog.getInstance().setAllowRestart(allowRestart);
8890            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8891            synchronized (death) {
8892                while (who.isBinderAlive()) {
8893                    try {
8894                        death.wait();
8895                    } catch (InterruptedException e) {
8896                    }
8897                }
8898            }
8899            Watchdog.getInstance().setAllowRestart(true);
8900        }
8901    }
8902
8903    @Override
8904    public void restart() {
8905        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8906                != PackageManager.PERMISSION_GRANTED) {
8907            throw new SecurityException("Requires permission "
8908                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8909        }
8910
8911        Log.i(TAG, "Sending shutdown broadcast...");
8912
8913        BroadcastReceiver br = new BroadcastReceiver() {
8914            @Override public void onReceive(Context context, Intent intent) {
8915                // Now the broadcast is done, finish up the low-level shutdown.
8916                Log.i(TAG, "Shutting down activity manager...");
8917                shutdown(10000);
8918                Log.i(TAG, "Shutdown complete, restarting!");
8919                Process.killProcess(Process.myPid());
8920                System.exit(10);
8921            }
8922        };
8923
8924        // First send the high-level shut down broadcast.
8925        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8926        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8927        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8928        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8929        mContext.sendOrderedBroadcastAsUser(intent,
8930                UserHandle.ALL, null, br, mHandler, 0, null, null);
8931        */
8932        br.onReceive(mContext, intent);
8933    }
8934
8935    private long getLowRamTimeSinceIdle(long now) {
8936        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8937    }
8938
8939    @Override
8940    public void performIdleMaintenance() {
8941        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8942                != PackageManager.PERMISSION_GRANTED) {
8943            throw new SecurityException("Requires permission "
8944                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8945        }
8946
8947        synchronized (this) {
8948            final long now = SystemClock.uptimeMillis();
8949            final long timeSinceLastIdle = now - mLastIdleTime;
8950            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8951            mLastIdleTime = now;
8952            mLowRamTimeSinceLastIdle = 0;
8953            if (mLowRamStartTime != 0) {
8954                mLowRamStartTime = now;
8955            }
8956
8957            StringBuilder sb = new StringBuilder(128);
8958            sb.append("Idle maintenance over ");
8959            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8960            sb.append(" low RAM for ");
8961            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8962            Slog.i(TAG, sb.toString());
8963
8964            // If at least 1/3 of our time since the last idle period has been spent
8965            // with RAM low, then we want to kill processes.
8966            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8967
8968            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8969                ProcessRecord proc = mLruProcesses.get(i);
8970                if (proc.notCachedSinceIdle) {
8971                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8972                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8973                        if (doKilling && proc.initialIdlePss != 0
8974                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8975                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8976                                    + " from " + proc.initialIdlePss + ")");
8977                        }
8978                    }
8979                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8980                    proc.notCachedSinceIdle = true;
8981                    proc.initialIdlePss = 0;
8982                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8983                            mSleeping, now);
8984                }
8985            }
8986
8987            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8988            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8989        }
8990    }
8991
8992    private void retrieveSettings() {
8993        final ContentResolver resolver = mContext.getContentResolver();
8994        String debugApp = Settings.Global.getString(
8995            resolver, Settings.Global.DEBUG_APP);
8996        boolean waitForDebugger = Settings.Global.getInt(
8997            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
8998        boolean alwaysFinishActivities = Settings.Global.getInt(
8999            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9000        boolean forceRtl = Settings.Global.getInt(
9001                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9002        // Transfer any global setting for forcing RTL layout, into a System Property
9003        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9004
9005        Configuration configuration = new Configuration();
9006        Settings.System.getConfiguration(resolver, configuration);
9007        if (forceRtl) {
9008            // This will take care of setting the correct layout direction flags
9009            configuration.setLayoutDirection(configuration.locale);
9010        }
9011
9012        synchronized (this) {
9013            mDebugApp = mOrigDebugApp = debugApp;
9014            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9015            mAlwaysFinishActivities = alwaysFinishActivities;
9016            // This happens before any activities are started, so we can
9017            // change mConfiguration in-place.
9018            updateConfigurationLocked(configuration, null, false, true);
9019            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9020        }
9021    }
9022
9023    public boolean testIsSystemReady() {
9024        // no need to synchronize(this) just to read & return the value
9025        return mSystemReady;
9026    }
9027
9028    private static File getCalledPreBootReceiversFile() {
9029        File dataDir = Environment.getDataDirectory();
9030        File systemDir = new File(dataDir, "system");
9031        File fname = new File(systemDir, "called_pre_boots.dat");
9032        return fname;
9033    }
9034
9035    static final int LAST_DONE_VERSION = 10000;
9036
9037    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9038        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9039        File file = getCalledPreBootReceiversFile();
9040        FileInputStream fis = null;
9041        try {
9042            fis = new FileInputStream(file);
9043            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9044            int fvers = dis.readInt();
9045            if (fvers == LAST_DONE_VERSION) {
9046                String vers = dis.readUTF();
9047                String codename = dis.readUTF();
9048                String build = dis.readUTF();
9049                if (android.os.Build.VERSION.RELEASE.equals(vers)
9050                        && android.os.Build.VERSION.CODENAME.equals(codename)
9051                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9052                    int num = dis.readInt();
9053                    while (num > 0) {
9054                        num--;
9055                        String pkg = dis.readUTF();
9056                        String cls = dis.readUTF();
9057                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9058                    }
9059                }
9060            }
9061        } catch (FileNotFoundException e) {
9062        } catch (IOException e) {
9063            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9064        } finally {
9065            if (fis != null) {
9066                try {
9067                    fis.close();
9068                } catch (IOException e) {
9069                }
9070            }
9071        }
9072        return lastDoneReceivers;
9073    }
9074
9075    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9076        File file = getCalledPreBootReceiversFile();
9077        FileOutputStream fos = null;
9078        DataOutputStream dos = null;
9079        try {
9080            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9081            fos = new FileOutputStream(file);
9082            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9083            dos.writeInt(LAST_DONE_VERSION);
9084            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9085            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9086            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9087            dos.writeInt(list.size());
9088            for (int i=0; i<list.size(); i++) {
9089                dos.writeUTF(list.get(i).getPackageName());
9090                dos.writeUTF(list.get(i).getClassName());
9091            }
9092        } catch (IOException e) {
9093            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9094            file.delete();
9095        } finally {
9096            FileUtils.sync(fos);
9097            if (dos != null) {
9098                try {
9099                    dos.close();
9100                } catch (IOException e) {
9101                    // TODO Auto-generated catch block
9102                    e.printStackTrace();
9103                }
9104            }
9105        }
9106    }
9107
9108    public void systemReady(final Runnable goingCallback) {
9109        synchronized(this) {
9110            if (mSystemReady) {
9111                if (goingCallback != null) goingCallback.run();
9112                return;
9113            }
9114
9115            // Check to see if there are any update receivers to run.
9116            if (!mDidUpdate) {
9117                if (mWaitingUpdate) {
9118                    return;
9119                }
9120                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9121                List<ResolveInfo> ris = null;
9122                try {
9123                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9124                            intent, null, 0, 0);
9125                } catch (RemoteException e) {
9126                }
9127                if (ris != null) {
9128                    for (int i=ris.size()-1; i>=0; i--) {
9129                        if ((ris.get(i).activityInfo.applicationInfo.flags
9130                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9131                            ris.remove(i);
9132                        }
9133                    }
9134                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9135
9136                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9137
9138                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9139                    for (int i=0; i<ris.size(); i++) {
9140                        ActivityInfo ai = ris.get(i).activityInfo;
9141                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9142                        if (lastDoneReceivers.contains(comp)) {
9143                            // We already did the pre boot receiver for this app with the current
9144                            // platform version, so don't do it again...
9145                            ris.remove(i);
9146                            i--;
9147                            // ...however, do keep it as one that has been done, so we don't
9148                            // forget about it when rewriting the file of last done receivers.
9149                            doneReceivers.add(comp);
9150                        }
9151                    }
9152
9153                    final int[] users = getUsersLocked();
9154                    for (int i=0; i<ris.size(); i++) {
9155                        ActivityInfo ai = ris.get(i).activityInfo;
9156                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9157                        doneReceivers.add(comp);
9158                        intent.setComponent(comp);
9159                        for (int j=0; j<users.length; j++) {
9160                            IIntentReceiver finisher = null;
9161                            if (i == ris.size()-1 && j == users.length-1) {
9162                                finisher = new IIntentReceiver.Stub() {
9163                                    public void performReceive(Intent intent, int resultCode,
9164                                            String data, Bundle extras, boolean ordered,
9165                                            boolean sticky, int sendingUser) {
9166                                        // The raw IIntentReceiver interface is called
9167                                        // with the AM lock held, so redispatch to
9168                                        // execute our code without the lock.
9169                                        mHandler.post(new Runnable() {
9170                                            public void run() {
9171                                                synchronized (ActivityManagerService.this) {
9172                                                    mDidUpdate = true;
9173                                                }
9174                                                writeLastDonePreBootReceivers(doneReceivers);
9175                                                showBootMessage(mContext.getText(
9176                                                        R.string.android_upgrading_complete),
9177                                                        false);
9178                                                systemReady(goingCallback);
9179                                            }
9180                                        });
9181                                    }
9182                                };
9183                            }
9184                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9185                                    + " for user " + users[j]);
9186                            broadcastIntentLocked(null, null, intent, null, finisher,
9187                                    0, null, null, null, AppOpsManager.OP_NONE,
9188                                    true, false, MY_PID, Process.SYSTEM_UID,
9189                                    users[j]);
9190                            if (finisher != null) {
9191                                mWaitingUpdate = true;
9192                            }
9193                        }
9194                    }
9195                }
9196                if (mWaitingUpdate) {
9197                    return;
9198                }
9199                mDidUpdate = true;
9200            }
9201
9202            mAppOpsService.systemReady();
9203            mSystemReady = true;
9204        }
9205
9206        ArrayList<ProcessRecord> procsToKill = null;
9207        synchronized(mPidsSelfLocked) {
9208            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9209                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9210                if (!isAllowedWhileBooting(proc.info)){
9211                    if (procsToKill == null) {
9212                        procsToKill = new ArrayList<ProcessRecord>();
9213                    }
9214                    procsToKill.add(proc);
9215                }
9216            }
9217        }
9218
9219        synchronized(this) {
9220            if (procsToKill != null) {
9221                for (int i=procsToKill.size()-1; i>=0; i--) {
9222                    ProcessRecord proc = procsToKill.get(i);
9223                    Slog.i(TAG, "Removing system update proc: " + proc);
9224                    removeProcessLocked(proc, true, false, "system update done");
9225                }
9226            }
9227
9228            // Now that we have cleaned up any update processes, we
9229            // are ready to start launching real processes and know that
9230            // we won't trample on them any more.
9231            mProcessesReady = true;
9232        }
9233
9234        Slog.i(TAG, "System now ready");
9235        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9236            SystemClock.uptimeMillis());
9237
9238        synchronized(this) {
9239            // Make sure we have no pre-ready processes sitting around.
9240
9241            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9242                ResolveInfo ri = mContext.getPackageManager()
9243                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9244                                STOCK_PM_FLAGS);
9245                CharSequence errorMsg = null;
9246                if (ri != null) {
9247                    ActivityInfo ai = ri.activityInfo;
9248                    ApplicationInfo app = ai.applicationInfo;
9249                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9250                        mTopAction = Intent.ACTION_FACTORY_TEST;
9251                        mTopData = null;
9252                        mTopComponent = new ComponentName(app.packageName,
9253                                ai.name);
9254                    } else {
9255                        errorMsg = mContext.getResources().getText(
9256                                com.android.internal.R.string.factorytest_not_system);
9257                    }
9258                } else {
9259                    errorMsg = mContext.getResources().getText(
9260                            com.android.internal.R.string.factorytest_no_action);
9261                }
9262                if (errorMsg != null) {
9263                    mTopAction = null;
9264                    mTopData = null;
9265                    mTopComponent = null;
9266                    Message msg = Message.obtain();
9267                    msg.what = SHOW_FACTORY_ERROR_MSG;
9268                    msg.getData().putCharSequence("msg", errorMsg);
9269                    mHandler.sendMessage(msg);
9270                }
9271            }
9272        }
9273
9274        retrieveSettings();
9275
9276        synchronized (this) {
9277            readGrantedUriPermissionsLocked();
9278        }
9279
9280        if (goingCallback != null) goingCallback.run();
9281
9282        synchronized (this) {
9283            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9284                try {
9285                    List apps = AppGlobals.getPackageManager().
9286                        getPersistentApplications(STOCK_PM_FLAGS);
9287                    if (apps != null) {
9288                        int N = apps.size();
9289                        int i;
9290                        for (i=0; i<N; i++) {
9291                            ApplicationInfo info
9292                                = (ApplicationInfo)apps.get(i);
9293                            if (info != null &&
9294                                    !info.packageName.equals("android")) {
9295                                addAppLocked(info, false);
9296                            }
9297                        }
9298                    }
9299                } catch (RemoteException ex) {
9300                    // pm is in same process, this will never happen.
9301                }
9302            }
9303
9304            // Start up initial activity.
9305            mBooting = true;
9306
9307            try {
9308                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9309                    Message msg = Message.obtain();
9310                    msg.what = SHOW_UID_ERROR_MSG;
9311                    mHandler.sendMessage(msg);
9312                }
9313            } catch (RemoteException e) {
9314            }
9315
9316            long ident = Binder.clearCallingIdentity();
9317            try {
9318                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9319                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9320                        | Intent.FLAG_RECEIVER_FOREGROUND);
9321                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9322                broadcastIntentLocked(null, null, intent,
9323                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9324                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9325                intent = new Intent(Intent.ACTION_USER_STARTING);
9326                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9327                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9328                broadcastIntentLocked(null, null, intent,
9329                        null, new IIntentReceiver.Stub() {
9330                            @Override
9331                            public void performReceive(Intent intent, int resultCode, String data,
9332                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9333                                    throws RemoteException {
9334                            }
9335                        }, 0, null, null,
9336                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9337                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9338            } finally {
9339                Binder.restoreCallingIdentity(ident);
9340            }
9341            mStackSupervisor.resumeTopActivitiesLocked();
9342            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9343        }
9344    }
9345
9346    private boolean makeAppCrashingLocked(ProcessRecord app,
9347            String shortMsg, String longMsg, String stackTrace) {
9348        app.crashing = true;
9349        app.crashingReport = generateProcessError(app,
9350                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9351        startAppProblemLocked(app);
9352        app.stopFreezingAllLocked();
9353        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9354    }
9355
9356    private void makeAppNotRespondingLocked(ProcessRecord app,
9357            String activity, String shortMsg, String longMsg) {
9358        app.notResponding = true;
9359        app.notRespondingReport = generateProcessError(app,
9360                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9361                activity, shortMsg, longMsg, null);
9362        startAppProblemLocked(app);
9363        app.stopFreezingAllLocked();
9364    }
9365
9366    /**
9367     * Generate a process error record, suitable for attachment to a ProcessRecord.
9368     *
9369     * @param app The ProcessRecord in which the error occurred.
9370     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9371     *                      ActivityManager.AppErrorStateInfo
9372     * @param activity The activity associated with the crash, if known.
9373     * @param shortMsg Short message describing the crash.
9374     * @param longMsg Long message describing the crash.
9375     * @param stackTrace Full crash stack trace, may be null.
9376     *
9377     * @return Returns a fully-formed AppErrorStateInfo record.
9378     */
9379    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9380            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9381        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9382
9383        report.condition = condition;
9384        report.processName = app.processName;
9385        report.pid = app.pid;
9386        report.uid = app.info.uid;
9387        report.tag = activity;
9388        report.shortMsg = shortMsg;
9389        report.longMsg = longMsg;
9390        report.stackTrace = stackTrace;
9391
9392        return report;
9393    }
9394
9395    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9396        synchronized (this) {
9397            app.crashing = false;
9398            app.crashingReport = null;
9399            app.notResponding = false;
9400            app.notRespondingReport = null;
9401            if (app.anrDialog == fromDialog) {
9402                app.anrDialog = null;
9403            }
9404            if (app.waitDialog == fromDialog) {
9405                app.waitDialog = null;
9406            }
9407            if (app.pid > 0 && app.pid != MY_PID) {
9408                handleAppCrashLocked(app, null, null, null);
9409                killUnneededProcessLocked(app, "user request after error");
9410            }
9411        }
9412    }
9413
9414    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9415            String stackTrace) {
9416        long now = SystemClock.uptimeMillis();
9417
9418        Long crashTime;
9419        if (!app.isolated) {
9420            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9421        } else {
9422            crashTime = null;
9423        }
9424        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9425            // This process loses!
9426            Slog.w(TAG, "Process " + app.info.processName
9427                    + " has crashed too many times: killing!");
9428            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9429                    app.userId, app.info.processName, app.uid);
9430            mStackSupervisor.handleAppCrashLocked(app);
9431            if (!app.persistent) {
9432                // We don't want to start this process again until the user
9433                // explicitly does so...  but for persistent process, we really
9434                // need to keep it running.  If a persistent process is actually
9435                // repeatedly crashing, then badness for everyone.
9436                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9437                        app.info.processName);
9438                if (!app.isolated) {
9439                    // XXX We don't have a way to mark isolated processes
9440                    // as bad, since they don't have a peristent identity.
9441                    mBadProcesses.put(app.info.processName, app.uid,
9442                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9443                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9444                }
9445                app.bad = true;
9446                app.removed = true;
9447                // Don't let services in this process be restarted and potentially
9448                // annoy the user repeatedly.  Unless it is persistent, since those
9449                // processes run critical code.
9450                removeProcessLocked(app, false, false, "crash");
9451                mStackSupervisor.resumeTopActivitiesLocked();
9452                return false;
9453            }
9454            mStackSupervisor.resumeTopActivitiesLocked();
9455        } else {
9456            mStackSupervisor.finishTopRunningActivityLocked(app);
9457        }
9458
9459        // Bump up the crash count of any services currently running in the proc.
9460        for (int i=app.services.size()-1; i>=0; i--) {
9461            // Any services running in the application need to be placed
9462            // back in the pending list.
9463            ServiceRecord sr = app.services.valueAt(i);
9464            sr.crashCount++;
9465        }
9466
9467        // If the crashing process is what we consider to be the "home process" and it has been
9468        // replaced by a third-party app, clear the package preferred activities from packages
9469        // with a home activity running in the process to prevent a repeatedly crashing app
9470        // from blocking the user to manually clear the list.
9471        final ArrayList<ActivityRecord> activities = app.activities;
9472        if (app == mHomeProcess && activities.size() > 0
9473                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9474            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9475                final ActivityRecord r = activities.get(activityNdx);
9476                if (r.isHomeActivity()) {
9477                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9478                    try {
9479                        ActivityThread.getPackageManager()
9480                                .clearPackagePreferredActivities(r.packageName);
9481                    } catch (RemoteException c) {
9482                        // pm is in same process, this will never happen.
9483                    }
9484                }
9485            }
9486        }
9487
9488        if (!app.isolated) {
9489            // XXX Can't keep track of crash times for isolated processes,
9490            // because they don't have a perisistent identity.
9491            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9492        }
9493
9494        return true;
9495    }
9496
9497    void startAppProblemLocked(ProcessRecord app) {
9498        if (app.userId == mCurrentUserId) {
9499            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9500                    mContext, app.info.packageName, app.info.flags);
9501        } else {
9502            // If this app is not running under the current user, then we
9503            // can't give it a report button because that would require
9504            // launching the report UI under a different user.
9505            app.errorReportReceiver = null;
9506        }
9507        skipCurrentReceiverLocked(app);
9508    }
9509
9510    void skipCurrentReceiverLocked(ProcessRecord app) {
9511        for (BroadcastQueue queue : mBroadcastQueues) {
9512            queue.skipCurrentReceiverLocked(app);
9513        }
9514    }
9515
9516    /**
9517     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9518     * The application process will exit immediately after this call returns.
9519     * @param app object of the crashing app, null for the system server
9520     * @param crashInfo describing the exception
9521     */
9522    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9523        ProcessRecord r = findAppProcess(app, "Crash");
9524        final String processName = app == null ? "system_server"
9525                : (r == null ? "unknown" : r.processName);
9526
9527        handleApplicationCrashInner("crash", r, processName, crashInfo);
9528    }
9529
9530    /* Native crash reporting uses this inner version because it needs to be somewhat
9531     * decoupled from the AM-managed cleanup lifecycle
9532     */
9533    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9534            ApplicationErrorReport.CrashInfo crashInfo) {
9535        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9536                UserHandle.getUserId(Binder.getCallingUid()), processName,
9537                r == null ? -1 : r.info.flags,
9538                crashInfo.exceptionClassName,
9539                crashInfo.exceptionMessage,
9540                crashInfo.throwFileName,
9541                crashInfo.throwLineNumber);
9542
9543        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9544
9545        crashApplication(r, crashInfo);
9546    }
9547
9548    public void handleApplicationStrictModeViolation(
9549            IBinder app,
9550            int violationMask,
9551            StrictMode.ViolationInfo info) {
9552        ProcessRecord r = findAppProcess(app, "StrictMode");
9553        if (r == null) {
9554            return;
9555        }
9556
9557        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9558            Integer stackFingerprint = info.hashCode();
9559            boolean logIt = true;
9560            synchronized (mAlreadyLoggedViolatedStacks) {
9561                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9562                    logIt = false;
9563                    // TODO: sub-sample into EventLog for these, with
9564                    // the info.durationMillis?  Then we'd get
9565                    // the relative pain numbers, without logging all
9566                    // the stack traces repeatedly.  We'd want to do
9567                    // likewise in the client code, which also does
9568                    // dup suppression, before the Binder call.
9569                } else {
9570                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9571                        mAlreadyLoggedViolatedStacks.clear();
9572                    }
9573                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9574                }
9575            }
9576            if (logIt) {
9577                logStrictModeViolationToDropBox(r, info);
9578            }
9579        }
9580
9581        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9582            AppErrorResult result = new AppErrorResult();
9583            synchronized (this) {
9584                final long origId = Binder.clearCallingIdentity();
9585
9586                Message msg = Message.obtain();
9587                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9588                HashMap<String, Object> data = new HashMap<String, Object>();
9589                data.put("result", result);
9590                data.put("app", r);
9591                data.put("violationMask", violationMask);
9592                data.put("info", info);
9593                msg.obj = data;
9594                mHandler.sendMessage(msg);
9595
9596                Binder.restoreCallingIdentity(origId);
9597            }
9598            int res = result.get();
9599            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9600        }
9601    }
9602
9603    // Depending on the policy in effect, there could be a bunch of
9604    // these in quick succession so we try to batch these together to
9605    // minimize disk writes, number of dropbox entries, and maximize
9606    // compression, by having more fewer, larger records.
9607    private void logStrictModeViolationToDropBox(
9608            ProcessRecord process,
9609            StrictMode.ViolationInfo info) {
9610        if (info == null) {
9611            return;
9612        }
9613        final boolean isSystemApp = process == null ||
9614                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9615                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9616        final String processName = process == null ? "unknown" : process.processName;
9617        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9618        final DropBoxManager dbox = (DropBoxManager)
9619                mContext.getSystemService(Context.DROPBOX_SERVICE);
9620
9621        // Exit early if the dropbox isn't configured to accept this report type.
9622        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9623
9624        boolean bufferWasEmpty;
9625        boolean needsFlush;
9626        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9627        synchronized (sb) {
9628            bufferWasEmpty = sb.length() == 0;
9629            appendDropBoxProcessHeaders(process, processName, sb);
9630            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9631            sb.append("System-App: ").append(isSystemApp).append("\n");
9632            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9633            if (info.violationNumThisLoop != 0) {
9634                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9635            }
9636            if (info.numAnimationsRunning != 0) {
9637                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9638            }
9639            if (info.broadcastIntentAction != null) {
9640                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9641            }
9642            if (info.durationMillis != -1) {
9643                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9644            }
9645            if (info.numInstances != -1) {
9646                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9647            }
9648            if (info.tags != null) {
9649                for (String tag : info.tags) {
9650                    sb.append("Span-Tag: ").append(tag).append("\n");
9651                }
9652            }
9653            sb.append("\n");
9654            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9655                sb.append(info.crashInfo.stackTrace);
9656            }
9657            sb.append("\n");
9658
9659            // Only buffer up to ~64k.  Various logging bits truncate
9660            // things at 128k.
9661            needsFlush = (sb.length() > 64 * 1024);
9662        }
9663
9664        // Flush immediately if the buffer's grown too large, or this
9665        // is a non-system app.  Non-system apps are isolated with a
9666        // different tag & policy and not batched.
9667        //
9668        // Batching is useful during internal testing with
9669        // StrictMode settings turned up high.  Without batching,
9670        // thousands of separate files could be created on boot.
9671        if (!isSystemApp || needsFlush) {
9672            new Thread("Error dump: " + dropboxTag) {
9673                @Override
9674                public void run() {
9675                    String report;
9676                    synchronized (sb) {
9677                        report = sb.toString();
9678                        sb.delete(0, sb.length());
9679                        sb.trimToSize();
9680                    }
9681                    if (report.length() != 0) {
9682                        dbox.addText(dropboxTag, report);
9683                    }
9684                }
9685            }.start();
9686            return;
9687        }
9688
9689        // System app batching:
9690        if (!bufferWasEmpty) {
9691            // An existing dropbox-writing thread is outstanding, so
9692            // we don't need to start it up.  The existing thread will
9693            // catch the buffer appends we just did.
9694            return;
9695        }
9696
9697        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9698        // (After this point, we shouldn't access AMS internal data structures.)
9699        new Thread("Error dump: " + dropboxTag) {
9700            @Override
9701            public void run() {
9702                // 5 second sleep to let stacks arrive and be batched together
9703                try {
9704                    Thread.sleep(5000);  // 5 seconds
9705                } catch (InterruptedException e) {}
9706
9707                String errorReport;
9708                synchronized (mStrictModeBuffer) {
9709                    errorReport = mStrictModeBuffer.toString();
9710                    if (errorReport.length() == 0) {
9711                        return;
9712                    }
9713                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9714                    mStrictModeBuffer.trimToSize();
9715                }
9716                dbox.addText(dropboxTag, errorReport);
9717            }
9718        }.start();
9719    }
9720
9721    /**
9722     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9723     * @param app object of the crashing app, null for the system server
9724     * @param tag reported by the caller
9725     * @param crashInfo describing the context of the error
9726     * @return true if the process should exit immediately (WTF is fatal)
9727     */
9728    public boolean handleApplicationWtf(IBinder app, String tag,
9729            ApplicationErrorReport.CrashInfo crashInfo) {
9730        ProcessRecord r = findAppProcess(app, "WTF");
9731        final String processName = app == null ? "system_server"
9732                : (r == null ? "unknown" : r.processName);
9733
9734        EventLog.writeEvent(EventLogTags.AM_WTF,
9735                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9736                processName,
9737                r == null ? -1 : r.info.flags,
9738                tag, crashInfo.exceptionMessage);
9739
9740        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9741
9742        if (r != null && r.pid != Process.myPid() &&
9743                Settings.Global.getInt(mContext.getContentResolver(),
9744                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9745            crashApplication(r, crashInfo);
9746            return true;
9747        } else {
9748            return false;
9749        }
9750    }
9751
9752    /**
9753     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9754     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9755     */
9756    private ProcessRecord findAppProcess(IBinder app, String reason) {
9757        if (app == null) {
9758            return null;
9759        }
9760
9761        synchronized (this) {
9762            final int NP = mProcessNames.getMap().size();
9763            for (int ip=0; ip<NP; ip++) {
9764                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9765                final int NA = apps.size();
9766                for (int ia=0; ia<NA; ia++) {
9767                    ProcessRecord p = apps.valueAt(ia);
9768                    if (p.thread != null && p.thread.asBinder() == app) {
9769                        return p;
9770                    }
9771                }
9772            }
9773
9774            Slog.w(TAG, "Can't find mystery application for " + reason
9775                    + " from pid=" + Binder.getCallingPid()
9776                    + " uid=" + Binder.getCallingUid() + ": " + app);
9777            return null;
9778        }
9779    }
9780
9781    /**
9782     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9783     * to append various headers to the dropbox log text.
9784     */
9785    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9786            StringBuilder sb) {
9787        // Watchdog thread ends up invoking this function (with
9788        // a null ProcessRecord) to add the stack file to dropbox.
9789        // Do not acquire a lock on this (am) in such cases, as it
9790        // could cause a potential deadlock, if and when watchdog
9791        // is invoked due to unavailability of lock on am and it
9792        // would prevent watchdog from killing system_server.
9793        if (process == null) {
9794            sb.append("Process: ").append(processName).append("\n");
9795            return;
9796        }
9797        // Note: ProcessRecord 'process' is guarded by the service
9798        // instance.  (notably process.pkgList, which could otherwise change
9799        // concurrently during execution of this method)
9800        synchronized (this) {
9801            sb.append("Process: ").append(processName).append("\n");
9802            int flags = process.info.flags;
9803            IPackageManager pm = AppGlobals.getPackageManager();
9804            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9805            for (int ip=0; ip<process.pkgList.size(); ip++) {
9806                String pkg = process.pkgList.keyAt(ip);
9807                sb.append("Package: ").append(pkg);
9808                try {
9809                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9810                    if (pi != null) {
9811                        sb.append(" v").append(pi.versionCode);
9812                        if (pi.versionName != null) {
9813                            sb.append(" (").append(pi.versionName).append(")");
9814                        }
9815                    }
9816                } catch (RemoteException e) {
9817                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9818                }
9819                sb.append("\n");
9820            }
9821        }
9822    }
9823
9824    private static String processClass(ProcessRecord process) {
9825        if (process == null || process.pid == MY_PID) {
9826            return "system_server";
9827        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9828            return "system_app";
9829        } else {
9830            return "data_app";
9831        }
9832    }
9833
9834    /**
9835     * Write a description of an error (crash, WTF, ANR) to the drop box.
9836     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9837     * @param process which caused the error, null means the system server
9838     * @param activity which triggered the error, null if unknown
9839     * @param parent activity related to the error, null if unknown
9840     * @param subject line related to the error, null if absent
9841     * @param report in long form describing the error, null if absent
9842     * @param logFile to include in the report, null if none
9843     * @param crashInfo giving an application stack trace, null if absent
9844     */
9845    public void addErrorToDropBox(String eventType,
9846            ProcessRecord process, String processName, ActivityRecord activity,
9847            ActivityRecord parent, String subject,
9848            final String report, final File logFile,
9849            final ApplicationErrorReport.CrashInfo crashInfo) {
9850        // NOTE -- this must never acquire the ActivityManagerService lock,
9851        // otherwise the watchdog may be prevented from resetting the system.
9852
9853        final String dropboxTag = processClass(process) + "_" + eventType;
9854        final DropBoxManager dbox = (DropBoxManager)
9855                mContext.getSystemService(Context.DROPBOX_SERVICE);
9856
9857        // Exit early if the dropbox isn't configured to accept this report type.
9858        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9859
9860        final StringBuilder sb = new StringBuilder(1024);
9861        appendDropBoxProcessHeaders(process, processName, sb);
9862        if (activity != null) {
9863            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9864        }
9865        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9866            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9867        }
9868        if (parent != null && parent != activity) {
9869            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9870        }
9871        if (subject != null) {
9872            sb.append("Subject: ").append(subject).append("\n");
9873        }
9874        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9875        if (Debug.isDebuggerConnected()) {
9876            sb.append("Debugger: Connected\n");
9877        }
9878        sb.append("\n");
9879
9880        // Do the rest in a worker thread to avoid blocking the caller on I/O
9881        // (After this point, we shouldn't access AMS internal data structures.)
9882        Thread worker = new Thread("Error dump: " + dropboxTag) {
9883            @Override
9884            public void run() {
9885                if (report != null) {
9886                    sb.append(report);
9887                }
9888                if (logFile != null) {
9889                    try {
9890                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9891                                    "\n\n[[TRUNCATED]]"));
9892                    } catch (IOException e) {
9893                        Slog.e(TAG, "Error reading " + logFile, e);
9894                    }
9895                }
9896                if (crashInfo != null && crashInfo.stackTrace != null) {
9897                    sb.append(crashInfo.stackTrace);
9898                }
9899
9900                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9901                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9902                if (lines > 0) {
9903                    sb.append("\n");
9904
9905                    // Merge several logcat streams, and take the last N lines
9906                    InputStreamReader input = null;
9907                    try {
9908                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9909                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9910                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9911
9912                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9913                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9914                        input = new InputStreamReader(logcat.getInputStream());
9915
9916                        int num;
9917                        char[] buf = new char[8192];
9918                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9919                    } catch (IOException e) {
9920                        Slog.e(TAG, "Error running logcat", e);
9921                    } finally {
9922                        if (input != null) try { input.close(); } catch (IOException e) {}
9923                    }
9924                }
9925
9926                dbox.addText(dropboxTag, sb.toString());
9927            }
9928        };
9929
9930        if (process == null) {
9931            // If process is null, we are being called from some internal code
9932            // and may be about to die -- run this synchronously.
9933            worker.run();
9934        } else {
9935            worker.start();
9936        }
9937    }
9938
9939    /**
9940     * Bring up the "unexpected error" dialog box for a crashing app.
9941     * Deal with edge cases (intercepts from instrumented applications,
9942     * ActivityController, error intent receivers, that sort of thing).
9943     * @param r the application crashing
9944     * @param crashInfo describing the failure
9945     */
9946    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9947        long timeMillis = System.currentTimeMillis();
9948        String shortMsg = crashInfo.exceptionClassName;
9949        String longMsg = crashInfo.exceptionMessage;
9950        String stackTrace = crashInfo.stackTrace;
9951        if (shortMsg != null && longMsg != null) {
9952            longMsg = shortMsg + ": " + longMsg;
9953        } else if (shortMsg != null) {
9954            longMsg = shortMsg;
9955        }
9956
9957        AppErrorResult result = new AppErrorResult();
9958        synchronized (this) {
9959            if (mController != null) {
9960                try {
9961                    String name = r != null ? r.processName : null;
9962                    int pid = r != null ? r.pid : Binder.getCallingPid();
9963                    if (!mController.appCrashed(name, pid,
9964                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9965                        Slog.w(TAG, "Force-killing crashed app " + name
9966                                + " at watcher's request");
9967                        Process.killProcess(pid);
9968                        return;
9969                    }
9970                } catch (RemoteException e) {
9971                    mController = null;
9972                    Watchdog.getInstance().setActivityController(null);
9973                }
9974            }
9975
9976            final long origId = Binder.clearCallingIdentity();
9977
9978            // If this process is running instrumentation, finish it.
9979            if (r != null && r.instrumentationClass != null) {
9980                Slog.w(TAG, "Error in app " + r.processName
9981                      + " running instrumentation " + r.instrumentationClass + ":");
9982                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
9983                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
9984                Bundle info = new Bundle();
9985                info.putString("shortMsg", shortMsg);
9986                info.putString("longMsg", longMsg);
9987                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
9988                Binder.restoreCallingIdentity(origId);
9989                return;
9990            }
9991
9992            // If we can't identify the process or it's already exceeded its crash quota,
9993            // quit right away without showing a crash dialog.
9994            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
9995                Binder.restoreCallingIdentity(origId);
9996                return;
9997            }
9998
9999            Message msg = Message.obtain();
10000            msg.what = SHOW_ERROR_MSG;
10001            HashMap data = new HashMap();
10002            data.put("result", result);
10003            data.put("app", r);
10004            msg.obj = data;
10005            mHandler.sendMessage(msg);
10006
10007            Binder.restoreCallingIdentity(origId);
10008        }
10009
10010        int res = result.get();
10011
10012        Intent appErrorIntent = null;
10013        synchronized (this) {
10014            if (r != null && !r.isolated) {
10015                // XXX Can't keep track of crash time for isolated processes,
10016                // since they don't have a persistent identity.
10017                mProcessCrashTimes.put(r.info.processName, r.uid,
10018                        SystemClock.uptimeMillis());
10019            }
10020            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10021                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10022            }
10023        }
10024
10025        if (appErrorIntent != null) {
10026            try {
10027                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10028            } catch (ActivityNotFoundException e) {
10029                Slog.w(TAG, "bug report receiver dissappeared", e);
10030            }
10031        }
10032    }
10033
10034    Intent createAppErrorIntentLocked(ProcessRecord r,
10035            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10036        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10037        if (report == null) {
10038            return null;
10039        }
10040        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10041        result.setComponent(r.errorReportReceiver);
10042        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10043        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10044        return result;
10045    }
10046
10047    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10048            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10049        if (r.errorReportReceiver == null) {
10050            return null;
10051        }
10052
10053        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10054            return null;
10055        }
10056
10057        ApplicationErrorReport report = new ApplicationErrorReport();
10058        report.packageName = r.info.packageName;
10059        report.installerPackageName = r.errorReportReceiver.getPackageName();
10060        report.processName = r.processName;
10061        report.time = timeMillis;
10062        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10063
10064        if (r.crashing || r.forceCrashReport) {
10065            report.type = ApplicationErrorReport.TYPE_CRASH;
10066            report.crashInfo = crashInfo;
10067        } else if (r.notResponding) {
10068            report.type = ApplicationErrorReport.TYPE_ANR;
10069            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10070
10071            report.anrInfo.activity = r.notRespondingReport.tag;
10072            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10073            report.anrInfo.info = r.notRespondingReport.longMsg;
10074        }
10075
10076        return report;
10077    }
10078
10079    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10080        enforceNotIsolatedCaller("getProcessesInErrorState");
10081        // assume our apps are happy - lazy create the list
10082        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10083
10084        final boolean allUsers = ActivityManager.checkUidPermission(
10085                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10086                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10087        int userId = UserHandle.getUserId(Binder.getCallingUid());
10088
10089        synchronized (this) {
10090
10091            // iterate across all processes
10092            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10093                ProcessRecord app = mLruProcesses.get(i);
10094                if (!allUsers && app.userId != userId) {
10095                    continue;
10096                }
10097                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10098                    // This one's in trouble, so we'll generate a report for it
10099                    // crashes are higher priority (in case there's a crash *and* an anr)
10100                    ActivityManager.ProcessErrorStateInfo report = null;
10101                    if (app.crashing) {
10102                        report = app.crashingReport;
10103                    } else if (app.notResponding) {
10104                        report = app.notRespondingReport;
10105                    }
10106
10107                    if (report != null) {
10108                        if (errList == null) {
10109                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10110                        }
10111                        errList.add(report);
10112                    } else {
10113                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10114                                " crashing = " + app.crashing +
10115                                " notResponding = " + app.notResponding);
10116                    }
10117                }
10118            }
10119        }
10120
10121        return errList;
10122    }
10123
10124    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10125        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10126            if (currApp != null) {
10127                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10128            }
10129            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10130        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10131            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10132        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10133            if (currApp != null) {
10134                currApp.lru = 0;
10135            }
10136            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10137        } else if (adj >= ProcessList.SERVICE_ADJ) {
10138            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10139        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10140            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10141        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10142            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10143        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10144            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10145        } else {
10146            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10147        }
10148    }
10149
10150    private void fillInProcMemInfo(ProcessRecord app,
10151            ActivityManager.RunningAppProcessInfo outInfo) {
10152        outInfo.pid = app.pid;
10153        outInfo.uid = app.info.uid;
10154        if (mHeavyWeightProcess == app) {
10155            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10156        }
10157        if (app.persistent) {
10158            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10159        }
10160        if (app.activities.size() > 0) {
10161            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10162        }
10163        outInfo.lastTrimLevel = app.trimMemoryLevel;
10164        int adj = app.curAdj;
10165        outInfo.importance = oomAdjToImportance(adj, outInfo);
10166        outInfo.importanceReasonCode = app.adjTypeCode;
10167    }
10168
10169    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10170        enforceNotIsolatedCaller("getRunningAppProcesses");
10171        // Lazy instantiation of list
10172        List<ActivityManager.RunningAppProcessInfo> runList = null;
10173        final boolean allUsers = ActivityManager.checkUidPermission(
10174                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10175                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10176        int userId = UserHandle.getUserId(Binder.getCallingUid());
10177        synchronized (this) {
10178            // Iterate across all processes
10179            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10180                ProcessRecord app = mLruProcesses.get(i);
10181                if (!allUsers && app.userId != userId) {
10182                    continue;
10183                }
10184                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10185                    // Generate process state info for running application
10186                    ActivityManager.RunningAppProcessInfo currApp =
10187                        new ActivityManager.RunningAppProcessInfo(app.processName,
10188                                app.pid, app.getPackageList());
10189                    fillInProcMemInfo(app, currApp);
10190                    if (app.adjSource instanceof ProcessRecord) {
10191                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10192                        currApp.importanceReasonImportance = oomAdjToImportance(
10193                                app.adjSourceOom, null);
10194                    } else if (app.adjSource instanceof ActivityRecord) {
10195                        ActivityRecord r = (ActivityRecord)app.adjSource;
10196                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10197                    }
10198                    if (app.adjTarget instanceof ComponentName) {
10199                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10200                    }
10201                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10202                    //        + " lru=" + currApp.lru);
10203                    if (runList == null) {
10204                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10205                    }
10206                    runList.add(currApp);
10207                }
10208            }
10209        }
10210        return runList;
10211    }
10212
10213    public List<ApplicationInfo> getRunningExternalApplications() {
10214        enforceNotIsolatedCaller("getRunningExternalApplications");
10215        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10216        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10217        if (runningApps != null && runningApps.size() > 0) {
10218            Set<String> extList = new HashSet<String>();
10219            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10220                if (app.pkgList != null) {
10221                    for (String pkg : app.pkgList) {
10222                        extList.add(pkg);
10223                    }
10224                }
10225            }
10226            IPackageManager pm = AppGlobals.getPackageManager();
10227            for (String pkg : extList) {
10228                try {
10229                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10230                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10231                        retList.add(info);
10232                    }
10233                } catch (RemoteException e) {
10234                }
10235            }
10236        }
10237        return retList;
10238    }
10239
10240    @Override
10241    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10242        enforceNotIsolatedCaller("getMyMemoryState");
10243        synchronized (this) {
10244            ProcessRecord proc;
10245            synchronized (mPidsSelfLocked) {
10246                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10247            }
10248            fillInProcMemInfo(proc, outInfo);
10249        }
10250    }
10251
10252    @Override
10253    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10254        if (checkCallingPermission(android.Manifest.permission.DUMP)
10255                != PackageManager.PERMISSION_GRANTED) {
10256            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10257                    + Binder.getCallingPid()
10258                    + ", uid=" + Binder.getCallingUid()
10259                    + " without permission "
10260                    + android.Manifest.permission.DUMP);
10261            return;
10262        }
10263
10264        boolean dumpAll = false;
10265        boolean dumpClient = false;
10266        String dumpPackage = null;
10267
10268        int opti = 0;
10269        while (opti < args.length) {
10270            String opt = args[opti];
10271            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10272                break;
10273            }
10274            opti++;
10275            if ("-a".equals(opt)) {
10276                dumpAll = true;
10277            } else if ("-c".equals(opt)) {
10278                dumpClient = true;
10279            } else if ("-h".equals(opt)) {
10280                pw.println("Activity manager dump options:");
10281                pw.println("  [-a] [-c] [-h] [cmd] ...");
10282                pw.println("  cmd may be one of:");
10283                pw.println("    a[ctivities]: activity stack state");
10284                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10285                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10286                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10287                pw.println("    o[om]: out of memory management");
10288                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10289                pw.println("    provider [COMP_SPEC]: provider client-side state");
10290                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10291                pw.println("    service [COMP_SPEC]: service client-side state");
10292                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10293                pw.println("    all: dump all activities");
10294                pw.println("    top: dump the top activity");
10295                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10296                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10297                pw.println("    a partial substring in a component name, a");
10298                pw.println("    hex object identifier.");
10299                pw.println("  -a: include all available server state.");
10300                pw.println("  -c: include client state.");
10301                return;
10302            } else {
10303                pw.println("Unknown argument: " + opt + "; use -h for help");
10304            }
10305        }
10306
10307        long origId = Binder.clearCallingIdentity();
10308        boolean more = false;
10309        // Is the caller requesting to dump a particular piece of data?
10310        if (opti < args.length) {
10311            String cmd = args[opti];
10312            opti++;
10313            if ("activities".equals(cmd) || "a".equals(cmd)) {
10314                synchronized (this) {
10315                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10316                }
10317            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10318                String[] newArgs;
10319                String name;
10320                if (opti >= args.length) {
10321                    name = null;
10322                    newArgs = EMPTY_STRING_ARRAY;
10323                } else {
10324                    name = args[opti];
10325                    opti++;
10326                    newArgs = new String[args.length - opti];
10327                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10328                            args.length - opti);
10329                }
10330                synchronized (this) {
10331                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10332                }
10333            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10334                String[] newArgs;
10335                String name;
10336                if (opti >= args.length) {
10337                    name = null;
10338                    newArgs = EMPTY_STRING_ARRAY;
10339                } else {
10340                    name = args[opti];
10341                    opti++;
10342                    newArgs = new String[args.length - opti];
10343                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10344                            args.length - opti);
10345                }
10346                synchronized (this) {
10347                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10348                }
10349            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10350                String[] newArgs;
10351                String name;
10352                if (opti >= args.length) {
10353                    name = null;
10354                    newArgs = EMPTY_STRING_ARRAY;
10355                } else {
10356                    name = args[opti];
10357                    opti++;
10358                    newArgs = new String[args.length - opti];
10359                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10360                            args.length - opti);
10361                }
10362                synchronized (this) {
10363                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10364                }
10365            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10366                synchronized (this) {
10367                    dumpOomLocked(fd, pw, args, opti, true);
10368                }
10369            } else if ("provider".equals(cmd)) {
10370                String[] newArgs;
10371                String name;
10372                if (opti >= args.length) {
10373                    name = null;
10374                    newArgs = EMPTY_STRING_ARRAY;
10375                } else {
10376                    name = args[opti];
10377                    opti++;
10378                    newArgs = new String[args.length - opti];
10379                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10380                }
10381                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10382                    pw.println("No providers match: " + name);
10383                    pw.println("Use -h for help.");
10384                }
10385            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10386                synchronized (this) {
10387                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10388                }
10389            } else if ("service".equals(cmd)) {
10390                String[] newArgs;
10391                String name;
10392                if (opti >= args.length) {
10393                    name = null;
10394                    newArgs = EMPTY_STRING_ARRAY;
10395                } else {
10396                    name = args[opti];
10397                    opti++;
10398                    newArgs = new String[args.length - opti];
10399                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10400                            args.length - opti);
10401                }
10402                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10403                    pw.println("No services match: " + name);
10404                    pw.println("Use -h for help.");
10405                }
10406            } else if ("package".equals(cmd)) {
10407                String[] newArgs;
10408                if (opti >= args.length) {
10409                    pw.println("package: no package name specified");
10410                    pw.println("Use -h for help.");
10411                } else {
10412                    dumpPackage = args[opti];
10413                    opti++;
10414                    newArgs = new String[args.length - opti];
10415                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10416                            args.length - opti);
10417                    args = newArgs;
10418                    opti = 0;
10419                    more = true;
10420                }
10421            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10422                synchronized (this) {
10423                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10424                }
10425            } else {
10426                // Dumping a single activity?
10427                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10428                    pw.println("Bad activity command, or no activities match: " + cmd);
10429                    pw.println("Use -h for help.");
10430                }
10431            }
10432            if (!more) {
10433                Binder.restoreCallingIdentity(origId);
10434                return;
10435            }
10436        }
10437
10438        // No piece of data specified, dump everything.
10439        synchronized (this) {
10440            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10441            pw.println();
10442            if (dumpAll) {
10443                pw.println("-------------------------------------------------------------------------------");
10444            }
10445            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10446            pw.println();
10447            if (dumpAll) {
10448                pw.println("-------------------------------------------------------------------------------");
10449            }
10450            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10451            pw.println();
10452            if (dumpAll) {
10453                pw.println("-------------------------------------------------------------------------------");
10454            }
10455            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10456            pw.println();
10457            if (dumpAll) {
10458                pw.println("-------------------------------------------------------------------------------");
10459            }
10460            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10461            pw.println();
10462            if (dumpAll) {
10463                pw.println("-------------------------------------------------------------------------------");
10464            }
10465            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10466        }
10467        Binder.restoreCallingIdentity(origId);
10468    }
10469
10470    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10471            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10472        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10473
10474        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10475                dumpPackage);
10476        boolean needSep = printedAnything;
10477
10478        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10479                dumpPackage, needSep, "  mFocusedActivity: ");
10480        if (printed) {
10481            printedAnything = true;
10482            needSep = false;
10483        }
10484
10485        if (dumpPackage == null) {
10486            if (needSep) {
10487                pw.println();
10488            }
10489            needSep = true;
10490            printedAnything = true;
10491            mStackSupervisor.dump(pw, "  ");
10492        }
10493
10494        if (mRecentTasks.size() > 0) {
10495            boolean printedHeader = false;
10496
10497            final int N = mRecentTasks.size();
10498            for (int i=0; i<N; i++) {
10499                TaskRecord tr = mRecentTasks.get(i);
10500                if (dumpPackage != null) {
10501                    if (tr.realActivity == null ||
10502                            !dumpPackage.equals(tr.realActivity)) {
10503                        continue;
10504                    }
10505                }
10506                if (!printedHeader) {
10507                    if (needSep) {
10508                        pw.println();
10509                    }
10510                    pw.println("  Recent tasks:");
10511                    printedHeader = true;
10512                    printedAnything = true;
10513                }
10514                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10515                        pw.println(tr);
10516                if (dumpAll) {
10517                    mRecentTasks.get(i).dump(pw, "    ");
10518                }
10519            }
10520        }
10521
10522        if (!printedAnything) {
10523            pw.println("  (nothing)");
10524        }
10525    }
10526
10527    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10528            int opti, boolean dumpAll, String dumpPackage) {
10529        boolean needSep = false;
10530        boolean printedAnything = false;
10531        int numPers = 0;
10532
10533        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10534
10535        if (dumpAll) {
10536            final int NP = mProcessNames.getMap().size();
10537            for (int ip=0; ip<NP; ip++) {
10538                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10539                final int NA = procs.size();
10540                for (int ia=0; ia<NA; ia++) {
10541                    ProcessRecord r = procs.valueAt(ia);
10542                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10543                        continue;
10544                    }
10545                    if (!needSep) {
10546                        pw.println("  All known processes:");
10547                        needSep = true;
10548                        printedAnything = true;
10549                    }
10550                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10551                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10552                        pw.print(" "); pw.println(r);
10553                    r.dump(pw, "    ");
10554                    if (r.persistent) {
10555                        numPers++;
10556                    }
10557                }
10558            }
10559        }
10560
10561        if (mIsolatedProcesses.size() > 0) {
10562            boolean printed = false;
10563            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10564                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10565                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10566                    continue;
10567                }
10568                if (!printed) {
10569                    if (needSep) {
10570                        pw.println();
10571                    }
10572                    pw.println("  Isolated process list (sorted by uid):");
10573                    printedAnything = true;
10574                    printed = true;
10575                    needSep = true;
10576                }
10577                pw.println(String.format("%sIsolated #%2d: %s",
10578                        "    ", i, r.toString()));
10579            }
10580        }
10581
10582        if (mLruProcesses.size() > 0) {
10583            if (needSep) {
10584                pw.println();
10585            }
10586            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10587                    pw.print(" total, non-act at ");
10588                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10589                    pw.print(", non-svc at ");
10590                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10591                    pw.println("):");
10592            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10593            needSep = true;
10594            printedAnything = true;
10595        }
10596
10597        if (dumpAll || dumpPackage != null) {
10598            synchronized (mPidsSelfLocked) {
10599                boolean printed = false;
10600                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10601                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10602                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10603                        continue;
10604                    }
10605                    if (!printed) {
10606                        if (needSep) pw.println();
10607                        needSep = true;
10608                        pw.println("  PID mappings:");
10609                        printed = true;
10610                        printedAnything = true;
10611                    }
10612                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10613                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10614                }
10615            }
10616        }
10617
10618        if (mForegroundProcesses.size() > 0) {
10619            synchronized (mPidsSelfLocked) {
10620                boolean printed = false;
10621                for (int i=0; i<mForegroundProcesses.size(); i++) {
10622                    ProcessRecord r = mPidsSelfLocked.get(
10623                            mForegroundProcesses.valueAt(i).pid);
10624                    if (dumpPackage != null && (r == null
10625                            || !r.pkgList.containsKey(dumpPackage))) {
10626                        continue;
10627                    }
10628                    if (!printed) {
10629                        if (needSep) pw.println();
10630                        needSep = true;
10631                        pw.println("  Foreground Processes:");
10632                        printed = true;
10633                        printedAnything = true;
10634                    }
10635                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10636                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10637                }
10638            }
10639        }
10640
10641        if (mPersistentStartingProcesses.size() > 0) {
10642            if (needSep) pw.println();
10643            needSep = true;
10644            printedAnything = true;
10645            pw.println("  Persisent processes that are starting:");
10646            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10647                    "Starting Norm", "Restarting PERS", dumpPackage);
10648        }
10649
10650        if (mRemovedProcesses.size() > 0) {
10651            if (needSep) pw.println();
10652            needSep = true;
10653            printedAnything = true;
10654            pw.println("  Processes that are being removed:");
10655            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10656                    "Removed Norm", "Removed PERS", dumpPackage);
10657        }
10658
10659        if (mProcessesOnHold.size() > 0) {
10660            if (needSep) pw.println();
10661            needSep = true;
10662            printedAnything = true;
10663            pw.println("  Processes that are on old until the system is ready:");
10664            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10665                    "OnHold Norm", "OnHold PERS", dumpPackage);
10666        }
10667
10668        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10669
10670        if (mProcessCrashTimes.getMap().size() > 0) {
10671            boolean printed = false;
10672            long now = SystemClock.uptimeMillis();
10673            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10674            final int NP = pmap.size();
10675            for (int ip=0; ip<NP; ip++) {
10676                String pname = pmap.keyAt(ip);
10677                SparseArray<Long> uids = pmap.valueAt(ip);
10678                final int N = uids.size();
10679                for (int i=0; i<N; i++) {
10680                    int puid = uids.keyAt(i);
10681                    ProcessRecord r = mProcessNames.get(pname, puid);
10682                    if (dumpPackage != null && (r == null
10683                            || !r.pkgList.containsKey(dumpPackage))) {
10684                        continue;
10685                    }
10686                    if (!printed) {
10687                        if (needSep) pw.println();
10688                        needSep = true;
10689                        pw.println("  Time since processes crashed:");
10690                        printed = true;
10691                        printedAnything = true;
10692                    }
10693                    pw.print("    Process "); pw.print(pname);
10694                            pw.print(" uid "); pw.print(puid);
10695                            pw.print(": last crashed ");
10696                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10697                            pw.println(" ago");
10698                }
10699            }
10700        }
10701
10702        if (mBadProcesses.getMap().size() > 0) {
10703            boolean printed = false;
10704            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10705            final int NP = pmap.size();
10706            for (int ip=0; ip<NP; ip++) {
10707                String pname = pmap.keyAt(ip);
10708                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10709                final int N = uids.size();
10710                for (int i=0; i<N; i++) {
10711                    int puid = uids.keyAt(i);
10712                    ProcessRecord r = mProcessNames.get(pname, puid);
10713                    if (dumpPackage != null && (r == null
10714                            || !r.pkgList.containsKey(dumpPackage))) {
10715                        continue;
10716                    }
10717                    if (!printed) {
10718                        if (needSep) pw.println();
10719                        needSep = true;
10720                        pw.println("  Bad processes:");
10721                        printedAnything = true;
10722                    }
10723                    BadProcessInfo info = uids.valueAt(i);
10724                    pw.print("    Bad process "); pw.print(pname);
10725                            pw.print(" uid "); pw.print(puid);
10726                            pw.print(": crashed at time "); pw.println(info.time);
10727                    if (info.shortMsg != null) {
10728                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10729                    }
10730                    if (info.longMsg != null) {
10731                        pw.print("      Long msg: "); pw.println(info.longMsg);
10732                    }
10733                    if (info.stack != null) {
10734                        pw.println("      Stack:");
10735                        int lastPos = 0;
10736                        for (int pos=0; pos<info.stack.length(); pos++) {
10737                            if (info.stack.charAt(pos) == '\n') {
10738                                pw.print("        ");
10739                                pw.write(info.stack, lastPos, pos-lastPos);
10740                                pw.println();
10741                                lastPos = pos+1;
10742                            }
10743                        }
10744                        if (lastPos < info.stack.length()) {
10745                            pw.print("        ");
10746                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10747                            pw.println();
10748                        }
10749                    }
10750                }
10751            }
10752        }
10753
10754        if (dumpPackage == null) {
10755            pw.println();
10756            needSep = false;
10757            pw.println("  mStartedUsers:");
10758            for (int i=0; i<mStartedUsers.size(); i++) {
10759                UserStartedState uss = mStartedUsers.valueAt(i);
10760                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10761                        pw.print(": "); uss.dump("", pw);
10762            }
10763            pw.print("  mStartedUserArray: [");
10764            for (int i=0; i<mStartedUserArray.length; i++) {
10765                if (i > 0) pw.print(", ");
10766                pw.print(mStartedUserArray[i]);
10767            }
10768            pw.println("]");
10769            pw.print("  mUserLru: [");
10770            for (int i=0; i<mUserLru.size(); i++) {
10771                if (i > 0) pw.print(", ");
10772                pw.print(mUserLru.get(i));
10773            }
10774            pw.println("]");
10775            if (dumpAll) {
10776                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10777            }
10778        }
10779        if (mHomeProcess != null && (dumpPackage == null
10780                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10781            if (needSep) {
10782                pw.println();
10783                needSep = false;
10784            }
10785            pw.println("  mHomeProcess: " + mHomeProcess);
10786        }
10787        if (mPreviousProcess != null && (dumpPackage == null
10788                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10789            if (needSep) {
10790                pw.println();
10791                needSep = false;
10792            }
10793            pw.println("  mPreviousProcess: " + mPreviousProcess);
10794        }
10795        if (dumpAll) {
10796            StringBuilder sb = new StringBuilder(128);
10797            sb.append("  mPreviousProcessVisibleTime: ");
10798            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10799            pw.println(sb);
10800        }
10801        if (mHeavyWeightProcess != null && (dumpPackage == null
10802                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10803            if (needSep) {
10804                pw.println();
10805                needSep = false;
10806            }
10807            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10808        }
10809        if (dumpPackage == null) {
10810            pw.println("  mConfiguration: " + mConfiguration);
10811        }
10812        if (dumpAll) {
10813            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10814            if (mCompatModePackages.getPackages().size() > 0) {
10815                boolean printed = false;
10816                for (Map.Entry<String, Integer> entry
10817                        : mCompatModePackages.getPackages().entrySet()) {
10818                    String pkg = entry.getKey();
10819                    int mode = entry.getValue();
10820                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10821                        continue;
10822                    }
10823                    if (!printed) {
10824                        pw.println("  mScreenCompatPackages:");
10825                        printed = true;
10826                    }
10827                    pw.print("    "); pw.print(pkg); pw.print(": ");
10828                            pw.print(mode); pw.println();
10829                }
10830            }
10831        }
10832        if (dumpPackage == null) {
10833            if (mSleeping || mWentToSleep || mLockScreenShown) {
10834                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10835                        + " mLockScreenShown " + mLockScreenShown);
10836            }
10837            if (mShuttingDown) {
10838                pw.println("  mShuttingDown=" + mShuttingDown);
10839            }
10840        }
10841        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10842                || mOrigWaitForDebugger) {
10843            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10844                    || dumpPackage.equals(mOrigDebugApp)) {
10845                if (needSep) {
10846                    pw.println();
10847                    needSep = false;
10848                }
10849                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10850                        + " mDebugTransient=" + mDebugTransient
10851                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10852            }
10853        }
10854        if (mOpenGlTraceApp != null) {
10855            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10856                if (needSep) {
10857                    pw.println();
10858                    needSep = false;
10859                }
10860                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10861            }
10862        }
10863        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10864                || mProfileFd != null) {
10865            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10866                if (needSep) {
10867                    pw.println();
10868                    needSep = false;
10869                }
10870                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10871                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10872                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10873                        + mAutoStopProfiler);
10874            }
10875        }
10876        if (dumpPackage == null) {
10877            if (mAlwaysFinishActivities || mController != null) {
10878                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10879                        + " mController=" + mController);
10880            }
10881            if (dumpAll) {
10882                pw.println("  Total persistent processes: " + numPers);
10883                pw.println("  mProcessesReady=" + mProcessesReady
10884                        + " mSystemReady=" + mSystemReady);
10885                pw.println("  mBooting=" + mBooting
10886                        + " mBooted=" + mBooted
10887                        + " mFactoryTest=" + mFactoryTest);
10888                pw.print("  mLastPowerCheckRealtime=");
10889                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10890                        pw.println("");
10891                pw.print("  mLastPowerCheckUptime=");
10892                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10893                        pw.println("");
10894                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10895                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10896                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10897                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10898                        + " (" + mLruProcesses.size() + " total)"
10899                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10900                        + " mNumServiceProcs=" + mNumServiceProcs
10901                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10902                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10903                        + " mLastMemoryLevel" + mLastMemoryLevel
10904                        + " mLastNumProcesses" + mLastNumProcesses);
10905                long now = SystemClock.uptimeMillis();
10906                pw.print("  mLastIdleTime=");
10907                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10908                        pw.print(" mLowRamSinceLastIdle=");
10909                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10910                        pw.println();
10911            }
10912        }
10913
10914        if (!printedAnything) {
10915            pw.println("  (nothing)");
10916        }
10917    }
10918
10919    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10920            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10921        if (mProcessesToGc.size() > 0) {
10922            boolean printed = false;
10923            long now = SystemClock.uptimeMillis();
10924            for (int i=0; i<mProcessesToGc.size(); i++) {
10925                ProcessRecord proc = mProcessesToGc.get(i);
10926                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10927                    continue;
10928                }
10929                if (!printed) {
10930                    if (needSep) pw.println();
10931                    needSep = true;
10932                    pw.println("  Processes that are waiting to GC:");
10933                    printed = true;
10934                }
10935                pw.print("    Process "); pw.println(proc);
10936                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10937                        pw.print(", last gced=");
10938                        pw.print(now-proc.lastRequestedGc);
10939                        pw.print(" ms ago, last lowMem=");
10940                        pw.print(now-proc.lastLowMemory);
10941                        pw.println(" ms ago");
10942
10943            }
10944        }
10945        return needSep;
10946    }
10947
10948    void printOomLevel(PrintWriter pw, String name, int adj) {
10949        pw.print("    ");
10950        if (adj >= 0) {
10951            pw.print(' ');
10952            if (adj < 10) pw.print(' ');
10953        } else {
10954            if (adj > -10) pw.print(' ');
10955        }
10956        pw.print(adj);
10957        pw.print(": ");
10958        pw.print(name);
10959        pw.print(" (");
10960        pw.print(mProcessList.getMemLevel(adj)/1024);
10961        pw.println(" kB)");
10962    }
10963
10964    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10965            int opti, boolean dumpAll) {
10966        boolean needSep = false;
10967
10968        if (mLruProcesses.size() > 0) {
10969            if (needSep) pw.println();
10970            needSep = true;
10971            pw.println("  OOM levels:");
10972            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10973            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10974            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10975            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10976            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10977            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10978            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10979            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10980            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
10981            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
10982            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
10983            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
10984            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
10985
10986            if (needSep) pw.println();
10987            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
10988                    pw.print(" total, non-act at ");
10989                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10990                    pw.print(", non-svc at ");
10991                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10992                    pw.println("):");
10993            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
10994            needSep = true;
10995        }
10996
10997        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
10998
10999        pw.println();
11000        pw.println("  mHomeProcess: " + mHomeProcess);
11001        pw.println("  mPreviousProcess: " + mPreviousProcess);
11002        if (mHeavyWeightProcess != null) {
11003            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11004        }
11005
11006        return true;
11007    }
11008
11009    /**
11010     * There are three ways to call this:
11011     *  - no provider specified: dump all the providers
11012     *  - a flattened component name that matched an existing provider was specified as the
11013     *    first arg: dump that one provider
11014     *  - the first arg isn't the flattened component name of an existing provider:
11015     *    dump all providers whose component contains the first arg as a substring
11016     */
11017    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11018            int opti, boolean dumpAll) {
11019        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11020    }
11021
11022    static class ItemMatcher {
11023        ArrayList<ComponentName> components;
11024        ArrayList<String> strings;
11025        ArrayList<Integer> objects;
11026        boolean all;
11027
11028        ItemMatcher() {
11029            all = true;
11030        }
11031
11032        void build(String name) {
11033            ComponentName componentName = ComponentName.unflattenFromString(name);
11034            if (componentName != null) {
11035                if (components == null) {
11036                    components = new ArrayList<ComponentName>();
11037                }
11038                components.add(componentName);
11039                all = false;
11040            } else {
11041                int objectId = 0;
11042                // Not a '/' separated full component name; maybe an object ID?
11043                try {
11044                    objectId = Integer.parseInt(name, 16);
11045                    if (objects == null) {
11046                        objects = new ArrayList<Integer>();
11047                    }
11048                    objects.add(objectId);
11049                    all = false;
11050                } catch (RuntimeException e) {
11051                    // Not an integer; just do string match.
11052                    if (strings == null) {
11053                        strings = new ArrayList<String>();
11054                    }
11055                    strings.add(name);
11056                    all = false;
11057                }
11058            }
11059        }
11060
11061        int build(String[] args, int opti) {
11062            for (; opti<args.length; opti++) {
11063                String name = args[opti];
11064                if ("--".equals(name)) {
11065                    return opti+1;
11066                }
11067                build(name);
11068            }
11069            return opti;
11070        }
11071
11072        boolean match(Object object, ComponentName comp) {
11073            if (all) {
11074                return true;
11075            }
11076            if (components != null) {
11077                for (int i=0; i<components.size(); i++) {
11078                    if (components.get(i).equals(comp)) {
11079                        return true;
11080                    }
11081                }
11082            }
11083            if (objects != null) {
11084                for (int i=0; i<objects.size(); i++) {
11085                    if (System.identityHashCode(object) == objects.get(i)) {
11086                        return true;
11087                    }
11088                }
11089            }
11090            if (strings != null) {
11091                String flat = comp.flattenToString();
11092                for (int i=0; i<strings.size(); i++) {
11093                    if (flat.contains(strings.get(i))) {
11094                        return true;
11095                    }
11096                }
11097            }
11098            return false;
11099        }
11100    }
11101
11102    /**
11103     * There are three things that cmd can be:
11104     *  - a flattened component name that matches an existing activity
11105     *  - the cmd arg isn't the flattened component name of an existing activity:
11106     *    dump all activity whose component contains the cmd as a substring
11107     *  - A hex number of the ActivityRecord object instance.
11108     */
11109    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11110            int opti, boolean dumpAll) {
11111        ArrayList<ActivityRecord> activities;
11112
11113        synchronized (this) {
11114            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11115        }
11116
11117        if (activities.size() <= 0) {
11118            return false;
11119        }
11120
11121        String[] newArgs = new String[args.length - opti];
11122        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11123
11124        TaskRecord lastTask = null;
11125        boolean needSep = false;
11126        for (int i=activities.size()-1; i>=0; i--) {
11127            ActivityRecord r = activities.get(i);
11128            if (needSep) {
11129                pw.println();
11130            }
11131            needSep = true;
11132            synchronized (this) {
11133                if (lastTask != r.task) {
11134                    lastTask = r.task;
11135                    pw.print("TASK "); pw.print(lastTask.affinity);
11136                            pw.print(" id="); pw.println(lastTask.taskId);
11137                    if (dumpAll) {
11138                        lastTask.dump(pw, "  ");
11139                    }
11140                }
11141            }
11142            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11143        }
11144        return true;
11145    }
11146
11147    /**
11148     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11149     * there is a thread associated with the activity.
11150     */
11151    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11152            final ActivityRecord r, String[] args, boolean dumpAll) {
11153        String innerPrefix = prefix + "  ";
11154        synchronized (this) {
11155            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11156                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11157                    pw.print(" pid=");
11158                    if (r.app != null) pw.println(r.app.pid);
11159                    else pw.println("(not running)");
11160            if (dumpAll) {
11161                r.dump(pw, innerPrefix);
11162            }
11163        }
11164        if (r.app != null && r.app.thread != null) {
11165            // flush anything that is already in the PrintWriter since the thread is going
11166            // to write to the file descriptor directly
11167            pw.flush();
11168            try {
11169                TransferPipe tp = new TransferPipe();
11170                try {
11171                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11172                            r.appToken, innerPrefix, args);
11173                    tp.go(fd);
11174                } finally {
11175                    tp.kill();
11176                }
11177            } catch (IOException e) {
11178                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11179            } catch (RemoteException e) {
11180                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11181            }
11182        }
11183    }
11184
11185    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11186            int opti, boolean dumpAll, String dumpPackage) {
11187        boolean needSep = false;
11188        boolean onlyHistory = false;
11189        boolean printedAnything = false;
11190
11191        if ("history".equals(dumpPackage)) {
11192            if (opti < args.length && "-s".equals(args[opti])) {
11193                dumpAll = false;
11194            }
11195            onlyHistory = true;
11196            dumpPackage = null;
11197        }
11198
11199        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11200        if (!onlyHistory && dumpAll) {
11201            if (mRegisteredReceivers.size() > 0) {
11202                boolean printed = false;
11203                Iterator it = mRegisteredReceivers.values().iterator();
11204                while (it.hasNext()) {
11205                    ReceiverList r = (ReceiverList)it.next();
11206                    if (dumpPackage != null && (r.app == null ||
11207                            !dumpPackage.equals(r.app.info.packageName))) {
11208                        continue;
11209                    }
11210                    if (!printed) {
11211                        pw.println("  Registered Receivers:");
11212                        needSep = true;
11213                        printed = true;
11214                        printedAnything = true;
11215                    }
11216                    pw.print("  * "); pw.println(r);
11217                    r.dump(pw, "    ");
11218                }
11219            }
11220
11221            if (mReceiverResolver.dump(pw, needSep ?
11222                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11223                    "    ", dumpPackage, false)) {
11224                needSep = true;
11225                printedAnything = true;
11226            }
11227        }
11228
11229        for (BroadcastQueue q : mBroadcastQueues) {
11230            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11231            printedAnything |= needSep;
11232        }
11233
11234        needSep = true;
11235
11236        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11237            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11238                if (needSep) {
11239                    pw.println();
11240                }
11241                needSep = true;
11242                printedAnything = true;
11243                pw.print("  Sticky broadcasts for user ");
11244                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11245                StringBuilder sb = new StringBuilder(128);
11246                for (Map.Entry<String, ArrayList<Intent>> ent
11247                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11248                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11249                    if (dumpAll) {
11250                        pw.println(":");
11251                        ArrayList<Intent> intents = ent.getValue();
11252                        final int N = intents.size();
11253                        for (int i=0; i<N; i++) {
11254                            sb.setLength(0);
11255                            sb.append("    Intent: ");
11256                            intents.get(i).toShortString(sb, false, true, false, false);
11257                            pw.println(sb.toString());
11258                            Bundle bundle = intents.get(i).getExtras();
11259                            if (bundle != null) {
11260                                pw.print("      ");
11261                                pw.println(bundle.toString());
11262                            }
11263                        }
11264                    } else {
11265                        pw.println("");
11266                    }
11267                }
11268            }
11269        }
11270
11271        if (!onlyHistory && dumpAll) {
11272            pw.println();
11273            for (BroadcastQueue queue : mBroadcastQueues) {
11274                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11275                        + queue.mBroadcastsScheduled);
11276            }
11277            pw.println("  mHandler:");
11278            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11279            needSep = true;
11280            printedAnything = true;
11281        }
11282
11283        if (!printedAnything) {
11284            pw.println("  (nothing)");
11285        }
11286    }
11287
11288    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11289            int opti, boolean dumpAll, String dumpPackage) {
11290        boolean needSep;
11291        boolean printedAnything = false;
11292
11293        ItemMatcher matcher = new ItemMatcher();
11294        matcher.build(args, opti);
11295
11296        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11297
11298        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11299        printedAnything |= needSep;
11300
11301        if (mLaunchingProviders.size() > 0) {
11302            boolean printed = false;
11303            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11304                ContentProviderRecord r = mLaunchingProviders.get(i);
11305                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11306                    continue;
11307                }
11308                if (!printed) {
11309                    if (needSep) pw.println();
11310                    needSep = true;
11311                    pw.println("  Launching content providers:");
11312                    printed = true;
11313                    printedAnything = true;
11314                }
11315                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11316                        pw.println(r);
11317            }
11318        }
11319
11320        if (mGrantedUriPermissions.size() > 0) {
11321            boolean printed = false;
11322            int dumpUid = -2;
11323            if (dumpPackage != null) {
11324                try {
11325                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11326                } catch (NameNotFoundException e) {
11327                    dumpUid = -1;
11328                }
11329            }
11330            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11331                int uid = mGrantedUriPermissions.keyAt(i);
11332                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11333                    continue;
11334                }
11335                ArrayMap<Uri, UriPermission> perms
11336                        = mGrantedUriPermissions.valueAt(i);
11337                if (!printed) {
11338                    if (needSep) pw.println();
11339                    needSep = true;
11340                    pw.println("  Granted Uri Permissions:");
11341                    printed = true;
11342                    printedAnything = true;
11343                }
11344                pw.print("  * UID "); pw.print(uid);
11345                        pw.println(" holds:");
11346                for (UriPermission perm : perms.values()) {
11347                    pw.print("    "); pw.println(perm);
11348                    if (dumpAll) {
11349                        perm.dump(pw, "      ");
11350                    }
11351                }
11352            }
11353        }
11354
11355        if (!printedAnything) {
11356            pw.println("  (nothing)");
11357        }
11358    }
11359
11360    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11361            int opti, boolean dumpAll, String dumpPackage) {
11362        boolean printed = false;
11363
11364        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11365
11366        if (mIntentSenderRecords.size() > 0) {
11367            Iterator<WeakReference<PendingIntentRecord>> it
11368                    = mIntentSenderRecords.values().iterator();
11369            while (it.hasNext()) {
11370                WeakReference<PendingIntentRecord> ref = it.next();
11371                PendingIntentRecord rec = ref != null ? ref.get(): null;
11372                if (dumpPackage != null && (rec == null
11373                        || !dumpPackage.equals(rec.key.packageName))) {
11374                    continue;
11375                }
11376                printed = true;
11377                if (rec != null) {
11378                    pw.print("  * "); pw.println(rec);
11379                    if (dumpAll) {
11380                        rec.dump(pw, "    ");
11381                    }
11382                } else {
11383                    pw.print("  * "); pw.println(ref);
11384                }
11385            }
11386        }
11387
11388        if (!printed) {
11389            pw.println("  (nothing)");
11390        }
11391    }
11392
11393    private static final int dumpProcessList(PrintWriter pw,
11394            ActivityManagerService service, List list,
11395            String prefix, String normalLabel, String persistentLabel,
11396            String dumpPackage) {
11397        int numPers = 0;
11398        final int N = list.size()-1;
11399        for (int i=N; i>=0; i--) {
11400            ProcessRecord r = (ProcessRecord)list.get(i);
11401            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11402                continue;
11403            }
11404            pw.println(String.format("%s%s #%2d: %s",
11405                    prefix, (r.persistent ? persistentLabel : normalLabel),
11406                    i, r.toString()));
11407            if (r.persistent) {
11408                numPers++;
11409            }
11410        }
11411        return numPers;
11412    }
11413
11414    private static final boolean dumpProcessOomList(PrintWriter pw,
11415            ActivityManagerService service, List<ProcessRecord> origList,
11416            String prefix, String normalLabel, String persistentLabel,
11417            boolean inclDetails, String dumpPackage) {
11418
11419        ArrayList<Pair<ProcessRecord, Integer>> list
11420                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11421        for (int i=0; i<origList.size(); i++) {
11422            ProcessRecord r = origList.get(i);
11423            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11424                continue;
11425            }
11426            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11427        }
11428
11429        if (list.size() <= 0) {
11430            return false;
11431        }
11432
11433        Comparator<Pair<ProcessRecord, Integer>> comparator
11434                = new Comparator<Pair<ProcessRecord, Integer>>() {
11435            @Override
11436            public int compare(Pair<ProcessRecord, Integer> object1,
11437                    Pair<ProcessRecord, Integer> object2) {
11438                if (object1.first.setAdj != object2.first.setAdj) {
11439                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11440                }
11441                if (object1.second.intValue() != object2.second.intValue()) {
11442                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11443                }
11444                return 0;
11445            }
11446        };
11447
11448        Collections.sort(list, comparator);
11449
11450        final long curRealtime = SystemClock.elapsedRealtime();
11451        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11452        final long curUptime = SystemClock.uptimeMillis();
11453        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11454
11455        for (int i=list.size()-1; i>=0; i--) {
11456            ProcessRecord r = list.get(i).first;
11457            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11458            char schedGroup;
11459            switch (r.setSchedGroup) {
11460                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11461                    schedGroup = 'B';
11462                    break;
11463                case Process.THREAD_GROUP_DEFAULT:
11464                    schedGroup = 'F';
11465                    break;
11466                default:
11467                    schedGroup = '?';
11468                    break;
11469            }
11470            char foreground;
11471            if (r.foregroundActivities) {
11472                foreground = 'A';
11473            } else if (r.foregroundServices) {
11474                foreground = 'S';
11475            } else {
11476                foreground = ' ';
11477            }
11478            String procState = ProcessList.makeProcStateString(r.curProcState);
11479            pw.print(prefix);
11480            pw.print(r.persistent ? persistentLabel : normalLabel);
11481            pw.print(" #");
11482            int num = (origList.size()-1)-list.get(i).second;
11483            if (num < 10) pw.print(' ');
11484            pw.print(num);
11485            pw.print(": ");
11486            pw.print(oomAdj);
11487            pw.print(' ');
11488            pw.print(schedGroup);
11489            pw.print('/');
11490            pw.print(foreground);
11491            pw.print('/');
11492            pw.print(procState);
11493            pw.print(" trm:");
11494            if (r.trimMemoryLevel < 10) pw.print(' ');
11495            pw.print(r.trimMemoryLevel);
11496            pw.print(' ');
11497            pw.print(r.toShortString());
11498            pw.print(" (");
11499            pw.print(r.adjType);
11500            pw.println(')');
11501            if (r.adjSource != null || r.adjTarget != null) {
11502                pw.print(prefix);
11503                pw.print("    ");
11504                if (r.adjTarget instanceof ComponentName) {
11505                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11506                } else if (r.adjTarget != null) {
11507                    pw.print(r.adjTarget.toString());
11508                } else {
11509                    pw.print("{null}");
11510                }
11511                pw.print("<=");
11512                if (r.adjSource instanceof ProcessRecord) {
11513                    pw.print("Proc{");
11514                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11515                    pw.println("}");
11516                } else if (r.adjSource != null) {
11517                    pw.println(r.adjSource.toString());
11518                } else {
11519                    pw.println("{null}");
11520                }
11521            }
11522            if (inclDetails) {
11523                pw.print(prefix);
11524                pw.print("    ");
11525                pw.print("oom: max="); pw.print(r.maxAdj);
11526                pw.print(" curRaw="); pw.print(r.curRawAdj);
11527                pw.print(" setRaw="); pw.print(r.setRawAdj);
11528                pw.print(" cur="); pw.print(r.curAdj);
11529                pw.print(" set="); pw.println(r.setAdj);
11530                pw.print(prefix);
11531                pw.print("    ");
11532                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11533                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11534                pw.print(" lastPss="); pw.print(r.lastPss);
11535                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11536                pw.print(prefix);
11537                pw.print("    ");
11538                pw.print("keeping="); pw.print(r.keeping);
11539                pw.print(" cached="); pw.print(r.cached);
11540                pw.print(" empty="); pw.print(r.empty);
11541                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11542
11543                if (!r.keeping) {
11544                    if (r.lastWakeTime != 0) {
11545                        long wtime;
11546                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11547                        synchronized (stats) {
11548                            wtime = stats.getProcessWakeTime(r.info.uid,
11549                                    r.pid, curRealtime);
11550                        }
11551                        long timeUsed = wtime - r.lastWakeTime;
11552                        pw.print(prefix);
11553                        pw.print("    ");
11554                        pw.print("keep awake over ");
11555                        TimeUtils.formatDuration(realtimeSince, pw);
11556                        pw.print(" used ");
11557                        TimeUtils.formatDuration(timeUsed, pw);
11558                        pw.print(" (");
11559                        pw.print((timeUsed*100)/realtimeSince);
11560                        pw.println("%)");
11561                    }
11562                    if (r.lastCpuTime != 0) {
11563                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11564                        pw.print(prefix);
11565                        pw.print("    ");
11566                        pw.print("run cpu over ");
11567                        TimeUtils.formatDuration(uptimeSince, pw);
11568                        pw.print(" used ");
11569                        TimeUtils.formatDuration(timeUsed, pw);
11570                        pw.print(" (");
11571                        pw.print((timeUsed*100)/uptimeSince);
11572                        pw.println("%)");
11573                    }
11574                }
11575            }
11576        }
11577        return true;
11578    }
11579
11580    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11581        ArrayList<ProcessRecord> procs;
11582        synchronized (this) {
11583            if (args != null && args.length > start
11584                    && args[start].charAt(0) != '-') {
11585                procs = new ArrayList<ProcessRecord>();
11586                int pid = -1;
11587                try {
11588                    pid = Integer.parseInt(args[start]);
11589                } catch (NumberFormatException e) {
11590                }
11591                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11592                    ProcessRecord proc = mLruProcesses.get(i);
11593                    if (proc.pid == pid) {
11594                        procs.add(proc);
11595                    } else if (proc.processName.equals(args[start])) {
11596                        procs.add(proc);
11597                    }
11598                }
11599                if (procs.size() <= 0) {
11600                    return null;
11601                }
11602            } else {
11603                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11604            }
11605        }
11606        return procs;
11607    }
11608
11609    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11610            PrintWriter pw, String[] args) {
11611        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11612        if (procs == null) {
11613            pw.println("No process found for: " + args[0]);
11614            return;
11615        }
11616
11617        long uptime = SystemClock.uptimeMillis();
11618        long realtime = SystemClock.elapsedRealtime();
11619        pw.println("Applications Graphics Acceleration Info:");
11620        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11621
11622        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11623            ProcessRecord r = procs.get(i);
11624            if (r.thread != null) {
11625                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11626                pw.flush();
11627                try {
11628                    TransferPipe tp = new TransferPipe();
11629                    try {
11630                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11631                        tp.go(fd);
11632                    } finally {
11633                        tp.kill();
11634                    }
11635                } catch (IOException e) {
11636                    pw.println("Failure while dumping the app: " + r);
11637                    pw.flush();
11638                } catch (RemoteException e) {
11639                    pw.println("Got a RemoteException while dumping the app " + r);
11640                    pw.flush();
11641                }
11642            }
11643        }
11644    }
11645
11646    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11647        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11648        if (procs == null) {
11649            pw.println("No process found for: " + args[0]);
11650            return;
11651        }
11652
11653        pw.println("Applications Database Info:");
11654
11655        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11656            ProcessRecord r = procs.get(i);
11657            if (r.thread != null) {
11658                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11659                pw.flush();
11660                try {
11661                    TransferPipe tp = new TransferPipe();
11662                    try {
11663                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11664                        tp.go(fd);
11665                    } finally {
11666                        tp.kill();
11667                    }
11668                } catch (IOException e) {
11669                    pw.println("Failure while dumping the app: " + r);
11670                    pw.flush();
11671                } catch (RemoteException e) {
11672                    pw.println("Got a RemoteException while dumping the app " + r);
11673                    pw.flush();
11674                }
11675            }
11676        }
11677    }
11678
11679    final static class MemItem {
11680        final boolean isProc;
11681        final String label;
11682        final String shortLabel;
11683        final long pss;
11684        final int id;
11685        final boolean hasActivities;
11686        ArrayList<MemItem> subitems;
11687
11688        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11689                boolean _hasActivities) {
11690            isProc = true;
11691            label = _label;
11692            shortLabel = _shortLabel;
11693            pss = _pss;
11694            id = _id;
11695            hasActivities = _hasActivities;
11696        }
11697
11698        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11699            isProc = false;
11700            label = _label;
11701            shortLabel = _shortLabel;
11702            pss = _pss;
11703            id = _id;
11704            hasActivities = false;
11705        }
11706    }
11707
11708    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11709            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11710        if (sort && !isCompact) {
11711            Collections.sort(items, new Comparator<MemItem>() {
11712                @Override
11713                public int compare(MemItem lhs, MemItem rhs) {
11714                    if (lhs.pss < rhs.pss) {
11715                        return 1;
11716                    } else if (lhs.pss > rhs.pss) {
11717                        return -1;
11718                    }
11719                    return 0;
11720                }
11721            });
11722        }
11723
11724        for (int i=0; i<items.size(); i++) {
11725            MemItem mi = items.get(i);
11726            if (!isCompact) {
11727                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11728            } else if (mi.isProc) {
11729                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11730                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11731                pw.println(mi.hasActivities ? ",a" : ",e");
11732            } else {
11733                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11734                pw.println(mi.pss);
11735            }
11736            if (mi.subitems != null) {
11737                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11738                        true, isCompact);
11739            }
11740        }
11741    }
11742
11743    // These are in KB.
11744    static final long[] DUMP_MEM_BUCKETS = new long[] {
11745        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11746        120*1024, 160*1024, 200*1024,
11747        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11748        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11749    };
11750
11751    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11752            boolean stackLike) {
11753        int start = label.lastIndexOf('.');
11754        if (start >= 0) start++;
11755        else start = 0;
11756        int end = label.length();
11757        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11758            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11759                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11760                out.append(bucket);
11761                out.append(stackLike ? "MB." : "MB ");
11762                out.append(label, start, end);
11763                return;
11764            }
11765        }
11766        out.append(memKB/1024);
11767        out.append(stackLike ? "MB." : "MB ");
11768        out.append(label, start, end);
11769    }
11770
11771    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11772            ProcessList.NATIVE_ADJ,
11773            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11774            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11775            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11776            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11777            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11778    };
11779    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11780            "Native",
11781            "System", "Persistent", "Foreground",
11782            "Visible", "Perceptible",
11783            "Heavy Weight", "Backup",
11784            "A Services", "Home",
11785            "Previous", "B Services", "Cached"
11786    };
11787    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11788            "native",
11789            "sys", "pers", "fore",
11790            "vis", "percept",
11791            "heavy", "backup",
11792            "servicea", "home",
11793            "prev", "serviceb", "cached"
11794    };
11795
11796    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11797            long realtime, boolean isCheckinRequest, boolean isCompact) {
11798        if (isCheckinRequest || isCompact) {
11799            // short checkin version
11800            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11801        } else {
11802            pw.println("Applications Memory Usage (kB):");
11803            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11804        }
11805    }
11806
11807    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11808            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11809        boolean dumpDetails = false;
11810        boolean dumpFullDetails = false;
11811        boolean dumpDalvik = false;
11812        boolean oomOnly = false;
11813        boolean isCompact = false;
11814        boolean localOnly = false;
11815
11816        int opti = 0;
11817        while (opti < args.length) {
11818            String opt = args[opti];
11819            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11820                break;
11821            }
11822            opti++;
11823            if ("-a".equals(opt)) {
11824                dumpDetails = true;
11825                dumpFullDetails = true;
11826                dumpDalvik = true;
11827            } else if ("-d".equals(opt)) {
11828                dumpDalvik = true;
11829            } else if ("-c".equals(opt)) {
11830                isCompact = true;
11831            } else if ("--oom".equals(opt)) {
11832                oomOnly = true;
11833            } else if ("--local".equals(opt)) {
11834                localOnly = true;
11835            } else if ("-h".equals(opt)) {
11836                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11837                pw.println("  -a: include all available information for each process.");
11838                pw.println("  -d: include dalvik details when dumping process details.");
11839                pw.println("  -c: dump in a compact machine-parseable representation.");
11840                pw.println("  --oom: only show processes organized by oom adj.");
11841                pw.println("  --local: only collect details locally, don't call process.");
11842                pw.println("If [process] is specified it can be the name or ");
11843                pw.println("pid of a specific process to dump.");
11844                return;
11845            } else {
11846                pw.println("Unknown argument: " + opt + "; use -h for help");
11847            }
11848        }
11849
11850        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11851        long uptime = SystemClock.uptimeMillis();
11852        long realtime = SystemClock.elapsedRealtime();
11853        final long[] tmpLong = new long[1];
11854
11855        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11856        if (procs == null) {
11857            // No Java processes.  Maybe they want to print a native process.
11858            if (args != null && args.length > opti
11859                    && args[opti].charAt(0) != '-') {
11860                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11861                        = new ArrayList<ProcessCpuTracker.Stats>();
11862                updateCpuStatsNow();
11863                int findPid = -1;
11864                try {
11865                    findPid = Integer.parseInt(args[opti]);
11866                } catch (NumberFormatException e) {
11867                }
11868                synchronized (mProcessCpuThread) {
11869                    final int N = mProcessCpuTracker.countStats();
11870                    for (int i=0; i<N; i++) {
11871                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11872                        if (st.pid == findPid || (st.baseName != null
11873                                && st.baseName.equals(args[opti]))) {
11874                            nativeProcs.add(st);
11875                        }
11876                    }
11877                }
11878                if (nativeProcs.size() > 0) {
11879                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11880                            isCompact);
11881                    Debug.MemoryInfo mi = null;
11882                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11883                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11884                        final int pid = r.pid;
11885                        if (!isCheckinRequest && dumpDetails) {
11886                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11887                        }
11888                        if (mi == null) {
11889                            mi = new Debug.MemoryInfo();
11890                        }
11891                        if (dumpDetails || (!brief && !oomOnly)) {
11892                            Debug.getMemoryInfo(pid, mi);
11893                        } else {
11894                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11895                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11896                        }
11897                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11898                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11899                        if (isCheckinRequest) {
11900                            pw.println();
11901                        }
11902                    }
11903                    return;
11904                }
11905            }
11906            pw.println("No process found for: " + args[opti]);
11907            return;
11908        }
11909
11910        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11911            dumpDetails = true;
11912        }
11913
11914        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11915
11916        String[] innerArgs = new String[args.length-opti];
11917        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11918
11919        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11920        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11921        long nativePss=0, dalvikPss=0, otherPss=0;
11922        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11923
11924        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11925        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11926                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11927
11928        long totalPss = 0;
11929        long cachedPss = 0;
11930
11931        Debug.MemoryInfo mi = null;
11932        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11933            final ProcessRecord r = procs.get(i);
11934            final IApplicationThread thread;
11935            final int pid;
11936            final int oomAdj;
11937            final boolean hasActivities;
11938            synchronized (this) {
11939                thread = r.thread;
11940                pid = r.pid;
11941                oomAdj = r.getSetAdjWithServices();
11942                hasActivities = r.activities.size() > 0;
11943            }
11944            if (thread != null) {
11945                if (!isCheckinRequest && dumpDetails) {
11946                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11947                }
11948                if (mi == null) {
11949                    mi = new Debug.MemoryInfo();
11950                }
11951                if (dumpDetails || (!brief && !oomOnly)) {
11952                    Debug.getMemoryInfo(pid, mi);
11953                } else {
11954                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11955                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11956                }
11957                if (dumpDetails) {
11958                    if (localOnly) {
11959                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11960                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11961                        if (isCheckinRequest) {
11962                            pw.println();
11963                        }
11964                    } else {
11965                        try {
11966                            pw.flush();
11967                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11968                                    dumpDalvik, innerArgs);
11969                        } catch (RemoteException e) {
11970                            if (!isCheckinRequest) {
11971                                pw.println("Got RemoteException!");
11972                                pw.flush();
11973                            }
11974                        }
11975                    }
11976                }
11977
11978                final long myTotalPss = mi.getTotalPss();
11979                final long myTotalUss = mi.getTotalUss();
11980
11981                synchronized (this) {
11982                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
11983                        // Record this for posterity if the process has been stable.
11984                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
11985                    }
11986                }
11987
11988                if (!isCheckinRequest && mi != null) {
11989                    totalPss += myTotalPss;
11990                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
11991                            (hasActivities ? " / activities)" : ")"),
11992                            r.processName, myTotalPss, pid, hasActivities);
11993                    procMems.add(pssItem);
11994                    procMemsMap.put(pid, pssItem);
11995
11996                    nativePss += mi.nativePss;
11997                    dalvikPss += mi.dalvikPss;
11998                    otherPss += mi.otherPss;
11999                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12000                        long mem = mi.getOtherPss(j);
12001                        miscPss[j] += mem;
12002                        otherPss -= mem;
12003                    }
12004
12005                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12006                        cachedPss += myTotalPss;
12007                    }
12008
12009                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12010                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12011                                || oomIndex == (oomPss.length-1)) {
12012                            oomPss[oomIndex] += myTotalPss;
12013                            if (oomProcs[oomIndex] == null) {
12014                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12015                            }
12016                            oomProcs[oomIndex].add(pssItem);
12017                            break;
12018                        }
12019                    }
12020                }
12021            }
12022        }
12023
12024        if (!isCheckinRequest && procs.size() > 1) {
12025            // If we are showing aggregations, also look for native processes to
12026            // include so that our aggregations are more accurate.
12027            updateCpuStatsNow();
12028            synchronized (mProcessCpuThread) {
12029                final int N = mProcessCpuTracker.countStats();
12030                for (int i=0; i<N; i++) {
12031                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12032                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12033                        if (mi == null) {
12034                            mi = new Debug.MemoryInfo();
12035                        }
12036                        if (!brief && !oomOnly) {
12037                            Debug.getMemoryInfo(st.pid, mi);
12038                        } else {
12039                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12040                            mi.nativePrivateDirty = (int)tmpLong[0];
12041                        }
12042
12043                        final long myTotalPss = mi.getTotalPss();
12044                        totalPss += myTotalPss;
12045
12046                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12047                                st.name, myTotalPss, st.pid, false);
12048                        procMems.add(pssItem);
12049
12050                        nativePss += mi.nativePss;
12051                        dalvikPss += mi.dalvikPss;
12052                        otherPss += mi.otherPss;
12053                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12054                            long mem = mi.getOtherPss(j);
12055                            miscPss[j] += mem;
12056                            otherPss -= mem;
12057                        }
12058                        oomPss[0] += myTotalPss;
12059                        if (oomProcs[0] == null) {
12060                            oomProcs[0] = new ArrayList<MemItem>();
12061                        }
12062                        oomProcs[0].add(pssItem);
12063                    }
12064                }
12065            }
12066
12067            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12068
12069            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12070            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12071            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12072            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12073                String label = Debug.MemoryInfo.getOtherLabel(j);
12074                catMems.add(new MemItem(label, label, miscPss[j], j));
12075            }
12076
12077            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12078            for (int j=0; j<oomPss.length; j++) {
12079                if (oomPss[j] != 0) {
12080                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12081                            : DUMP_MEM_OOM_LABEL[j];
12082                    MemItem item = new MemItem(label, label, oomPss[j],
12083                            DUMP_MEM_OOM_ADJ[j]);
12084                    item.subitems = oomProcs[j];
12085                    oomMems.add(item);
12086                }
12087            }
12088
12089            if (!brief && !oomOnly && !isCompact) {
12090                pw.println();
12091                pw.println("Total PSS by process:");
12092                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12093                pw.println();
12094            }
12095            if (!isCompact) {
12096                pw.println("Total PSS by OOM adjustment:");
12097            }
12098            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12099            if (!brief && !oomOnly) {
12100                PrintWriter out = categoryPw != null ? categoryPw : pw;
12101                if (!isCompact) {
12102                    out.println();
12103                    out.println("Total PSS by category:");
12104                }
12105                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12106            }
12107            if (!isCompact) {
12108                pw.println();
12109            }
12110            MemInfoReader memInfo = new MemInfoReader();
12111            memInfo.readMemInfo();
12112            if (!brief) {
12113                if (!isCompact) {
12114                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12115                    pw.println(" kB");
12116                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12117                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12118                            pw.print(cachedPss); pw.print(" cached pss + ");
12119                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12120                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12121                } else {
12122                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12123                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12124                            + memInfo.getFreeSizeKb()); pw.print(",");
12125                    pw.println(totalPss - cachedPss);
12126                }
12127            }
12128            if (!isCompact) {
12129                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12130                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12131                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12132                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12133                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12134                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12135                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12136                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12137                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12138                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12139                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12140            }
12141            if (!brief) {
12142                if (memInfo.getZramTotalSizeKb() != 0) {
12143                    if (!isCompact) {
12144                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12145                                pw.print(" kB physical used for ");
12146                                pw.print(memInfo.getSwapTotalSizeKb()
12147                                        - memInfo.getSwapFreeSizeKb());
12148                                pw.print(" kB in swap (");
12149                                pw.print(memInfo.getSwapTotalSizeKb());
12150                                pw.println(" kB total swap)");
12151                    } else {
12152                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12153                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12154                                pw.println(memInfo.getSwapFreeSizeKb());
12155                    }
12156                }
12157                final int[] SINGLE_LONG_FORMAT = new int[] {
12158                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12159                };
12160                long[] longOut = new long[1];
12161                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12162                        SINGLE_LONG_FORMAT, null, longOut, null);
12163                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12164                longOut[0] = 0;
12165                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12166                        SINGLE_LONG_FORMAT, null, longOut, null);
12167                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12168                longOut[0] = 0;
12169                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12170                        SINGLE_LONG_FORMAT, null, longOut, null);
12171                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12172                longOut[0] = 0;
12173                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12174                        SINGLE_LONG_FORMAT, null, longOut, null);
12175                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12176                if (!isCompact) {
12177                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12178                        pw.print("      KSM: "); pw.print(sharing);
12179                                pw.print(" kB saved from shared ");
12180                                pw.print(shared); pw.println(" kB");
12181                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12182                                pw.print(voltile); pw.println(" kB volatile");
12183                    }
12184                    pw.print("   Tuning: ");
12185                    pw.print(ActivityManager.staticGetMemoryClass());
12186                    pw.print(" (large ");
12187                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12188                    pw.print("), oom ");
12189                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12190                    pw.print(" kB");
12191                    pw.print(", restore limit ");
12192                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12193                    pw.print(" kB");
12194                    if (ActivityManager.isLowRamDeviceStatic()) {
12195                        pw.print(" (low-ram)");
12196                    }
12197                    if (ActivityManager.isHighEndGfx()) {
12198                        pw.print(" (high-end-gfx)");
12199                    }
12200                    pw.println();
12201                } else {
12202                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12203                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12204                    pw.println(voltile);
12205                    pw.print("tuning,");
12206                    pw.print(ActivityManager.staticGetMemoryClass());
12207                    pw.print(',');
12208                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12209                    pw.print(',');
12210                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12211                    if (ActivityManager.isLowRamDeviceStatic()) {
12212                        pw.print(",low-ram");
12213                    }
12214                    if (ActivityManager.isHighEndGfx()) {
12215                        pw.print(",high-end-gfx");
12216                    }
12217                    pw.println();
12218                }
12219            }
12220        }
12221    }
12222
12223    /**
12224     * Searches array of arguments for the specified string
12225     * @param args array of argument strings
12226     * @param value value to search for
12227     * @return true if the value is contained in the array
12228     */
12229    private static boolean scanArgs(String[] args, String value) {
12230        if (args != null) {
12231            for (String arg : args) {
12232                if (value.equals(arg)) {
12233                    return true;
12234                }
12235            }
12236        }
12237        return false;
12238    }
12239
12240    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12241            ContentProviderRecord cpr, boolean always) {
12242        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12243
12244        if (!inLaunching || always) {
12245            synchronized (cpr) {
12246                cpr.launchingApp = null;
12247                cpr.notifyAll();
12248            }
12249            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12250            String names[] = cpr.info.authority.split(";");
12251            for (int j = 0; j < names.length; j++) {
12252                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12253            }
12254        }
12255
12256        for (int i=0; i<cpr.connections.size(); i++) {
12257            ContentProviderConnection conn = cpr.connections.get(i);
12258            if (conn.waiting) {
12259                // If this connection is waiting for the provider, then we don't
12260                // need to mess with its process unless we are always removing
12261                // or for some reason the provider is not currently launching.
12262                if (inLaunching && !always) {
12263                    continue;
12264                }
12265            }
12266            ProcessRecord capp = conn.client;
12267            conn.dead = true;
12268            if (conn.stableCount > 0) {
12269                if (!capp.persistent && capp.thread != null
12270                        && capp.pid != 0
12271                        && capp.pid != MY_PID) {
12272                    killUnneededProcessLocked(capp, "depends on provider "
12273                            + cpr.name.flattenToShortString()
12274                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12275                }
12276            } else if (capp.thread != null && conn.provider.provider != null) {
12277                try {
12278                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12279                } catch (RemoteException e) {
12280                }
12281                // In the protocol here, we don't expect the client to correctly
12282                // clean up this connection, we'll just remove it.
12283                cpr.connections.remove(i);
12284                conn.client.conProviders.remove(conn);
12285            }
12286        }
12287
12288        if (inLaunching && always) {
12289            mLaunchingProviders.remove(cpr);
12290        }
12291        return inLaunching;
12292    }
12293
12294    /**
12295     * Main code for cleaning up a process when it has gone away.  This is
12296     * called both as a result of the process dying, or directly when stopping
12297     * a process when running in single process mode.
12298     */
12299    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12300            boolean restarting, boolean allowRestart, int index) {
12301        if (index >= 0) {
12302            removeLruProcessLocked(app);
12303            ProcessList.remove(app.pid);
12304        }
12305
12306        mProcessesToGc.remove(app);
12307        mPendingPssProcesses.remove(app);
12308
12309        // Dismiss any open dialogs.
12310        if (app.crashDialog != null && !app.forceCrashReport) {
12311            app.crashDialog.dismiss();
12312            app.crashDialog = null;
12313        }
12314        if (app.anrDialog != null) {
12315            app.anrDialog.dismiss();
12316            app.anrDialog = null;
12317        }
12318        if (app.waitDialog != null) {
12319            app.waitDialog.dismiss();
12320            app.waitDialog = null;
12321        }
12322
12323        app.crashing = false;
12324        app.notResponding = false;
12325
12326        app.resetPackageList(mProcessStats);
12327        app.unlinkDeathRecipient();
12328        app.makeInactive(mProcessStats);
12329        app.forcingToForeground = null;
12330        app.foregroundServices = false;
12331        app.foregroundActivities = false;
12332        app.hasShownUi = false;
12333        app.hasAboveClient = false;
12334        app.hasClientActivities = false;
12335
12336        mServices.killServicesLocked(app, allowRestart);
12337
12338        boolean restart = false;
12339
12340        // Remove published content providers.
12341        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12342            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12343            final boolean always = app.bad || !allowRestart;
12344            if (removeDyingProviderLocked(app, cpr, always) || always) {
12345                // We left the provider in the launching list, need to
12346                // restart it.
12347                restart = true;
12348            }
12349
12350            cpr.provider = null;
12351            cpr.proc = null;
12352        }
12353        app.pubProviders.clear();
12354
12355        // Take care of any launching providers waiting for this process.
12356        if (checkAppInLaunchingProvidersLocked(app, false)) {
12357            restart = true;
12358        }
12359
12360        // Unregister from connected content providers.
12361        if (!app.conProviders.isEmpty()) {
12362            for (int i=0; i<app.conProviders.size(); i++) {
12363                ContentProviderConnection conn = app.conProviders.get(i);
12364                conn.provider.connections.remove(conn);
12365            }
12366            app.conProviders.clear();
12367        }
12368
12369        // At this point there may be remaining entries in mLaunchingProviders
12370        // where we were the only one waiting, so they are no longer of use.
12371        // Look for these and clean up if found.
12372        // XXX Commented out for now.  Trying to figure out a way to reproduce
12373        // the actual situation to identify what is actually going on.
12374        if (false) {
12375            for (int i=0; i<mLaunchingProviders.size(); i++) {
12376                ContentProviderRecord cpr = (ContentProviderRecord)
12377                        mLaunchingProviders.get(i);
12378                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12379                    synchronized (cpr) {
12380                        cpr.launchingApp = null;
12381                        cpr.notifyAll();
12382                    }
12383                }
12384            }
12385        }
12386
12387        skipCurrentReceiverLocked(app);
12388
12389        // Unregister any receivers.
12390        for (int i=app.receivers.size()-1; i>=0; i--) {
12391            removeReceiverLocked(app.receivers.valueAt(i));
12392        }
12393        app.receivers.clear();
12394
12395        // If the app is undergoing backup, tell the backup manager about it
12396        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12397            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12398                    + mBackupTarget.appInfo + " died during backup");
12399            try {
12400                IBackupManager bm = IBackupManager.Stub.asInterface(
12401                        ServiceManager.getService(Context.BACKUP_SERVICE));
12402                bm.agentDisconnected(app.info.packageName);
12403            } catch (RemoteException e) {
12404                // can't happen; backup manager is local
12405            }
12406        }
12407
12408        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12409            ProcessChangeItem item = mPendingProcessChanges.get(i);
12410            if (item.pid == app.pid) {
12411                mPendingProcessChanges.remove(i);
12412                mAvailProcessChanges.add(item);
12413            }
12414        }
12415        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12416
12417        // If the caller is restarting this app, then leave it in its
12418        // current lists and let the caller take care of it.
12419        if (restarting) {
12420            return;
12421        }
12422
12423        if (!app.persistent || app.isolated) {
12424            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12425                    "Removing non-persistent process during cleanup: " + app);
12426            mProcessNames.remove(app.processName, app.uid);
12427            mIsolatedProcesses.remove(app.uid);
12428            if (mHeavyWeightProcess == app) {
12429                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12430                        mHeavyWeightProcess.userId, 0));
12431                mHeavyWeightProcess = null;
12432            }
12433        } else if (!app.removed) {
12434            // This app is persistent, so we need to keep its record around.
12435            // If it is not already on the pending app list, add it there
12436            // and start a new process for it.
12437            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12438                mPersistentStartingProcesses.add(app);
12439                restart = true;
12440            }
12441        }
12442        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12443                "Clean-up removing on hold: " + app);
12444        mProcessesOnHold.remove(app);
12445
12446        if (app == mHomeProcess) {
12447            mHomeProcess = null;
12448        }
12449        if (app == mPreviousProcess) {
12450            mPreviousProcess = null;
12451        }
12452
12453        if (restart && !app.isolated) {
12454            // We have components that still need to be running in the
12455            // process, so re-launch it.
12456            mProcessNames.put(app.processName, app.uid, app);
12457            startProcessLocked(app, "restart", app.processName);
12458        } else if (app.pid > 0 && app.pid != MY_PID) {
12459            // Goodbye!
12460            synchronized (mPidsSelfLocked) {
12461                mPidsSelfLocked.remove(app.pid);
12462                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12463            }
12464            app.setPid(0);
12465        }
12466    }
12467
12468    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12469        // Look through the content providers we are waiting to have launched,
12470        // and if any run in this process then either schedule a restart of
12471        // the process or kill the client waiting for it if this process has
12472        // gone bad.
12473        int NL = mLaunchingProviders.size();
12474        boolean restart = false;
12475        for (int i=0; i<NL; i++) {
12476            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12477            if (cpr.launchingApp == app) {
12478                if (!alwaysBad && !app.bad) {
12479                    restart = true;
12480                } else {
12481                    removeDyingProviderLocked(app, cpr, true);
12482                    // cpr should have been removed from mLaunchingProviders
12483                    NL = mLaunchingProviders.size();
12484                    i--;
12485                }
12486            }
12487        }
12488        return restart;
12489    }
12490
12491    // =========================================================
12492    // SERVICES
12493    // =========================================================
12494
12495    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12496            int flags) {
12497        enforceNotIsolatedCaller("getServices");
12498        synchronized (this) {
12499            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12500        }
12501    }
12502
12503    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12504        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12505        synchronized (this) {
12506            return mServices.getRunningServiceControlPanelLocked(name);
12507        }
12508    }
12509
12510    public ComponentName startService(IApplicationThread caller, Intent service,
12511            String resolvedType, int userId) {
12512        enforceNotIsolatedCaller("startService");
12513        // Refuse possible leaked file descriptors
12514        if (service != null && service.hasFileDescriptors() == true) {
12515            throw new IllegalArgumentException("File descriptors passed in Intent");
12516        }
12517
12518        if (DEBUG_SERVICE)
12519            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12520        synchronized(this) {
12521            final int callingPid = Binder.getCallingPid();
12522            final int callingUid = Binder.getCallingUid();
12523            final long origId = Binder.clearCallingIdentity();
12524            ComponentName res = mServices.startServiceLocked(caller, service,
12525                    resolvedType, callingPid, callingUid, userId);
12526            Binder.restoreCallingIdentity(origId);
12527            return res;
12528        }
12529    }
12530
12531    ComponentName startServiceInPackage(int uid,
12532            Intent service, String resolvedType, int userId) {
12533        synchronized(this) {
12534            if (DEBUG_SERVICE)
12535                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12536            final long origId = Binder.clearCallingIdentity();
12537            ComponentName res = mServices.startServiceLocked(null, service,
12538                    resolvedType, -1, uid, userId);
12539            Binder.restoreCallingIdentity(origId);
12540            return res;
12541        }
12542    }
12543
12544    public int stopService(IApplicationThread caller, Intent service,
12545            String resolvedType, int userId) {
12546        enforceNotIsolatedCaller("stopService");
12547        // Refuse possible leaked file descriptors
12548        if (service != null && service.hasFileDescriptors() == true) {
12549            throw new IllegalArgumentException("File descriptors passed in Intent");
12550        }
12551
12552        synchronized(this) {
12553            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12554        }
12555    }
12556
12557    public IBinder peekService(Intent service, String resolvedType) {
12558        enforceNotIsolatedCaller("peekService");
12559        // Refuse possible leaked file descriptors
12560        if (service != null && service.hasFileDescriptors() == true) {
12561            throw new IllegalArgumentException("File descriptors passed in Intent");
12562        }
12563        synchronized(this) {
12564            return mServices.peekServiceLocked(service, resolvedType);
12565        }
12566    }
12567
12568    public boolean stopServiceToken(ComponentName className, IBinder token,
12569            int startId) {
12570        synchronized(this) {
12571            return mServices.stopServiceTokenLocked(className, token, startId);
12572        }
12573    }
12574
12575    public void setServiceForeground(ComponentName className, IBinder token,
12576            int id, Notification notification, boolean removeNotification) {
12577        synchronized(this) {
12578            mServices.setServiceForegroundLocked(className, token, id, notification,
12579                    removeNotification);
12580        }
12581    }
12582
12583    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12584            boolean requireFull, String name, String callerPackage) {
12585        final int callingUserId = UserHandle.getUserId(callingUid);
12586        if (callingUserId != userId) {
12587            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12588                if ((requireFull || checkComponentPermission(
12589                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12590                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12591                        && checkComponentPermission(
12592                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12593                                callingPid, callingUid, -1, true)
12594                                != PackageManager.PERMISSION_GRANTED) {
12595                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12596                        // In this case, they would like to just execute as their
12597                        // owner user instead of failing.
12598                        userId = callingUserId;
12599                    } else {
12600                        StringBuilder builder = new StringBuilder(128);
12601                        builder.append("Permission Denial: ");
12602                        builder.append(name);
12603                        if (callerPackage != null) {
12604                            builder.append(" from ");
12605                            builder.append(callerPackage);
12606                        }
12607                        builder.append(" asks to run as user ");
12608                        builder.append(userId);
12609                        builder.append(" but is calling from user ");
12610                        builder.append(UserHandle.getUserId(callingUid));
12611                        builder.append("; this requires ");
12612                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12613                        if (!requireFull) {
12614                            builder.append(" or ");
12615                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12616                        }
12617                        String msg = builder.toString();
12618                        Slog.w(TAG, msg);
12619                        throw new SecurityException(msg);
12620                    }
12621                }
12622            }
12623            if (userId == UserHandle.USER_CURRENT
12624                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12625                // Note that we may be accessing this outside of a lock...
12626                // shouldn't be a big deal, if this is being called outside
12627                // of a locked context there is intrinsically a race with
12628                // the value the caller will receive and someone else changing it.
12629                userId = mCurrentUserId;
12630            }
12631            if (!allowAll && userId < 0) {
12632                throw new IllegalArgumentException(
12633                        "Call does not support special user #" + userId);
12634            }
12635        }
12636        return userId;
12637    }
12638
12639    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12640            String className, int flags) {
12641        boolean result = false;
12642        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12643            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12644                if (ActivityManager.checkUidPermission(
12645                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12646                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12647                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12648                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12649                            + " requests FLAG_SINGLE_USER, but app does not hold "
12650                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12651                    Slog.w(TAG, msg);
12652                    throw new SecurityException(msg);
12653                }
12654                result = true;
12655            }
12656        } else if (componentProcessName == aInfo.packageName) {
12657            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12658        } else if ("system".equals(componentProcessName)) {
12659            result = true;
12660        }
12661        if (DEBUG_MU) {
12662            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12663                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12664        }
12665        return result;
12666    }
12667
12668    public int bindService(IApplicationThread caller, IBinder token,
12669            Intent service, String resolvedType,
12670            IServiceConnection connection, int flags, int userId) {
12671        enforceNotIsolatedCaller("bindService");
12672        // Refuse possible leaked file descriptors
12673        if (service != null && service.hasFileDescriptors() == true) {
12674            throw new IllegalArgumentException("File descriptors passed in Intent");
12675        }
12676
12677        synchronized(this) {
12678            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12679                    connection, flags, userId);
12680        }
12681    }
12682
12683    public boolean unbindService(IServiceConnection connection) {
12684        synchronized (this) {
12685            return mServices.unbindServiceLocked(connection);
12686        }
12687    }
12688
12689    public void publishService(IBinder token, Intent intent, IBinder service) {
12690        // Refuse possible leaked file descriptors
12691        if (intent != null && intent.hasFileDescriptors() == true) {
12692            throw new IllegalArgumentException("File descriptors passed in Intent");
12693        }
12694
12695        synchronized(this) {
12696            if (!(token instanceof ServiceRecord)) {
12697                throw new IllegalArgumentException("Invalid service token");
12698            }
12699            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12700        }
12701    }
12702
12703    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12704        // Refuse possible leaked file descriptors
12705        if (intent != null && intent.hasFileDescriptors() == true) {
12706            throw new IllegalArgumentException("File descriptors passed in Intent");
12707        }
12708
12709        synchronized(this) {
12710            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12711        }
12712    }
12713
12714    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12715        synchronized(this) {
12716            if (!(token instanceof ServiceRecord)) {
12717                throw new IllegalArgumentException("Invalid service token");
12718            }
12719            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12720        }
12721    }
12722
12723    // =========================================================
12724    // BACKUP AND RESTORE
12725    // =========================================================
12726
12727    // Cause the target app to be launched if necessary and its backup agent
12728    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12729    // activity manager to announce its creation.
12730    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12731        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12732        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12733
12734        synchronized(this) {
12735            // !!! TODO: currently no check here that we're already bound
12736            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12737            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12738            synchronized (stats) {
12739                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12740            }
12741
12742            // Backup agent is now in use, its package can't be stopped.
12743            try {
12744                AppGlobals.getPackageManager().setPackageStoppedState(
12745                        app.packageName, false, UserHandle.getUserId(app.uid));
12746            } catch (RemoteException e) {
12747            } catch (IllegalArgumentException e) {
12748                Slog.w(TAG, "Failed trying to unstop package "
12749                        + app.packageName + ": " + e);
12750            }
12751
12752            BackupRecord r = new BackupRecord(ss, app, backupMode);
12753            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12754                    ? new ComponentName(app.packageName, app.backupAgentName)
12755                    : new ComponentName("android", "FullBackupAgent");
12756            // startProcessLocked() returns existing proc's record if it's already running
12757            ProcessRecord proc = startProcessLocked(app.processName, app,
12758                    false, 0, "backup", hostingName, false, false, false);
12759            if (proc == null) {
12760                Slog.e(TAG, "Unable to start backup agent process " + r);
12761                return false;
12762            }
12763
12764            r.app = proc;
12765            mBackupTarget = r;
12766            mBackupAppName = app.packageName;
12767
12768            // Try not to kill the process during backup
12769            updateOomAdjLocked(proc);
12770
12771            // If the process is already attached, schedule the creation of the backup agent now.
12772            // If it is not yet live, this will be done when it attaches to the framework.
12773            if (proc.thread != null) {
12774                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12775                try {
12776                    proc.thread.scheduleCreateBackupAgent(app,
12777                            compatibilityInfoForPackageLocked(app), backupMode);
12778                } catch (RemoteException e) {
12779                    // Will time out on the backup manager side
12780                }
12781            } else {
12782                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12783            }
12784            // Invariants: at this point, the target app process exists and the application
12785            // is either already running or in the process of coming up.  mBackupTarget and
12786            // mBackupAppName describe the app, so that when it binds back to the AM we
12787            // know that it's scheduled for a backup-agent operation.
12788        }
12789
12790        return true;
12791    }
12792
12793    @Override
12794    public void clearPendingBackup() {
12795        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12796        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12797
12798        synchronized (this) {
12799            mBackupTarget = null;
12800            mBackupAppName = null;
12801        }
12802    }
12803
12804    // A backup agent has just come up
12805    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12806        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12807                + " = " + agent);
12808
12809        synchronized(this) {
12810            if (!agentPackageName.equals(mBackupAppName)) {
12811                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12812                return;
12813            }
12814        }
12815
12816        long oldIdent = Binder.clearCallingIdentity();
12817        try {
12818            IBackupManager bm = IBackupManager.Stub.asInterface(
12819                    ServiceManager.getService(Context.BACKUP_SERVICE));
12820            bm.agentConnected(agentPackageName, agent);
12821        } catch (RemoteException e) {
12822            // can't happen; the backup manager service is local
12823        } catch (Exception e) {
12824            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12825            e.printStackTrace();
12826        } finally {
12827            Binder.restoreCallingIdentity(oldIdent);
12828        }
12829    }
12830
12831    // done with this agent
12832    public void unbindBackupAgent(ApplicationInfo appInfo) {
12833        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12834        if (appInfo == null) {
12835            Slog.w(TAG, "unbind backup agent for null app");
12836            return;
12837        }
12838
12839        synchronized(this) {
12840            try {
12841                if (mBackupAppName == null) {
12842                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12843                    return;
12844                }
12845
12846                if (!mBackupAppName.equals(appInfo.packageName)) {
12847                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12848                    return;
12849                }
12850
12851                // Not backing this app up any more; reset its OOM adjustment
12852                final ProcessRecord proc = mBackupTarget.app;
12853                updateOomAdjLocked(proc);
12854
12855                // If the app crashed during backup, 'thread' will be null here
12856                if (proc.thread != null) {
12857                    try {
12858                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12859                                compatibilityInfoForPackageLocked(appInfo));
12860                    } catch (Exception e) {
12861                        Slog.e(TAG, "Exception when unbinding backup agent:");
12862                        e.printStackTrace();
12863                    }
12864                }
12865            } finally {
12866                mBackupTarget = null;
12867                mBackupAppName = null;
12868            }
12869        }
12870    }
12871    // =========================================================
12872    // BROADCASTS
12873    // =========================================================
12874
12875    private final List getStickiesLocked(String action, IntentFilter filter,
12876            List cur, int userId) {
12877        final ContentResolver resolver = mContext.getContentResolver();
12878        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12879        if (stickies == null) {
12880            return cur;
12881        }
12882        final ArrayList<Intent> list = stickies.get(action);
12883        if (list == null) {
12884            return cur;
12885        }
12886        int N = list.size();
12887        for (int i=0; i<N; i++) {
12888            Intent intent = list.get(i);
12889            if (filter.match(resolver, intent, true, TAG) >= 0) {
12890                if (cur == null) {
12891                    cur = new ArrayList<Intent>();
12892                }
12893                cur.add(intent);
12894            }
12895        }
12896        return cur;
12897    }
12898
12899    boolean isPendingBroadcastProcessLocked(int pid) {
12900        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12901                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12902    }
12903
12904    void skipPendingBroadcastLocked(int pid) {
12905            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12906            for (BroadcastQueue queue : mBroadcastQueues) {
12907                queue.skipPendingBroadcastLocked(pid);
12908            }
12909    }
12910
12911    // The app just attached; send any pending broadcasts that it should receive
12912    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12913        boolean didSomething = false;
12914        for (BroadcastQueue queue : mBroadcastQueues) {
12915            didSomething |= queue.sendPendingBroadcastsLocked(app);
12916        }
12917        return didSomething;
12918    }
12919
12920    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12921            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12922        enforceNotIsolatedCaller("registerReceiver");
12923        int callingUid;
12924        int callingPid;
12925        synchronized(this) {
12926            ProcessRecord callerApp = null;
12927            if (caller != null) {
12928                callerApp = getRecordForAppLocked(caller);
12929                if (callerApp == null) {
12930                    throw new SecurityException(
12931                            "Unable to find app for caller " + caller
12932                            + " (pid=" + Binder.getCallingPid()
12933                            + ") when registering receiver " + receiver);
12934                }
12935                if (callerApp.info.uid != Process.SYSTEM_UID &&
12936                        !callerApp.pkgList.containsKey(callerPackage) &&
12937                        !"android".equals(callerPackage)) {
12938                    throw new SecurityException("Given caller package " + callerPackage
12939                            + " is not running in process " + callerApp);
12940                }
12941                callingUid = callerApp.info.uid;
12942                callingPid = callerApp.pid;
12943            } else {
12944                callerPackage = null;
12945                callingUid = Binder.getCallingUid();
12946                callingPid = Binder.getCallingPid();
12947            }
12948
12949            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12950                    true, true, "registerReceiver", callerPackage);
12951
12952            List allSticky = null;
12953
12954            // Look for any matching sticky broadcasts...
12955            Iterator actions = filter.actionsIterator();
12956            if (actions != null) {
12957                while (actions.hasNext()) {
12958                    String action = (String)actions.next();
12959                    allSticky = getStickiesLocked(action, filter, allSticky,
12960                            UserHandle.USER_ALL);
12961                    allSticky = getStickiesLocked(action, filter, allSticky,
12962                            UserHandle.getUserId(callingUid));
12963                }
12964            } else {
12965                allSticky = getStickiesLocked(null, filter, allSticky,
12966                        UserHandle.USER_ALL);
12967                allSticky = getStickiesLocked(null, filter, allSticky,
12968                        UserHandle.getUserId(callingUid));
12969            }
12970
12971            // The first sticky in the list is returned directly back to
12972            // the client.
12973            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12974
12975            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12976                    + ": " + sticky);
12977
12978            if (receiver == null) {
12979                return sticky;
12980            }
12981
12982            ReceiverList rl
12983                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12984            if (rl == null) {
12985                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
12986                        userId, receiver);
12987                if (rl.app != null) {
12988                    rl.app.receivers.add(rl);
12989                } else {
12990                    try {
12991                        receiver.asBinder().linkToDeath(rl, 0);
12992                    } catch (RemoteException e) {
12993                        return sticky;
12994                    }
12995                    rl.linkedToDeath = true;
12996                }
12997                mRegisteredReceivers.put(receiver.asBinder(), rl);
12998            } else if (rl.uid != callingUid) {
12999                throw new IllegalArgumentException(
13000                        "Receiver requested to register for uid " + callingUid
13001                        + " was previously registered for uid " + rl.uid);
13002            } else if (rl.pid != callingPid) {
13003                throw new IllegalArgumentException(
13004                        "Receiver requested to register for pid " + callingPid
13005                        + " was previously registered for pid " + rl.pid);
13006            } else if (rl.userId != userId) {
13007                throw new IllegalArgumentException(
13008                        "Receiver requested to register for user " + userId
13009                        + " was previously registered for user " + rl.userId);
13010            }
13011            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13012                    permission, callingUid, userId);
13013            rl.add(bf);
13014            if (!bf.debugCheck()) {
13015                Slog.w(TAG, "==> For Dynamic broadast");
13016            }
13017            mReceiverResolver.addFilter(bf);
13018
13019            // Enqueue broadcasts for all existing stickies that match
13020            // this filter.
13021            if (allSticky != null) {
13022                ArrayList receivers = new ArrayList();
13023                receivers.add(bf);
13024
13025                int N = allSticky.size();
13026                for (int i=0; i<N; i++) {
13027                    Intent intent = (Intent)allSticky.get(i);
13028                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13029                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13030                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13031                            null, null, false, true, true, -1);
13032                    queue.enqueueParallelBroadcastLocked(r);
13033                    queue.scheduleBroadcastsLocked();
13034                }
13035            }
13036
13037            return sticky;
13038        }
13039    }
13040
13041    public void unregisterReceiver(IIntentReceiver receiver) {
13042        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13043
13044        final long origId = Binder.clearCallingIdentity();
13045        try {
13046            boolean doTrim = false;
13047
13048            synchronized(this) {
13049                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13050                if (rl != null) {
13051                    if (rl.curBroadcast != null) {
13052                        BroadcastRecord r = rl.curBroadcast;
13053                        final boolean doNext = finishReceiverLocked(
13054                                receiver.asBinder(), r.resultCode, r.resultData,
13055                                r.resultExtras, r.resultAbort);
13056                        if (doNext) {
13057                            doTrim = true;
13058                            r.queue.processNextBroadcast(false);
13059                        }
13060                    }
13061
13062                    if (rl.app != null) {
13063                        rl.app.receivers.remove(rl);
13064                    }
13065                    removeReceiverLocked(rl);
13066                    if (rl.linkedToDeath) {
13067                        rl.linkedToDeath = false;
13068                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13069                    }
13070                }
13071            }
13072
13073            // If we actually concluded any broadcasts, we might now be able
13074            // to trim the recipients' apps from our working set
13075            if (doTrim) {
13076                trimApplications();
13077                return;
13078            }
13079
13080        } finally {
13081            Binder.restoreCallingIdentity(origId);
13082        }
13083    }
13084
13085    void removeReceiverLocked(ReceiverList rl) {
13086        mRegisteredReceivers.remove(rl.receiver.asBinder());
13087        int N = rl.size();
13088        for (int i=0; i<N; i++) {
13089            mReceiverResolver.removeFilter(rl.get(i));
13090        }
13091    }
13092
13093    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13094        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13095            ProcessRecord r = mLruProcesses.get(i);
13096            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13097                try {
13098                    r.thread.dispatchPackageBroadcast(cmd, packages);
13099                } catch (RemoteException ex) {
13100                }
13101            }
13102        }
13103    }
13104
13105    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13106            int[] users) {
13107        List<ResolveInfo> receivers = null;
13108        try {
13109            HashSet<ComponentName> singleUserReceivers = null;
13110            boolean scannedFirstReceivers = false;
13111            for (int user : users) {
13112                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13113                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13114                if (user != 0 && newReceivers != null) {
13115                    // If this is not the primary user, we need to check for
13116                    // any receivers that should be filtered out.
13117                    for (int i=0; i<newReceivers.size(); i++) {
13118                        ResolveInfo ri = newReceivers.get(i);
13119                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13120                            newReceivers.remove(i);
13121                            i--;
13122                        }
13123                    }
13124                }
13125                if (newReceivers != null && newReceivers.size() == 0) {
13126                    newReceivers = null;
13127                }
13128                if (receivers == null) {
13129                    receivers = newReceivers;
13130                } else if (newReceivers != null) {
13131                    // We need to concatenate the additional receivers
13132                    // found with what we have do far.  This would be easy,
13133                    // but we also need to de-dup any receivers that are
13134                    // singleUser.
13135                    if (!scannedFirstReceivers) {
13136                        // Collect any single user receivers we had already retrieved.
13137                        scannedFirstReceivers = true;
13138                        for (int i=0; i<receivers.size(); i++) {
13139                            ResolveInfo ri = receivers.get(i);
13140                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13141                                ComponentName cn = new ComponentName(
13142                                        ri.activityInfo.packageName, ri.activityInfo.name);
13143                                if (singleUserReceivers == null) {
13144                                    singleUserReceivers = new HashSet<ComponentName>();
13145                                }
13146                                singleUserReceivers.add(cn);
13147                            }
13148                        }
13149                    }
13150                    // Add the new results to the existing results, tracking
13151                    // and de-dupping single user receivers.
13152                    for (int i=0; i<newReceivers.size(); i++) {
13153                        ResolveInfo ri = newReceivers.get(i);
13154                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13155                            ComponentName cn = new ComponentName(
13156                                    ri.activityInfo.packageName, ri.activityInfo.name);
13157                            if (singleUserReceivers == null) {
13158                                singleUserReceivers = new HashSet<ComponentName>();
13159                            }
13160                            if (!singleUserReceivers.contains(cn)) {
13161                                singleUserReceivers.add(cn);
13162                                receivers.add(ri);
13163                            }
13164                        } else {
13165                            receivers.add(ri);
13166                        }
13167                    }
13168                }
13169            }
13170        } catch (RemoteException ex) {
13171            // pm is in same process, this will never happen.
13172        }
13173        return receivers;
13174    }
13175
13176    private final int broadcastIntentLocked(ProcessRecord callerApp,
13177            String callerPackage, Intent intent, String resolvedType,
13178            IIntentReceiver resultTo, int resultCode, String resultData,
13179            Bundle map, String requiredPermission, int appOp,
13180            boolean ordered, boolean sticky, int callingPid, int callingUid,
13181            int userId) {
13182        intent = new Intent(intent);
13183
13184        // By default broadcasts do not go to stopped apps.
13185        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13186
13187        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13188            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13189            + " ordered=" + ordered + " userid=" + userId);
13190        if ((resultTo != null) && !ordered) {
13191            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13192        }
13193
13194        userId = handleIncomingUser(callingPid, callingUid, userId,
13195                true, false, "broadcast", callerPackage);
13196
13197        // Make sure that the user who is receiving this broadcast is started.
13198        // If not, we will just skip it.
13199        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13200            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13201                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13202                Slog.w(TAG, "Skipping broadcast of " + intent
13203                        + ": user " + userId + " is stopped");
13204                return ActivityManager.BROADCAST_SUCCESS;
13205            }
13206        }
13207
13208        /*
13209         * Prevent non-system code (defined here to be non-persistent
13210         * processes) from sending protected broadcasts.
13211         */
13212        int callingAppId = UserHandle.getAppId(callingUid);
13213        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13214            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13215            callingUid == 0) {
13216            // Always okay.
13217        } else if (callerApp == null || !callerApp.persistent) {
13218            try {
13219                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13220                        intent.getAction())) {
13221                    String msg = "Permission Denial: not allowed to send broadcast "
13222                            + intent.getAction() + " from pid="
13223                            + callingPid + ", uid=" + callingUid;
13224                    Slog.w(TAG, msg);
13225                    throw new SecurityException(msg);
13226                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13227                    // Special case for compatibility: we don't want apps to send this,
13228                    // but historically it has not been protected and apps may be using it
13229                    // to poke their own app widget.  So, instead of making it protected,
13230                    // just limit it to the caller.
13231                    if (callerApp == null) {
13232                        String msg = "Permission Denial: not allowed to send broadcast "
13233                                + intent.getAction() + " from unknown caller.";
13234                        Slog.w(TAG, msg);
13235                        throw new SecurityException(msg);
13236                    } else if (intent.getComponent() != null) {
13237                        // They are good enough to send to an explicit component...  verify
13238                        // it is being sent to the calling app.
13239                        if (!intent.getComponent().getPackageName().equals(
13240                                callerApp.info.packageName)) {
13241                            String msg = "Permission Denial: not allowed to send broadcast "
13242                                    + intent.getAction() + " to "
13243                                    + intent.getComponent().getPackageName() + " from "
13244                                    + callerApp.info.packageName;
13245                            Slog.w(TAG, msg);
13246                            throw new SecurityException(msg);
13247                        }
13248                    } else {
13249                        // Limit broadcast to their own package.
13250                        intent.setPackage(callerApp.info.packageName);
13251                    }
13252                }
13253            } catch (RemoteException e) {
13254                Slog.w(TAG, "Remote exception", e);
13255                return ActivityManager.BROADCAST_SUCCESS;
13256            }
13257        }
13258
13259        // Handle special intents: if this broadcast is from the package
13260        // manager about a package being removed, we need to remove all of
13261        // its activities from the history stack.
13262        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13263                intent.getAction());
13264        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13265                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13266                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13267                || uidRemoved) {
13268            if (checkComponentPermission(
13269                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13270                    callingPid, callingUid, -1, true)
13271                    == PackageManager.PERMISSION_GRANTED) {
13272                if (uidRemoved) {
13273                    final Bundle intentExtras = intent.getExtras();
13274                    final int uid = intentExtras != null
13275                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13276                    if (uid >= 0) {
13277                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13278                        synchronized (bs) {
13279                            bs.removeUidStatsLocked(uid);
13280                        }
13281                        mAppOpsService.uidRemoved(uid);
13282                    }
13283                } else {
13284                    // If resources are unavailable just force stop all
13285                    // those packages and flush the attribute cache as well.
13286                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13287                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13288                        if (list != null && (list.length > 0)) {
13289                            for (String pkg : list) {
13290                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
13291                                        "storage unmount");
13292                            }
13293                            sendPackageBroadcastLocked(
13294                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13295                        }
13296                    } else {
13297                        Uri data = intent.getData();
13298                        String ssp;
13299                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13300                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13301                                    intent.getAction());
13302                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13303                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13304                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13305                                        false, userId, removed ? "pkg removed" : "pkg changed");
13306                            }
13307                            if (removed) {
13308                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13309                                        new String[] {ssp}, userId);
13310                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13311                                    mAppOpsService.packageRemoved(
13312                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13313
13314                                    // Remove all permissions granted from/to this package
13315                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13316                                }
13317                            }
13318                        }
13319                    }
13320                }
13321            } else {
13322                String msg = "Permission Denial: " + intent.getAction()
13323                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13324                        + ", uid=" + callingUid + ")"
13325                        + " requires "
13326                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13327                Slog.w(TAG, msg);
13328                throw new SecurityException(msg);
13329            }
13330
13331        // Special case for adding a package: by default turn on compatibility
13332        // mode.
13333        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13334            Uri data = intent.getData();
13335            String ssp;
13336            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13337                mCompatModePackages.handlePackageAddedLocked(ssp,
13338                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13339            }
13340        }
13341
13342        /*
13343         * If this is the time zone changed action, queue up a message that will reset the timezone
13344         * of all currently running processes. This message will get queued up before the broadcast
13345         * happens.
13346         */
13347        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13348            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13349        }
13350
13351        /*
13352         * If the user set the time, let all running processes know.
13353         */
13354        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13355            final int is24Hour = intent.getBooleanExtra(
13356                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13357            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13358        }
13359
13360        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13361            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13362        }
13363
13364        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13365            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13366            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13367        }
13368
13369        // Add to the sticky list if requested.
13370        if (sticky) {
13371            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13372                    callingPid, callingUid)
13373                    != PackageManager.PERMISSION_GRANTED) {
13374                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13375                        + callingPid + ", uid=" + callingUid
13376                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13377                Slog.w(TAG, msg);
13378                throw new SecurityException(msg);
13379            }
13380            if (requiredPermission != null) {
13381                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13382                        + " and enforce permission " + requiredPermission);
13383                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13384            }
13385            if (intent.getComponent() != null) {
13386                throw new SecurityException(
13387                        "Sticky broadcasts can't target a specific component");
13388            }
13389            // We use userId directly here, since the "all" target is maintained
13390            // as a separate set of sticky broadcasts.
13391            if (userId != UserHandle.USER_ALL) {
13392                // But first, if this is not a broadcast to all users, then
13393                // make sure it doesn't conflict with an existing broadcast to
13394                // all users.
13395                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13396                        UserHandle.USER_ALL);
13397                if (stickies != null) {
13398                    ArrayList<Intent> list = stickies.get(intent.getAction());
13399                    if (list != null) {
13400                        int N = list.size();
13401                        int i;
13402                        for (i=0; i<N; i++) {
13403                            if (intent.filterEquals(list.get(i))) {
13404                                throw new IllegalArgumentException(
13405                                        "Sticky broadcast " + intent + " for user "
13406                                        + userId + " conflicts with existing global broadcast");
13407                            }
13408                        }
13409                    }
13410                }
13411            }
13412            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13413            if (stickies == null) {
13414                stickies = new ArrayMap<String, ArrayList<Intent>>();
13415                mStickyBroadcasts.put(userId, stickies);
13416            }
13417            ArrayList<Intent> list = stickies.get(intent.getAction());
13418            if (list == null) {
13419                list = new ArrayList<Intent>();
13420                stickies.put(intent.getAction(), list);
13421            }
13422            int N = list.size();
13423            int i;
13424            for (i=0; i<N; i++) {
13425                if (intent.filterEquals(list.get(i))) {
13426                    // This sticky already exists, replace it.
13427                    list.set(i, new Intent(intent));
13428                    break;
13429                }
13430            }
13431            if (i >= N) {
13432                list.add(new Intent(intent));
13433            }
13434        }
13435
13436        int[] users;
13437        if (userId == UserHandle.USER_ALL) {
13438            // Caller wants broadcast to go to all started users.
13439            users = mStartedUserArray;
13440        } else {
13441            // Caller wants broadcast to go to one specific user.
13442            users = new int[] {userId};
13443        }
13444
13445        // Figure out who all will receive this broadcast.
13446        List receivers = null;
13447        List<BroadcastFilter> registeredReceivers = null;
13448        // Need to resolve the intent to interested receivers...
13449        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13450                 == 0) {
13451            receivers = collectReceiverComponents(intent, resolvedType, users);
13452        }
13453        if (intent.getComponent() == null) {
13454            registeredReceivers = mReceiverResolver.queryIntent(intent,
13455                    resolvedType, false, userId);
13456        }
13457
13458        final boolean replacePending =
13459                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13460
13461        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13462                + " replacePending=" + replacePending);
13463
13464        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13465        if (!ordered && NR > 0) {
13466            // If we are not serializing this broadcast, then send the
13467            // registered receivers separately so they don't wait for the
13468            // components to be launched.
13469            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13470            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13471                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13472                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13473                    ordered, sticky, false, userId);
13474            if (DEBUG_BROADCAST) Slog.v(
13475                    TAG, "Enqueueing parallel broadcast " + r);
13476            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13477            if (!replaced) {
13478                queue.enqueueParallelBroadcastLocked(r);
13479                queue.scheduleBroadcastsLocked();
13480            }
13481            registeredReceivers = null;
13482            NR = 0;
13483        }
13484
13485        // Merge into one list.
13486        int ir = 0;
13487        if (receivers != null) {
13488            // A special case for PACKAGE_ADDED: do not allow the package
13489            // being added to see this broadcast.  This prevents them from
13490            // using this as a back door to get run as soon as they are
13491            // installed.  Maybe in the future we want to have a special install
13492            // broadcast or such for apps, but we'd like to deliberately make
13493            // this decision.
13494            String skipPackages[] = null;
13495            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13496                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13497                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13498                Uri data = intent.getData();
13499                if (data != null) {
13500                    String pkgName = data.getSchemeSpecificPart();
13501                    if (pkgName != null) {
13502                        skipPackages = new String[] { pkgName };
13503                    }
13504                }
13505            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13506                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13507            }
13508            if (skipPackages != null && (skipPackages.length > 0)) {
13509                for (String skipPackage : skipPackages) {
13510                    if (skipPackage != null) {
13511                        int NT = receivers.size();
13512                        for (int it=0; it<NT; it++) {
13513                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13514                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13515                                receivers.remove(it);
13516                                it--;
13517                                NT--;
13518                            }
13519                        }
13520                    }
13521                }
13522            }
13523
13524            int NT = receivers != null ? receivers.size() : 0;
13525            int it = 0;
13526            ResolveInfo curt = null;
13527            BroadcastFilter curr = null;
13528            while (it < NT && ir < NR) {
13529                if (curt == null) {
13530                    curt = (ResolveInfo)receivers.get(it);
13531                }
13532                if (curr == null) {
13533                    curr = registeredReceivers.get(ir);
13534                }
13535                if (curr.getPriority() >= curt.priority) {
13536                    // Insert this broadcast record into the final list.
13537                    receivers.add(it, curr);
13538                    ir++;
13539                    curr = null;
13540                    it++;
13541                    NT++;
13542                } else {
13543                    // Skip to the next ResolveInfo in the final list.
13544                    it++;
13545                    curt = null;
13546                }
13547            }
13548        }
13549        while (ir < NR) {
13550            if (receivers == null) {
13551                receivers = new ArrayList();
13552            }
13553            receivers.add(registeredReceivers.get(ir));
13554            ir++;
13555        }
13556
13557        if ((receivers != null && receivers.size() > 0)
13558                || resultTo != null) {
13559            BroadcastQueue queue = broadcastQueueForIntent(intent);
13560            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13561                    callerPackage, callingPid, callingUid, resolvedType,
13562                    requiredPermission, appOp, receivers, resultTo, resultCode,
13563                    resultData, map, ordered, sticky, false, userId);
13564            if (DEBUG_BROADCAST) Slog.v(
13565                    TAG, "Enqueueing ordered broadcast " + r
13566                    + ": prev had " + queue.mOrderedBroadcasts.size());
13567            if (DEBUG_BROADCAST) {
13568                int seq = r.intent.getIntExtra("seq", -1);
13569                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13570            }
13571            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13572            if (!replaced) {
13573                queue.enqueueOrderedBroadcastLocked(r);
13574                queue.scheduleBroadcastsLocked();
13575            }
13576        }
13577
13578        return ActivityManager.BROADCAST_SUCCESS;
13579    }
13580
13581    final Intent verifyBroadcastLocked(Intent intent) {
13582        // Refuse possible leaked file descriptors
13583        if (intent != null && intent.hasFileDescriptors() == true) {
13584            throw new IllegalArgumentException("File descriptors passed in Intent");
13585        }
13586
13587        int flags = intent.getFlags();
13588
13589        if (!mProcessesReady) {
13590            // if the caller really truly claims to know what they're doing, go
13591            // ahead and allow the broadcast without launching any receivers
13592            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13593                intent = new Intent(intent);
13594                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13595            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13596                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13597                        + " before boot completion");
13598                throw new IllegalStateException("Cannot broadcast before boot completed");
13599            }
13600        }
13601
13602        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13603            throw new IllegalArgumentException(
13604                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13605        }
13606
13607        return intent;
13608    }
13609
13610    public final int broadcastIntent(IApplicationThread caller,
13611            Intent intent, String resolvedType, IIntentReceiver resultTo,
13612            int resultCode, String resultData, Bundle map,
13613            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13614        enforceNotIsolatedCaller("broadcastIntent");
13615        synchronized(this) {
13616            intent = verifyBroadcastLocked(intent);
13617
13618            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13619            final int callingPid = Binder.getCallingPid();
13620            final int callingUid = Binder.getCallingUid();
13621            final long origId = Binder.clearCallingIdentity();
13622            int res = broadcastIntentLocked(callerApp,
13623                    callerApp != null ? callerApp.info.packageName : null,
13624                    intent, resolvedType, resultTo,
13625                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13626                    callingPid, callingUid, userId);
13627            Binder.restoreCallingIdentity(origId);
13628            return res;
13629        }
13630    }
13631
13632    int broadcastIntentInPackage(String packageName, int uid,
13633            Intent intent, String resolvedType, IIntentReceiver resultTo,
13634            int resultCode, String resultData, Bundle map,
13635            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13636        synchronized(this) {
13637            intent = verifyBroadcastLocked(intent);
13638
13639            final long origId = Binder.clearCallingIdentity();
13640            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13641                    resultTo, resultCode, resultData, map, requiredPermission,
13642                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13643            Binder.restoreCallingIdentity(origId);
13644            return res;
13645        }
13646    }
13647
13648    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13649        // Refuse possible leaked file descriptors
13650        if (intent != null && intent.hasFileDescriptors() == true) {
13651            throw new IllegalArgumentException("File descriptors passed in Intent");
13652        }
13653
13654        userId = handleIncomingUser(Binder.getCallingPid(),
13655                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13656
13657        synchronized(this) {
13658            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13659                    != PackageManager.PERMISSION_GRANTED) {
13660                String msg = "Permission Denial: unbroadcastIntent() from pid="
13661                        + Binder.getCallingPid()
13662                        + ", uid=" + Binder.getCallingUid()
13663                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13664                Slog.w(TAG, msg);
13665                throw new SecurityException(msg);
13666            }
13667            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13668            if (stickies != null) {
13669                ArrayList<Intent> list = stickies.get(intent.getAction());
13670                if (list != null) {
13671                    int N = list.size();
13672                    int i;
13673                    for (i=0; i<N; i++) {
13674                        if (intent.filterEquals(list.get(i))) {
13675                            list.remove(i);
13676                            break;
13677                        }
13678                    }
13679                    if (list.size() <= 0) {
13680                        stickies.remove(intent.getAction());
13681                    }
13682                }
13683                if (stickies.size() <= 0) {
13684                    mStickyBroadcasts.remove(userId);
13685                }
13686            }
13687        }
13688    }
13689
13690    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13691            String resultData, Bundle resultExtras, boolean resultAbort) {
13692        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13693        if (r == null) {
13694            Slog.w(TAG, "finishReceiver called but not found on queue");
13695            return false;
13696        }
13697
13698        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13699    }
13700
13701    void backgroundServicesFinishedLocked(int userId) {
13702        for (BroadcastQueue queue : mBroadcastQueues) {
13703            queue.backgroundServicesFinishedLocked(userId);
13704        }
13705    }
13706
13707    public void finishReceiver(IBinder who, int resultCode, String resultData,
13708            Bundle resultExtras, boolean resultAbort) {
13709        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13710
13711        // Refuse possible leaked file descriptors
13712        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13713            throw new IllegalArgumentException("File descriptors passed in Bundle");
13714        }
13715
13716        final long origId = Binder.clearCallingIdentity();
13717        try {
13718            boolean doNext = false;
13719            BroadcastRecord r;
13720
13721            synchronized(this) {
13722                r = broadcastRecordForReceiverLocked(who);
13723                if (r != null) {
13724                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13725                        resultData, resultExtras, resultAbort, true);
13726                }
13727            }
13728
13729            if (doNext) {
13730                r.queue.processNextBroadcast(false);
13731            }
13732            trimApplications();
13733        } finally {
13734            Binder.restoreCallingIdentity(origId);
13735        }
13736    }
13737
13738    // =========================================================
13739    // INSTRUMENTATION
13740    // =========================================================
13741
13742    public boolean startInstrumentation(ComponentName className,
13743            String profileFile, int flags, Bundle arguments,
13744            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13745            int userId) {
13746        enforceNotIsolatedCaller("startInstrumentation");
13747        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13748                userId, false, true, "startInstrumentation", null);
13749        // Refuse possible leaked file descriptors
13750        if (arguments != null && arguments.hasFileDescriptors()) {
13751            throw new IllegalArgumentException("File descriptors passed in Bundle");
13752        }
13753
13754        synchronized(this) {
13755            InstrumentationInfo ii = null;
13756            ApplicationInfo ai = null;
13757            try {
13758                ii = mContext.getPackageManager().getInstrumentationInfo(
13759                    className, STOCK_PM_FLAGS);
13760                ai = AppGlobals.getPackageManager().getApplicationInfo(
13761                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13762            } catch (PackageManager.NameNotFoundException e) {
13763            } catch (RemoteException e) {
13764            }
13765            if (ii == null) {
13766                reportStartInstrumentationFailure(watcher, className,
13767                        "Unable to find instrumentation info for: " + className);
13768                return false;
13769            }
13770            if (ai == null) {
13771                reportStartInstrumentationFailure(watcher, className,
13772                        "Unable to find instrumentation target package: " + ii.targetPackage);
13773                return false;
13774            }
13775
13776            int match = mContext.getPackageManager().checkSignatures(
13777                    ii.targetPackage, ii.packageName);
13778            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13779                String msg = "Permission Denial: starting instrumentation "
13780                        + className + " from pid="
13781                        + Binder.getCallingPid()
13782                        + ", uid=" + Binder.getCallingPid()
13783                        + " not allowed because package " + ii.packageName
13784                        + " does not have a signature matching the target "
13785                        + ii.targetPackage;
13786                reportStartInstrumentationFailure(watcher, className, msg);
13787                throw new SecurityException(msg);
13788            }
13789
13790            final long origId = Binder.clearCallingIdentity();
13791            // Instrumentation can kill and relaunch even persistent processes
13792            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
13793                    "start instr");
13794            ProcessRecord app = addAppLocked(ai, false);
13795            app.instrumentationClass = className;
13796            app.instrumentationInfo = ai;
13797            app.instrumentationProfileFile = profileFile;
13798            app.instrumentationArguments = arguments;
13799            app.instrumentationWatcher = watcher;
13800            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13801            app.instrumentationResultClass = className;
13802            Binder.restoreCallingIdentity(origId);
13803        }
13804
13805        return true;
13806    }
13807
13808    /**
13809     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13810     * error to the logs, but if somebody is watching, send the report there too.  This enables
13811     * the "am" command to report errors with more information.
13812     *
13813     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13814     * @param cn The component name of the instrumentation.
13815     * @param report The error report.
13816     */
13817    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13818            ComponentName cn, String report) {
13819        Slog.w(TAG, report);
13820        try {
13821            if (watcher != null) {
13822                Bundle results = new Bundle();
13823                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13824                results.putString("Error", report);
13825                watcher.instrumentationStatus(cn, -1, results);
13826            }
13827        } catch (RemoteException e) {
13828            Slog.w(TAG, e);
13829        }
13830    }
13831
13832    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13833        if (app.instrumentationWatcher != null) {
13834            try {
13835                // NOTE:  IInstrumentationWatcher *must* be oneway here
13836                app.instrumentationWatcher.instrumentationFinished(
13837                    app.instrumentationClass,
13838                    resultCode,
13839                    results);
13840            } catch (RemoteException e) {
13841            }
13842        }
13843        if (app.instrumentationUiAutomationConnection != null) {
13844            try {
13845                app.instrumentationUiAutomationConnection.shutdown();
13846            } catch (RemoteException re) {
13847                /* ignore */
13848            }
13849            // Only a UiAutomation can set this flag and now that
13850            // it is finished we make sure it is reset to its default.
13851            mUserIsMonkey = false;
13852        }
13853        app.instrumentationWatcher = null;
13854        app.instrumentationUiAutomationConnection = null;
13855        app.instrumentationClass = null;
13856        app.instrumentationInfo = null;
13857        app.instrumentationProfileFile = null;
13858        app.instrumentationArguments = null;
13859
13860        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
13861                "finished inst");
13862    }
13863
13864    public void finishInstrumentation(IApplicationThread target,
13865            int resultCode, Bundle results) {
13866        int userId = UserHandle.getCallingUserId();
13867        // Refuse possible leaked file descriptors
13868        if (results != null && results.hasFileDescriptors()) {
13869            throw new IllegalArgumentException("File descriptors passed in Intent");
13870        }
13871
13872        synchronized(this) {
13873            ProcessRecord app = getRecordForAppLocked(target);
13874            if (app == null) {
13875                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13876                return;
13877            }
13878            final long origId = Binder.clearCallingIdentity();
13879            finishInstrumentationLocked(app, resultCode, results);
13880            Binder.restoreCallingIdentity(origId);
13881        }
13882    }
13883
13884    // =========================================================
13885    // CONFIGURATION
13886    // =========================================================
13887
13888    public ConfigurationInfo getDeviceConfigurationInfo() {
13889        ConfigurationInfo config = new ConfigurationInfo();
13890        synchronized (this) {
13891            config.reqTouchScreen = mConfiguration.touchscreen;
13892            config.reqKeyboardType = mConfiguration.keyboard;
13893            config.reqNavigation = mConfiguration.navigation;
13894            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13895                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13896                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13897            }
13898            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13899                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13900                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13901            }
13902            config.reqGlEsVersion = GL_ES_VERSION;
13903        }
13904        return config;
13905    }
13906
13907    ActivityStack getFocusedStack() {
13908        return mStackSupervisor.getFocusedStack();
13909    }
13910
13911    public Configuration getConfiguration() {
13912        Configuration ci;
13913        synchronized(this) {
13914            ci = new Configuration(mConfiguration);
13915        }
13916        return ci;
13917    }
13918
13919    public void updatePersistentConfiguration(Configuration values) {
13920        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13921                "updateConfiguration()");
13922        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13923                "updateConfiguration()");
13924        if (values == null) {
13925            throw new NullPointerException("Configuration must not be null");
13926        }
13927
13928        synchronized(this) {
13929            final long origId = Binder.clearCallingIdentity();
13930            updateConfigurationLocked(values, null, true, false);
13931            Binder.restoreCallingIdentity(origId);
13932        }
13933    }
13934
13935    public void updateConfiguration(Configuration values) {
13936        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13937                "updateConfiguration()");
13938
13939        synchronized(this) {
13940            if (values == null && mWindowManager != null) {
13941                // sentinel: fetch the current configuration from the window manager
13942                values = mWindowManager.computeNewConfiguration();
13943            }
13944
13945            if (mWindowManager != null) {
13946                mProcessList.applyDisplaySize(mWindowManager);
13947            }
13948
13949            final long origId = Binder.clearCallingIdentity();
13950            if (values != null) {
13951                Settings.System.clearConfiguration(values);
13952            }
13953            updateConfigurationLocked(values, null, false, false);
13954            Binder.restoreCallingIdentity(origId);
13955        }
13956    }
13957
13958    /**
13959     * Do either or both things: (1) change the current configuration, and (2)
13960     * make sure the given activity is running with the (now) current
13961     * configuration.  Returns true if the activity has been left running, or
13962     * false if <var>starting</var> is being destroyed to match the new
13963     * configuration.
13964     * @param persistent TODO
13965     */
13966    boolean updateConfigurationLocked(Configuration values,
13967            ActivityRecord starting, boolean persistent, boolean initLocale) {
13968        int changes = 0;
13969
13970        if (values != null) {
13971            Configuration newConfig = new Configuration(mConfiguration);
13972            changes = newConfig.updateFrom(values);
13973            if (changes != 0) {
13974                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13975                    Slog.i(TAG, "Updating configuration to: " + values);
13976                }
13977
13978                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13979
13980                if (values.locale != null && !initLocale) {
13981                    saveLocaleLocked(values.locale,
13982                                     !values.locale.equals(mConfiguration.locale),
13983                                     values.userSetLocale);
13984                }
13985
13986                mConfigurationSeq++;
13987                if (mConfigurationSeq <= 0) {
13988                    mConfigurationSeq = 1;
13989                }
13990                newConfig.seq = mConfigurationSeq;
13991                mConfiguration = newConfig;
13992                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
13993
13994                final Configuration configCopy = new Configuration(mConfiguration);
13995
13996                // TODO: If our config changes, should we auto dismiss any currently
13997                // showing dialogs?
13998                mShowDialogs = shouldShowDialogs(newConfig);
13999
14000                AttributeCache ac = AttributeCache.instance();
14001                if (ac != null) {
14002                    ac.updateConfiguration(configCopy);
14003                }
14004
14005                // Make sure all resources in our process are updated
14006                // right now, so that anyone who is going to retrieve
14007                // resource values after we return will be sure to get
14008                // the new ones.  This is especially important during
14009                // boot, where the first config change needs to guarantee
14010                // all resources have that config before following boot
14011                // code is executed.
14012                mSystemThread.applyConfigurationToResources(configCopy);
14013
14014                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14015                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14016                    msg.obj = new Configuration(configCopy);
14017                    mHandler.sendMessage(msg);
14018                }
14019
14020                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14021                    ProcessRecord app = mLruProcesses.get(i);
14022                    try {
14023                        if (app.thread != null) {
14024                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14025                                    + app.processName + " new config " + mConfiguration);
14026                            app.thread.scheduleConfigurationChanged(configCopy);
14027                        }
14028                    } catch (Exception e) {
14029                    }
14030                }
14031                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14032                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14033                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14034                        | Intent.FLAG_RECEIVER_FOREGROUND);
14035                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14036                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14037                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14038                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14039                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14040                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14041                    broadcastIntentLocked(null, null, intent,
14042                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14043                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14044                }
14045            }
14046        }
14047
14048        boolean kept = true;
14049        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14050        // mainStack is null during startup.
14051        if (mainStack != null) {
14052            if (changes != 0 && starting == null) {
14053                // If the configuration changed, and the caller is not already
14054                // in the process of starting an activity, then find the top
14055                // activity to check if its configuration needs to change.
14056                starting = mainStack.topRunningActivityLocked(null);
14057            }
14058
14059            if (starting != null) {
14060                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14061                // And we need to make sure at this point that all other activities
14062                // are made visible with the correct configuration.
14063                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14064            }
14065        }
14066
14067        if (values != null && mWindowManager != null) {
14068            mWindowManager.setNewConfiguration(mConfiguration);
14069        }
14070
14071        return kept;
14072    }
14073
14074    /**
14075     * Decide based on the configuration whether we should shouw the ANR,
14076     * crash, etc dialogs.  The idea is that if there is no affordnace to
14077     * press the on-screen buttons, we shouldn't show the dialog.
14078     *
14079     * A thought: SystemUI might also want to get told about this, the Power
14080     * dialog / global actions also might want different behaviors.
14081     */
14082    private static final boolean shouldShowDialogs(Configuration config) {
14083        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14084                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14085    }
14086
14087    /**
14088     * Save the locale.  You must be inside a synchronized (this) block.
14089     */
14090    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14091        if(isDiff) {
14092            SystemProperties.set("user.language", l.getLanguage());
14093            SystemProperties.set("user.region", l.getCountry());
14094        }
14095
14096        if(isPersist) {
14097            SystemProperties.set("persist.sys.language", l.getLanguage());
14098            SystemProperties.set("persist.sys.country", l.getCountry());
14099            SystemProperties.set("persist.sys.localevar", l.getVariant());
14100        }
14101    }
14102
14103    @Override
14104    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14105        ActivityRecord srec = ActivityRecord.forToken(token);
14106        return srec != null && srec.task.affinity != null &&
14107                srec.task.affinity.equals(destAffinity);
14108    }
14109
14110    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14111            Intent resultData) {
14112
14113        synchronized (this) {
14114            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14115            if (stack != null) {
14116                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14117            }
14118            return false;
14119        }
14120    }
14121
14122    public int getLaunchedFromUid(IBinder activityToken) {
14123        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14124        if (srec == null) {
14125            return -1;
14126        }
14127        return srec.launchedFromUid;
14128    }
14129
14130    public String getLaunchedFromPackage(IBinder activityToken) {
14131        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14132        if (srec == null) {
14133            return null;
14134        }
14135        return srec.launchedFromPackage;
14136    }
14137
14138    // =========================================================
14139    // LIFETIME MANAGEMENT
14140    // =========================================================
14141
14142    // Returns which broadcast queue the app is the current [or imminent] receiver
14143    // on, or 'null' if the app is not an active broadcast recipient.
14144    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14145        BroadcastRecord r = app.curReceiver;
14146        if (r != null) {
14147            return r.queue;
14148        }
14149
14150        // It's not the current receiver, but it might be starting up to become one
14151        synchronized (this) {
14152            for (BroadcastQueue queue : mBroadcastQueues) {
14153                r = queue.mPendingBroadcast;
14154                if (r != null && r.curApp == app) {
14155                    // found it; report which queue it's in
14156                    return queue;
14157                }
14158            }
14159        }
14160
14161        return null;
14162    }
14163
14164    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14165            boolean doingAll, long now) {
14166        if (mAdjSeq == app.adjSeq) {
14167            // This adjustment has already been computed.
14168            return app.curRawAdj;
14169        }
14170
14171        if (app.thread == null) {
14172            app.adjSeq = mAdjSeq;
14173            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14174            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14175            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14176        }
14177
14178        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14179        app.adjSource = null;
14180        app.adjTarget = null;
14181        app.empty = false;
14182        app.cached = false;
14183
14184        final int activitiesSize = app.activities.size();
14185
14186        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14187            // The max adjustment doesn't allow this app to be anything
14188            // below foreground, so it is not worth doing work for it.
14189            app.adjType = "fixed";
14190            app.adjSeq = mAdjSeq;
14191            app.curRawAdj = app.maxAdj;
14192            app.foregroundActivities = false;
14193            app.keeping = true;
14194            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14195            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14196            // System process can do UI, and when they do we want to have
14197            // them trim their memory after the user leaves the UI.  To
14198            // facilitate this, here we need to determine whether or not it
14199            // is currently showing UI.
14200            app.systemNoUi = true;
14201            if (app == TOP_APP) {
14202                app.systemNoUi = false;
14203            } else if (activitiesSize > 0) {
14204                for (int j = 0; j < activitiesSize; j++) {
14205                    final ActivityRecord r = app.activities.get(j);
14206                    if (r.visible) {
14207                        app.systemNoUi = false;
14208                    }
14209                }
14210            }
14211            if (!app.systemNoUi) {
14212                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14213            }
14214            return (app.curAdj=app.maxAdj);
14215        }
14216
14217        app.keeping = false;
14218        app.systemNoUi = false;
14219
14220        // Determine the importance of the process, starting with most
14221        // important to least, and assign an appropriate OOM adjustment.
14222        int adj;
14223        int schedGroup;
14224        int procState;
14225        boolean foregroundActivities = false;
14226        boolean interesting = false;
14227        BroadcastQueue queue;
14228        if (app == TOP_APP) {
14229            // The last app on the list is the foreground app.
14230            adj = ProcessList.FOREGROUND_APP_ADJ;
14231            schedGroup = Process.THREAD_GROUP_DEFAULT;
14232            app.adjType = "top-activity";
14233            foregroundActivities = true;
14234            interesting = true;
14235            procState = ActivityManager.PROCESS_STATE_TOP;
14236        } else if (app.instrumentationClass != null) {
14237            // Don't want to kill running instrumentation.
14238            adj = ProcessList.FOREGROUND_APP_ADJ;
14239            schedGroup = Process.THREAD_GROUP_DEFAULT;
14240            app.adjType = "instrumentation";
14241            interesting = true;
14242            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14243        } else if ((queue = isReceivingBroadcast(app)) != null) {
14244            // An app that is currently receiving a broadcast also
14245            // counts as being in the foreground for OOM killer purposes.
14246            // It's placed in a sched group based on the nature of the
14247            // broadcast as reflected by which queue it's active in.
14248            adj = ProcessList.FOREGROUND_APP_ADJ;
14249            schedGroup = (queue == mFgBroadcastQueue)
14250                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14251            app.adjType = "broadcast";
14252            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14253        } else if (app.executingServices.size() > 0) {
14254            // An app that is currently executing a service callback also
14255            // counts as being in the foreground.
14256            adj = ProcessList.FOREGROUND_APP_ADJ;
14257            schedGroup = app.execServicesFg ?
14258                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14259            app.adjType = "exec-service";
14260            procState = ActivityManager.PROCESS_STATE_SERVICE;
14261            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14262        } else {
14263            // As far as we know the process is empty.  We may change our mind later.
14264            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14265            // At this point we don't actually know the adjustment.  Use the cached adj
14266            // value that the caller wants us to.
14267            adj = cachedAdj;
14268            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14269            app.cached = true;
14270            app.empty = true;
14271            app.adjType = "cch-empty";
14272        }
14273
14274        // Examine all activities if not already foreground.
14275        if (!foregroundActivities && activitiesSize > 0) {
14276            for (int j = 0; j < activitiesSize; j++) {
14277                final ActivityRecord r = app.activities.get(j);
14278                if (r.app != app) {
14279                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14280                            + app + "?!?");
14281                    continue;
14282                }
14283                if (r.visible) {
14284                    // App has a visible activity; only upgrade adjustment.
14285                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14286                        adj = ProcessList.VISIBLE_APP_ADJ;
14287                        app.adjType = "visible";
14288                    }
14289                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14290                        procState = ActivityManager.PROCESS_STATE_TOP;
14291                    }
14292                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14293                    app.cached = false;
14294                    app.empty = false;
14295                    foregroundActivities = true;
14296                    break;
14297                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14298                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14299                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14300                        app.adjType = "pausing";
14301                    }
14302                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14303                        procState = ActivityManager.PROCESS_STATE_TOP;
14304                    }
14305                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14306                    app.cached = false;
14307                    app.empty = false;
14308                    foregroundActivities = true;
14309                } else if (r.state == ActivityState.STOPPING) {
14310                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14311                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14312                        app.adjType = "stopping";
14313                    }
14314                    // For the process state, we will at this point consider the
14315                    // process to be cached.  It will be cached either as an activity
14316                    // or empty depending on whether the activity is finishing.  We do
14317                    // this so that we can treat the process as cached for purposes of
14318                    // memory trimming (determing current memory level, trim command to
14319                    // send to process) since there can be an arbitrary number of stopping
14320                    // processes and they should soon all go into the cached state.
14321                    if (!r.finishing) {
14322                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14323                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14324                        }
14325                    }
14326                    app.cached = false;
14327                    app.empty = false;
14328                    foregroundActivities = true;
14329                } else {
14330                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14331                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14332                        app.adjType = "cch-act";
14333                    }
14334                }
14335            }
14336        }
14337
14338        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14339            if (app.foregroundServices) {
14340                // The user is aware of this app, so make it visible.
14341                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14342                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14343                app.cached = false;
14344                app.adjType = "fg-service";
14345                schedGroup = Process.THREAD_GROUP_DEFAULT;
14346            } else if (app.forcingToForeground != null) {
14347                // The user is aware of this app, so make it visible.
14348                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14349                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14350                app.cached = false;
14351                app.adjType = "force-fg";
14352                app.adjSource = app.forcingToForeground;
14353                schedGroup = Process.THREAD_GROUP_DEFAULT;
14354            }
14355        }
14356
14357        if (app.foregroundServices) {
14358            interesting = true;
14359        }
14360
14361        if (app == mHeavyWeightProcess) {
14362            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14363                // We don't want to kill the current heavy-weight process.
14364                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14365                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14366                app.cached = false;
14367                app.adjType = "heavy";
14368            }
14369            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14370                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14371            }
14372        }
14373
14374        if (app == mHomeProcess) {
14375            if (adj > ProcessList.HOME_APP_ADJ) {
14376                // This process is hosting what we currently consider to be the
14377                // home app, so we don't want to let it go into the background.
14378                adj = ProcessList.HOME_APP_ADJ;
14379                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14380                app.cached = false;
14381                app.adjType = "home";
14382            }
14383            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14384                procState = ActivityManager.PROCESS_STATE_HOME;
14385            }
14386        }
14387
14388        if (app == mPreviousProcess && app.activities.size() > 0) {
14389            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14390                // This was the previous process that showed UI to the user.
14391                // We want to try to keep it around more aggressively, to give
14392                // a good experience around switching between two apps.
14393                adj = ProcessList.PREVIOUS_APP_ADJ;
14394                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14395                app.cached = false;
14396                app.adjType = "previous";
14397            }
14398            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14399                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14400            }
14401        }
14402
14403        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14404                + " reason=" + app.adjType);
14405
14406        // By default, we use the computed adjustment.  It may be changed if
14407        // there are applications dependent on our services or providers, but
14408        // this gives us a baseline and makes sure we don't get into an
14409        // infinite recursion.
14410        app.adjSeq = mAdjSeq;
14411        app.curRawAdj = adj;
14412        app.hasStartedServices = false;
14413
14414        if (mBackupTarget != null && app == mBackupTarget.app) {
14415            // If possible we want to avoid killing apps while they're being backed up
14416            if (adj > ProcessList.BACKUP_APP_ADJ) {
14417                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14418                adj = ProcessList.BACKUP_APP_ADJ;
14419                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14420                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14421                }
14422                app.adjType = "backup";
14423                app.cached = false;
14424            }
14425            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14426                procState = ActivityManager.PROCESS_STATE_BACKUP;
14427            }
14428        }
14429
14430        boolean mayBeTop = false;
14431
14432        for (int is = app.services.size()-1;
14433                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14434                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14435                        || procState > ActivityManager.PROCESS_STATE_TOP);
14436                is--) {
14437            ServiceRecord s = app.services.valueAt(is);
14438            if (s.startRequested) {
14439                app.hasStartedServices = true;
14440                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14441                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14442                }
14443                if (app.hasShownUi && app != mHomeProcess) {
14444                    // If this process has shown some UI, let it immediately
14445                    // go to the LRU list because it may be pretty heavy with
14446                    // UI stuff.  We'll tag it with a label just to help
14447                    // debug and understand what is going on.
14448                    if (adj > ProcessList.SERVICE_ADJ) {
14449                        app.adjType = "cch-started-ui-services";
14450                    }
14451                } else {
14452                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14453                        // This service has seen some activity within
14454                        // recent memory, so we will keep its process ahead
14455                        // of the background processes.
14456                        if (adj > ProcessList.SERVICE_ADJ) {
14457                            adj = ProcessList.SERVICE_ADJ;
14458                            app.adjType = "started-services";
14459                            app.cached = false;
14460                        }
14461                    }
14462                    // If we have let the service slide into the background
14463                    // state, still have some text describing what it is doing
14464                    // even though the service no longer has an impact.
14465                    if (adj > ProcessList.SERVICE_ADJ) {
14466                        app.adjType = "cch-started-services";
14467                    }
14468                }
14469                // Don't kill this process because it is doing work; it
14470                // has said it is doing work.
14471                app.keeping = true;
14472            }
14473            for (int conni = s.connections.size()-1;
14474                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14475                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14476                            || procState > ActivityManager.PROCESS_STATE_TOP);
14477                    conni--) {
14478                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14479                for (int i = 0;
14480                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14481                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14482                                || procState > ActivityManager.PROCESS_STATE_TOP);
14483                        i++) {
14484                    // XXX should compute this based on the max of
14485                    // all connected clients.
14486                    ConnectionRecord cr = clist.get(i);
14487                    if (cr.binding.client == app) {
14488                        // Binding to ourself is not interesting.
14489                        continue;
14490                    }
14491                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14492                        ProcessRecord client = cr.binding.client;
14493                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14494                                TOP_APP, doingAll, now);
14495                        int clientProcState = client.curProcState;
14496                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14497                            // If the other app is cached for any reason, for purposes here
14498                            // we are going to consider it empty.  The specific cached state
14499                            // doesn't propagate except under certain conditions.
14500                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14501                        }
14502                        String adjType = null;
14503                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14504                            // Not doing bind OOM management, so treat
14505                            // this guy more like a started service.
14506                            if (app.hasShownUi && app != mHomeProcess) {
14507                                // If this process has shown some UI, let it immediately
14508                                // go to the LRU list because it may be pretty heavy with
14509                                // UI stuff.  We'll tag it with a label just to help
14510                                // debug and understand what is going on.
14511                                if (adj > clientAdj) {
14512                                    adjType = "cch-bound-ui-services";
14513                                }
14514                                app.cached = false;
14515                                clientAdj = adj;
14516                                clientProcState = procState;
14517                            } else {
14518                                if (now >= (s.lastActivity
14519                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14520                                    // This service has not seen activity within
14521                                    // recent memory, so allow it to drop to the
14522                                    // LRU list if there is no other reason to keep
14523                                    // it around.  We'll also tag it with a label just
14524                                    // to help debug and undertand what is going on.
14525                                    if (adj > clientAdj) {
14526                                        adjType = "cch-bound-services";
14527                                    }
14528                                    clientAdj = adj;
14529                                }
14530                            }
14531                        }
14532                        if (adj > clientAdj) {
14533                            // If this process has recently shown UI, and
14534                            // the process that is binding to it is less
14535                            // important than being visible, then we don't
14536                            // care about the binding as much as we care
14537                            // about letting this process get into the LRU
14538                            // list to be killed and restarted if needed for
14539                            // memory.
14540                            if (app.hasShownUi && app != mHomeProcess
14541                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14542                                adjType = "cch-bound-ui-services";
14543                            } else {
14544                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14545                                        |Context.BIND_IMPORTANT)) != 0) {
14546                                    adj = clientAdj;
14547                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14548                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14549                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14550                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14551                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14552                                    adj = clientAdj;
14553                                } else {
14554                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14555                                        adj = ProcessList.VISIBLE_APP_ADJ;
14556                                    }
14557                                }
14558                                if (!client.cached) {
14559                                    app.cached = false;
14560                                }
14561                                if (client.keeping) {
14562                                    app.keeping = true;
14563                                }
14564                                adjType = "service";
14565                            }
14566                        }
14567                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14568                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14569                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14570                            }
14571                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14572                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14573                                    // Special handling of clients who are in the top state.
14574                                    // We *may* want to consider this process to be in the
14575                                    // top state as well, but only if there is not another
14576                                    // reason for it to be running.  Being on the top is a
14577                                    // special state, meaning you are specifically running
14578                                    // for the current top app.  If the process is already
14579                                    // running in the background for some other reason, it
14580                                    // is more important to continue considering it to be
14581                                    // in the background state.
14582                                    mayBeTop = true;
14583                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14584                                } else {
14585                                    // Special handling for above-top states (persistent
14586                                    // processes).  These should not bring the current process
14587                                    // into the top state, since they are not on top.  Instead
14588                                    // give them the best state after that.
14589                                    clientProcState =
14590                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14591                                }
14592                            }
14593                        } else {
14594                            if (clientProcState <
14595                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14596                                clientProcState =
14597                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14598                            }
14599                        }
14600                        if (procState > clientProcState) {
14601                            procState = clientProcState;
14602                        }
14603                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14604                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14605                            app.pendingUiClean = true;
14606                        }
14607                        if (adjType != null) {
14608                            app.adjType = adjType;
14609                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14610                                    .REASON_SERVICE_IN_USE;
14611                            app.adjSource = cr.binding.client;
14612                            app.adjSourceOom = clientAdj;
14613                            app.adjTarget = s.name;
14614                        }
14615                    }
14616                    final ActivityRecord a = cr.activity;
14617                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14618                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14619                                (a.visible || a.state == ActivityState.RESUMED
14620                                 || a.state == ActivityState.PAUSING)) {
14621                            adj = ProcessList.FOREGROUND_APP_ADJ;
14622                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14623                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14624                            }
14625                            app.cached = false;
14626                            app.adjType = "service";
14627                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14628                                    .REASON_SERVICE_IN_USE;
14629                            app.adjSource = a;
14630                            app.adjSourceOom = adj;
14631                            app.adjTarget = s.name;
14632                        }
14633                    }
14634                }
14635            }
14636        }
14637
14638        for (int provi = app.pubProviders.size()-1;
14639                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14640                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14641                        || procState > ActivityManager.PROCESS_STATE_TOP);
14642                provi--) {
14643            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14644            for (int i = cpr.connections.size()-1;
14645                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14646                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14647                            || procState > ActivityManager.PROCESS_STATE_TOP);
14648                    i--) {
14649                ContentProviderConnection conn = cpr.connections.get(i);
14650                ProcessRecord client = conn.client;
14651                if (client == app) {
14652                    // Being our own client is not interesting.
14653                    continue;
14654                }
14655                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14656                int clientProcState = client.curProcState;
14657                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14658                    // If the other app is cached for any reason, for purposes here
14659                    // we are going to consider it empty.
14660                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14661                }
14662                if (adj > clientAdj) {
14663                    if (app.hasShownUi && app != mHomeProcess
14664                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14665                        app.adjType = "cch-ui-provider";
14666                    } else {
14667                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14668                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14669                        app.adjType = "provider";
14670                    }
14671                    app.cached &= client.cached;
14672                    app.keeping |= client.keeping;
14673                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14674                            .REASON_PROVIDER_IN_USE;
14675                    app.adjSource = client;
14676                    app.adjSourceOom = clientAdj;
14677                    app.adjTarget = cpr.name;
14678                }
14679                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14680                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14681                        // Special handling of clients who are in the top state.
14682                        // We *may* want to consider this process to be in the
14683                        // top state as well, but only if there is not another
14684                        // reason for it to be running.  Being on the top is a
14685                        // special state, meaning you are specifically running
14686                        // for the current top app.  If the process is already
14687                        // running in the background for some other reason, it
14688                        // is more important to continue considering it to be
14689                        // in the background state.
14690                        mayBeTop = true;
14691                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14692                    } else {
14693                        // Special handling for above-top states (persistent
14694                        // processes).  These should not bring the current process
14695                        // into the top state, since they are not on top.  Instead
14696                        // give them the best state after that.
14697                        clientProcState =
14698                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14699                    }
14700                }
14701                if (procState > clientProcState) {
14702                    procState = clientProcState;
14703                }
14704                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14705                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14706                }
14707            }
14708            // If the provider has external (non-framework) process
14709            // dependencies, ensure that its adjustment is at least
14710            // FOREGROUND_APP_ADJ.
14711            if (cpr.hasExternalProcessHandles()) {
14712                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14713                    adj = ProcessList.FOREGROUND_APP_ADJ;
14714                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14715                    app.cached = false;
14716                    app.keeping = true;
14717                    app.adjType = "provider";
14718                    app.adjTarget = cpr.name;
14719                }
14720                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14721                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14722                }
14723            }
14724        }
14725
14726        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14727            // A client of one of our services or providers is in the top state.  We
14728            // *may* want to be in the top state, but not if we are already running in
14729            // the background for some other reason.  For the decision here, we are going
14730            // to pick out a few specific states that we want to remain in when a client
14731            // is top (states that tend to be longer-term) and otherwise allow it to go
14732            // to the top state.
14733            switch (procState) {
14734                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14735                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14736                case ActivityManager.PROCESS_STATE_SERVICE:
14737                    // These all are longer-term states, so pull them up to the top
14738                    // of the background states, but not all the way to the top state.
14739                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14740                    break;
14741                default:
14742                    // Otherwise, top is a better choice, so take it.
14743                    procState = ActivityManager.PROCESS_STATE_TOP;
14744                    break;
14745            }
14746        }
14747
14748        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14749            // This is a cached process, but with client activities.  Mark it so.
14750            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14751            app.adjType = "cch-client-act";
14752        }
14753
14754        if (adj == ProcessList.SERVICE_ADJ) {
14755            if (doingAll) {
14756                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14757                mNewNumServiceProcs++;
14758                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14759                if (!app.serviceb) {
14760                    // This service isn't far enough down on the LRU list to
14761                    // normally be a B service, but if we are low on RAM and it
14762                    // is large we want to force it down since we would prefer to
14763                    // keep launcher over it.
14764                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14765                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14766                        app.serviceHighRam = true;
14767                        app.serviceb = true;
14768                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14769                    } else {
14770                        mNewNumAServiceProcs++;
14771                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14772                    }
14773                } else {
14774                    app.serviceHighRam = false;
14775                }
14776            }
14777            if (app.serviceb) {
14778                adj = ProcessList.SERVICE_B_ADJ;
14779            }
14780        }
14781
14782        app.curRawAdj = adj;
14783
14784        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14785        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14786        if (adj > app.maxAdj) {
14787            adj = app.maxAdj;
14788            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14789                schedGroup = Process.THREAD_GROUP_DEFAULT;
14790            }
14791        }
14792        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14793            app.keeping = true;
14794        }
14795
14796        // Do final modification to adj.  Everything we do between here and applying
14797        // the final setAdj must be done in this function, because we will also use
14798        // it when computing the final cached adj later.  Note that we don't need to
14799        // worry about this for max adj above, since max adj will always be used to
14800        // keep it out of the cached vaues.
14801        adj = app.modifyRawOomAdj(adj);
14802
14803        app.curProcState = procState;
14804
14805        int importance = app.memImportance;
14806        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14807            app.curAdj = adj;
14808            app.curSchedGroup = schedGroup;
14809            if (!interesting) {
14810                // For this reporting, if there is not something explicitly
14811                // interesting in this process then we will push it to the
14812                // background importance.
14813                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14814            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14815                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14816            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14817                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14818            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14819                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14820            } else if (adj >= ProcessList.SERVICE_ADJ) {
14821                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14822            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14823                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14824            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14825                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14826            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14827                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14828            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14829                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14830            } else {
14831                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14832            }
14833        }
14834
14835        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14836        if (foregroundActivities != app.foregroundActivities) {
14837            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14838        }
14839        if (changes != 0) {
14840            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14841            app.memImportance = importance;
14842            app.foregroundActivities = foregroundActivities;
14843            int i = mPendingProcessChanges.size()-1;
14844            ProcessChangeItem item = null;
14845            while (i >= 0) {
14846                item = mPendingProcessChanges.get(i);
14847                if (item.pid == app.pid) {
14848                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14849                    break;
14850                }
14851                i--;
14852            }
14853            if (i < 0) {
14854                // No existing item in pending changes; need a new one.
14855                final int NA = mAvailProcessChanges.size();
14856                if (NA > 0) {
14857                    item = mAvailProcessChanges.remove(NA-1);
14858                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14859                } else {
14860                    item = new ProcessChangeItem();
14861                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14862                }
14863                item.changes = 0;
14864                item.pid = app.pid;
14865                item.uid = app.info.uid;
14866                if (mPendingProcessChanges.size() == 0) {
14867                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14868                            "*** Enqueueing dispatch processes changed!");
14869                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14870                }
14871                mPendingProcessChanges.add(item);
14872            }
14873            item.changes |= changes;
14874            item.importance = importance;
14875            item.foregroundActivities = foregroundActivities;
14876            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14877                    + Integer.toHexString(System.identityHashCode(item))
14878                    + " " + app.toShortString() + ": changes=" + item.changes
14879                    + " importance=" + item.importance
14880                    + " foreground=" + item.foregroundActivities
14881                    + " type=" + app.adjType + " source=" + app.adjSource
14882                    + " target=" + app.adjTarget);
14883        }
14884
14885        return app.curRawAdj;
14886    }
14887
14888    /**
14889     * Schedule PSS collection of a process.
14890     */
14891    void requestPssLocked(ProcessRecord proc, int procState) {
14892        if (mPendingPssProcesses.contains(proc)) {
14893            return;
14894        }
14895        if (mPendingPssProcesses.size() == 0) {
14896            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14897        }
14898        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14899        proc.pssProcState = procState;
14900        mPendingPssProcesses.add(proc);
14901    }
14902
14903    /**
14904     * Schedule PSS collection of all processes.
14905     */
14906    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14907        if (!always) {
14908            if (now < (mLastFullPssTime +
14909                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14910                return;
14911            }
14912        }
14913        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14914        mLastFullPssTime = now;
14915        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14916        mPendingPssProcesses.clear();
14917        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14918            ProcessRecord app = mLruProcesses.get(i);
14919            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14920                app.pssProcState = app.setProcState;
14921                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14922                        mSleeping, now);
14923                mPendingPssProcesses.add(app);
14924            }
14925        }
14926        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14927    }
14928
14929    /**
14930     * Ask a given process to GC right now.
14931     */
14932    final void performAppGcLocked(ProcessRecord app) {
14933        try {
14934            app.lastRequestedGc = SystemClock.uptimeMillis();
14935            if (app.thread != null) {
14936                if (app.reportLowMemory) {
14937                    app.reportLowMemory = false;
14938                    app.thread.scheduleLowMemory();
14939                } else {
14940                    app.thread.processInBackground();
14941                }
14942            }
14943        } catch (Exception e) {
14944            // whatever.
14945        }
14946    }
14947
14948    /**
14949     * Returns true if things are idle enough to perform GCs.
14950     */
14951    private final boolean canGcNowLocked() {
14952        boolean processingBroadcasts = false;
14953        for (BroadcastQueue q : mBroadcastQueues) {
14954            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14955                processingBroadcasts = true;
14956            }
14957        }
14958        return !processingBroadcasts
14959                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14960    }
14961
14962    /**
14963     * Perform GCs on all processes that are waiting for it, but only
14964     * if things are idle.
14965     */
14966    final void performAppGcsLocked() {
14967        final int N = mProcessesToGc.size();
14968        if (N <= 0) {
14969            return;
14970        }
14971        if (canGcNowLocked()) {
14972            while (mProcessesToGc.size() > 0) {
14973                ProcessRecord proc = mProcessesToGc.remove(0);
14974                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14975                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14976                            <= SystemClock.uptimeMillis()) {
14977                        // To avoid spamming the system, we will GC processes one
14978                        // at a time, waiting a few seconds between each.
14979                        performAppGcLocked(proc);
14980                        scheduleAppGcsLocked();
14981                        return;
14982                    } else {
14983                        // It hasn't been long enough since we last GCed this
14984                        // process...  put it in the list to wait for its time.
14985                        addProcessToGcListLocked(proc);
14986                        break;
14987                    }
14988                }
14989            }
14990
14991            scheduleAppGcsLocked();
14992        }
14993    }
14994
14995    /**
14996     * If all looks good, perform GCs on all processes waiting for them.
14997     */
14998    final void performAppGcsIfAppropriateLocked() {
14999        if (canGcNowLocked()) {
15000            performAppGcsLocked();
15001            return;
15002        }
15003        // Still not idle, wait some more.
15004        scheduleAppGcsLocked();
15005    }
15006
15007    /**
15008     * Schedule the execution of all pending app GCs.
15009     */
15010    final void scheduleAppGcsLocked() {
15011        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15012
15013        if (mProcessesToGc.size() > 0) {
15014            // Schedule a GC for the time to the next process.
15015            ProcessRecord proc = mProcessesToGc.get(0);
15016            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15017
15018            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15019            long now = SystemClock.uptimeMillis();
15020            if (when < (now+GC_TIMEOUT)) {
15021                when = now + GC_TIMEOUT;
15022            }
15023            mHandler.sendMessageAtTime(msg, when);
15024        }
15025    }
15026
15027    /**
15028     * Add a process to the array of processes waiting to be GCed.  Keeps the
15029     * list in sorted order by the last GC time.  The process can't already be
15030     * on the list.
15031     */
15032    final void addProcessToGcListLocked(ProcessRecord proc) {
15033        boolean added = false;
15034        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15035            if (mProcessesToGc.get(i).lastRequestedGc <
15036                    proc.lastRequestedGc) {
15037                added = true;
15038                mProcessesToGc.add(i+1, proc);
15039                break;
15040            }
15041        }
15042        if (!added) {
15043            mProcessesToGc.add(0, proc);
15044        }
15045    }
15046
15047    /**
15048     * Set up to ask a process to GC itself.  This will either do it
15049     * immediately, or put it on the list of processes to gc the next
15050     * time things are idle.
15051     */
15052    final void scheduleAppGcLocked(ProcessRecord app) {
15053        long now = SystemClock.uptimeMillis();
15054        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15055            return;
15056        }
15057        if (!mProcessesToGc.contains(app)) {
15058            addProcessToGcListLocked(app);
15059            scheduleAppGcsLocked();
15060        }
15061    }
15062
15063    final void checkExcessivePowerUsageLocked(boolean doKills) {
15064        updateCpuStatsNow();
15065
15066        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15067        boolean doWakeKills = doKills;
15068        boolean doCpuKills = doKills;
15069        if (mLastPowerCheckRealtime == 0) {
15070            doWakeKills = false;
15071        }
15072        if (mLastPowerCheckUptime == 0) {
15073            doCpuKills = false;
15074        }
15075        if (stats.isScreenOn()) {
15076            doWakeKills = false;
15077        }
15078        final long curRealtime = SystemClock.elapsedRealtime();
15079        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15080        final long curUptime = SystemClock.uptimeMillis();
15081        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15082        mLastPowerCheckRealtime = curRealtime;
15083        mLastPowerCheckUptime = curUptime;
15084        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15085            doWakeKills = false;
15086        }
15087        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15088            doCpuKills = false;
15089        }
15090        int i = mLruProcesses.size();
15091        while (i > 0) {
15092            i--;
15093            ProcessRecord app = mLruProcesses.get(i);
15094            if (!app.keeping) {
15095                long wtime;
15096                synchronized (stats) {
15097                    wtime = stats.getProcessWakeTime(app.info.uid,
15098                            app.pid, curRealtime);
15099                }
15100                long wtimeUsed = wtime - app.lastWakeTime;
15101                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15102                if (DEBUG_POWER) {
15103                    StringBuilder sb = new StringBuilder(128);
15104                    sb.append("Wake for ");
15105                    app.toShortString(sb);
15106                    sb.append(": over ");
15107                    TimeUtils.formatDuration(realtimeSince, sb);
15108                    sb.append(" used ");
15109                    TimeUtils.formatDuration(wtimeUsed, sb);
15110                    sb.append(" (");
15111                    sb.append((wtimeUsed*100)/realtimeSince);
15112                    sb.append("%)");
15113                    Slog.i(TAG, sb.toString());
15114                    sb.setLength(0);
15115                    sb.append("CPU for ");
15116                    app.toShortString(sb);
15117                    sb.append(": over ");
15118                    TimeUtils.formatDuration(uptimeSince, sb);
15119                    sb.append(" used ");
15120                    TimeUtils.formatDuration(cputimeUsed, sb);
15121                    sb.append(" (");
15122                    sb.append((cputimeUsed*100)/uptimeSince);
15123                    sb.append("%)");
15124                    Slog.i(TAG, sb.toString());
15125                }
15126                // If a process has held a wake lock for more
15127                // than 50% of the time during this period,
15128                // that sounds bad.  Kill!
15129                if (doWakeKills && realtimeSince > 0
15130                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15131                    synchronized (stats) {
15132                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15133                                realtimeSince, wtimeUsed);
15134                    }
15135                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15136                            + " during " + realtimeSince);
15137                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15138                } else if (doCpuKills && uptimeSince > 0
15139                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15140                    synchronized (stats) {
15141                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15142                                uptimeSince, cputimeUsed);
15143                    }
15144                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15145                            + " during " + uptimeSince);
15146                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15147                } else {
15148                    app.lastWakeTime = wtime;
15149                    app.lastCpuTime = app.curCpuTime;
15150                }
15151            }
15152        }
15153    }
15154
15155    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15156            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15157        boolean success = true;
15158
15159        if (app.curRawAdj != app.setRawAdj) {
15160            if (wasKeeping && !app.keeping) {
15161                // This app is no longer something we want to keep.  Note
15162                // its current wake lock time to later know to kill it if
15163                // it is not behaving well.
15164                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15165                synchronized (stats) {
15166                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15167                            app.pid, SystemClock.elapsedRealtime());
15168                }
15169                app.lastCpuTime = app.curCpuTime;
15170            }
15171
15172            app.setRawAdj = app.curRawAdj;
15173        }
15174
15175        if (app.curAdj != app.setAdj) {
15176            ProcessList.setOomAdj(app.pid, app.curAdj);
15177            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15178                TAG, "Set " + app.pid + " " + app.processName +
15179                " adj " + app.curAdj + ": " + app.adjType);
15180            app.setAdj = app.curAdj;
15181        }
15182
15183        if (app.setSchedGroup != app.curSchedGroup) {
15184            app.setSchedGroup = app.curSchedGroup;
15185            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15186                    "Setting process group of " + app.processName
15187                    + " to " + app.curSchedGroup);
15188            if (app.waitingToKill != null &&
15189                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15190                killUnneededProcessLocked(app, app.waitingToKill);
15191                success = false;
15192            } else {
15193                if (true) {
15194                    long oldId = Binder.clearCallingIdentity();
15195                    try {
15196                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15197                    } catch (Exception e) {
15198                        Slog.w(TAG, "Failed setting process group of " + app.pid
15199                                + " to " + app.curSchedGroup);
15200                        e.printStackTrace();
15201                    } finally {
15202                        Binder.restoreCallingIdentity(oldId);
15203                    }
15204                } else {
15205                    if (app.thread != null) {
15206                        try {
15207                            app.thread.setSchedulingGroup(app.curSchedGroup);
15208                        } catch (RemoteException e) {
15209                        }
15210                    }
15211                }
15212                Process.setSwappiness(app.pid,
15213                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15214            }
15215        }
15216        if (app.repProcState != app.curProcState) {
15217            app.repProcState = app.curProcState;
15218            if (!reportingProcessState && app.thread != null) {
15219                try {
15220                    if (false) {
15221                        //RuntimeException h = new RuntimeException("here");
15222                        Slog.i(TAG, "Sending new process state " + app.repProcState
15223                                + " to " + app /*, h*/);
15224                    }
15225                    app.thread.setProcessState(app.repProcState);
15226                } catch (RemoteException e) {
15227                }
15228            }
15229        }
15230        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15231                app.setProcState)) {
15232            app.lastStateTime = now;
15233            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15234                    mSleeping, now);
15235            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15236                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15237                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15238                    + (app.nextPssTime-now) + ": " + app);
15239        } else {
15240            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15241                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15242                requestPssLocked(app, app.setProcState);
15243                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15244                        mSleeping, now);
15245            } else if (false && DEBUG_PSS) {
15246                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15247            }
15248        }
15249        if (app.setProcState != app.curProcState) {
15250            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15251                    "Proc state change of " + app.processName
15252                    + " to " + app.curProcState);
15253            app.setProcState = app.curProcState;
15254            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15255                app.notCachedSinceIdle = false;
15256            }
15257            if (!doingAll) {
15258                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15259            } else {
15260                app.procStateChanged = true;
15261            }
15262        }
15263        return success;
15264    }
15265
15266    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15267        if (proc.thread != null && proc.baseProcessTracker != null) {
15268            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15269        }
15270    }
15271
15272    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15273            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15274        if (app.thread == null) {
15275            return false;
15276        }
15277
15278        final boolean wasKeeping = app.keeping;
15279
15280        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15281
15282        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15283                reportingProcessState, now);
15284    }
15285
15286    private final ActivityRecord resumedAppLocked() {
15287        return mStackSupervisor.resumedAppLocked();
15288    }
15289
15290    final boolean updateOomAdjLocked(ProcessRecord app) {
15291        return updateOomAdjLocked(app, false);
15292    }
15293
15294    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15295        final ActivityRecord TOP_ACT = resumedAppLocked();
15296        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15297        final boolean wasCached = app.cached;
15298
15299        mAdjSeq++;
15300
15301        // This is the desired cached adjusment we want to tell it to use.
15302        // If our app is currently cached, we know it, and that is it.  Otherwise,
15303        // we don't know it yet, and it needs to now be cached we will then
15304        // need to do a complete oom adj.
15305        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15306                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15307        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15308                SystemClock.uptimeMillis());
15309        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15310            // Changed to/from cached state, so apps after it in the LRU
15311            // list may also be changed.
15312            updateOomAdjLocked();
15313        }
15314        return success;
15315    }
15316
15317    final void updateOomAdjLocked() {
15318        final ActivityRecord TOP_ACT = resumedAppLocked();
15319        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15320        final long now = SystemClock.uptimeMillis();
15321        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15322        final int N = mLruProcesses.size();
15323
15324        if (false) {
15325            RuntimeException e = new RuntimeException();
15326            e.fillInStackTrace();
15327            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15328        }
15329
15330        mAdjSeq++;
15331        mNewNumServiceProcs = 0;
15332        mNewNumAServiceProcs = 0;
15333
15334        final int emptyProcessLimit;
15335        final int cachedProcessLimit;
15336        if (mProcessLimit <= 0) {
15337            emptyProcessLimit = cachedProcessLimit = 0;
15338        } else if (mProcessLimit == 1) {
15339            emptyProcessLimit = 1;
15340            cachedProcessLimit = 0;
15341        } else {
15342            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15343            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15344        }
15345
15346        // Let's determine how many processes we have running vs.
15347        // how many slots we have for background processes; we may want
15348        // to put multiple processes in a slot of there are enough of
15349        // them.
15350        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15351                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15352        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15353        if (numEmptyProcs > cachedProcessLimit) {
15354            // If there are more empty processes than our limit on cached
15355            // processes, then use the cached process limit for the factor.
15356            // This ensures that the really old empty processes get pushed
15357            // down to the bottom, so if we are running low on memory we will
15358            // have a better chance at keeping around more cached processes
15359            // instead of a gazillion empty processes.
15360            numEmptyProcs = cachedProcessLimit;
15361        }
15362        int emptyFactor = numEmptyProcs/numSlots;
15363        if (emptyFactor < 1) emptyFactor = 1;
15364        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15365        if (cachedFactor < 1) cachedFactor = 1;
15366        int stepCached = 0;
15367        int stepEmpty = 0;
15368        int numCached = 0;
15369        int numEmpty = 0;
15370        int numTrimming = 0;
15371
15372        mNumNonCachedProcs = 0;
15373        mNumCachedHiddenProcs = 0;
15374
15375        // First update the OOM adjustment for each of the
15376        // application processes based on their current state.
15377        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15378        int nextCachedAdj = curCachedAdj+1;
15379        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15380        int nextEmptyAdj = curEmptyAdj+2;
15381        for (int i=N-1; i>=0; i--) {
15382            ProcessRecord app = mLruProcesses.get(i);
15383            if (!app.killedByAm && app.thread != null) {
15384                app.procStateChanged = false;
15385                final boolean wasKeeping = app.keeping;
15386                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15387
15388                // If we haven't yet assigned the final cached adj
15389                // to the process, do that now.
15390                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15391                    switch (app.curProcState) {
15392                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15393                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15394                            // This process is a cached process holding activities...
15395                            // assign it the next cached value for that type, and then
15396                            // step that cached level.
15397                            app.curRawAdj = curCachedAdj;
15398                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15399                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15400                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15401                                    + ")");
15402                            if (curCachedAdj != nextCachedAdj) {
15403                                stepCached++;
15404                                if (stepCached >= cachedFactor) {
15405                                    stepCached = 0;
15406                                    curCachedAdj = nextCachedAdj;
15407                                    nextCachedAdj += 2;
15408                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15409                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15410                                    }
15411                                }
15412                            }
15413                            break;
15414                        default:
15415                            // For everything else, assign next empty cached process
15416                            // level and bump that up.  Note that this means that
15417                            // long-running services that have dropped down to the
15418                            // cached level will be treated as empty (since their process
15419                            // state is still as a service), which is what we want.
15420                            app.curRawAdj = curEmptyAdj;
15421                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15422                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15423                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15424                                    + ")");
15425                            if (curEmptyAdj != nextEmptyAdj) {
15426                                stepEmpty++;
15427                                if (stepEmpty >= emptyFactor) {
15428                                    stepEmpty = 0;
15429                                    curEmptyAdj = nextEmptyAdj;
15430                                    nextEmptyAdj += 2;
15431                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15432                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15433                                    }
15434                                }
15435                            }
15436                            break;
15437                    }
15438                }
15439
15440                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15441
15442                // Count the number of process types.
15443                switch (app.curProcState) {
15444                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15445                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15446                        mNumCachedHiddenProcs++;
15447                        numCached++;
15448                        if (numCached > cachedProcessLimit) {
15449                            killUnneededProcessLocked(app, "cached #" + numCached);
15450                        }
15451                        break;
15452                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15453                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15454                                && app.lastActivityTime < oldTime) {
15455                            killUnneededProcessLocked(app, "empty for "
15456                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15457                                    / 1000) + "s");
15458                        } else {
15459                            numEmpty++;
15460                            if (numEmpty > emptyProcessLimit) {
15461                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15462                            }
15463                        }
15464                        break;
15465                    default:
15466                        mNumNonCachedProcs++;
15467                        break;
15468                }
15469
15470                if (app.isolated && app.services.size() <= 0) {
15471                    // If this is an isolated process, and there are no
15472                    // services running in it, then the process is no longer
15473                    // needed.  We agressively kill these because we can by
15474                    // definition not re-use the same process again, and it is
15475                    // good to avoid having whatever code was running in them
15476                    // left sitting around after no longer needed.
15477                    killUnneededProcessLocked(app, "isolated not needed");
15478                }
15479
15480                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15481                        && !app.killedByAm) {
15482                    numTrimming++;
15483                }
15484            }
15485        }
15486
15487        mNumServiceProcs = mNewNumServiceProcs;
15488
15489        // Now determine the memory trimming level of background processes.
15490        // Unfortunately we need to start at the back of the list to do this
15491        // properly.  We only do this if the number of background apps we
15492        // are managing to keep around is less than half the maximum we desire;
15493        // if we are keeping a good number around, we'll let them use whatever
15494        // memory they want.
15495        final int numCachedAndEmpty = numCached + numEmpty;
15496        int memFactor;
15497        if (numCached <= ProcessList.TRIM_CACHED_APPS
15498                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15499            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15500                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15501            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15502                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15503            } else {
15504                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15505            }
15506        } else {
15507            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15508        }
15509        // We always allow the memory level to go up (better).  We only allow it to go
15510        // down if we are in a state where that is allowed, *and* the total number of processes
15511        // has gone down since last time.
15512        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15513                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15514                + " last=" + mLastNumProcesses);
15515        if (memFactor > mLastMemoryLevel) {
15516            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15517                memFactor = mLastMemoryLevel;
15518                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15519            }
15520        }
15521        mLastMemoryLevel = memFactor;
15522        mLastNumProcesses = mLruProcesses.size();
15523        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15524        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15525        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15526            if (mLowRamStartTime == 0) {
15527                mLowRamStartTime = now;
15528            }
15529            int step = 0;
15530            int fgTrimLevel;
15531            switch (memFactor) {
15532                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15533                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15534                    break;
15535                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15536                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15537                    break;
15538                default:
15539                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15540                    break;
15541            }
15542            int factor = numTrimming/3;
15543            int minFactor = 2;
15544            if (mHomeProcess != null) minFactor++;
15545            if (mPreviousProcess != null) minFactor++;
15546            if (factor < minFactor) factor = minFactor;
15547            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15548            for (int i=N-1; i>=0; i--) {
15549                ProcessRecord app = mLruProcesses.get(i);
15550                if (allChanged || app.procStateChanged) {
15551                    setProcessTrackerState(app, trackerMemFactor, now);
15552                    app.procStateChanged = false;
15553                }
15554                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15555                        && !app.killedByAm) {
15556                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15557                        try {
15558                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15559                                    "Trimming memory of " + app.processName
15560                                    + " to " + curLevel);
15561                            app.thread.scheduleTrimMemory(curLevel);
15562                        } catch (RemoteException e) {
15563                        }
15564                        if (false) {
15565                            // For now we won't do this; our memory trimming seems
15566                            // to be good enough at this point that destroying
15567                            // activities causes more harm than good.
15568                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15569                                    && app != mHomeProcess && app != mPreviousProcess) {
15570                                // Need to do this on its own message because the stack may not
15571                                // be in a consistent state at this point.
15572                                // For these apps we will also finish their activities
15573                                // to help them free memory.
15574                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15575                            }
15576                        }
15577                    }
15578                    app.trimMemoryLevel = curLevel;
15579                    step++;
15580                    if (step >= factor) {
15581                        step = 0;
15582                        switch (curLevel) {
15583                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15584                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15585                                break;
15586                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15587                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15588                                break;
15589                        }
15590                    }
15591                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15592                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15593                            && app.thread != null) {
15594                        try {
15595                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15596                                    "Trimming memory of heavy-weight " + app.processName
15597                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15598                            app.thread.scheduleTrimMemory(
15599                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15600                        } catch (RemoteException e) {
15601                        }
15602                    }
15603                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15604                } else {
15605                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15606                            || app.systemNoUi) && app.pendingUiClean) {
15607                        // If this application is now in the background and it
15608                        // had done UI, then give it the special trim level to
15609                        // have it free UI resources.
15610                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15611                        if (app.trimMemoryLevel < level && app.thread != null) {
15612                            try {
15613                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15614                                        "Trimming memory of bg-ui " + app.processName
15615                                        + " to " + level);
15616                                app.thread.scheduleTrimMemory(level);
15617                            } catch (RemoteException e) {
15618                            }
15619                        }
15620                        app.pendingUiClean = false;
15621                    }
15622                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15623                        try {
15624                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15625                                    "Trimming memory of fg " + app.processName
15626                                    + " to " + fgTrimLevel);
15627                            app.thread.scheduleTrimMemory(fgTrimLevel);
15628                        } catch (RemoteException e) {
15629                        }
15630                    }
15631                    app.trimMemoryLevel = fgTrimLevel;
15632                }
15633            }
15634        } else {
15635            if (mLowRamStartTime != 0) {
15636                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15637                mLowRamStartTime = 0;
15638            }
15639            for (int i=N-1; i>=0; i--) {
15640                ProcessRecord app = mLruProcesses.get(i);
15641                if (allChanged || app.procStateChanged) {
15642                    setProcessTrackerState(app, trackerMemFactor, now);
15643                    app.procStateChanged = false;
15644                }
15645                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15646                        || app.systemNoUi) && app.pendingUiClean) {
15647                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15648                            && app.thread != null) {
15649                        try {
15650                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15651                                    "Trimming memory of ui hidden " + app.processName
15652                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15653                            app.thread.scheduleTrimMemory(
15654                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15655                        } catch (RemoteException e) {
15656                        }
15657                    }
15658                    app.pendingUiClean = false;
15659                }
15660                app.trimMemoryLevel = 0;
15661            }
15662        }
15663
15664        if (mAlwaysFinishActivities) {
15665            // Need to do this on its own message because the stack may not
15666            // be in a consistent state at this point.
15667            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15668        }
15669
15670        if (allChanged) {
15671            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15672        }
15673
15674        if (mProcessStats.shouldWriteNowLocked(now)) {
15675            mHandler.post(new Runnable() {
15676                @Override public void run() {
15677                    synchronized (ActivityManagerService.this) {
15678                        mProcessStats.writeStateAsyncLocked();
15679                    }
15680                }
15681            });
15682        }
15683
15684        if (DEBUG_OOM_ADJ) {
15685            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15686        }
15687    }
15688
15689    final void trimApplications() {
15690        synchronized (this) {
15691            int i;
15692
15693            // First remove any unused application processes whose package
15694            // has been removed.
15695            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15696                final ProcessRecord app = mRemovedProcesses.get(i);
15697                if (app.activities.size() == 0
15698                        && app.curReceiver == null && app.services.size() == 0) {
15699                    Slog.i(
15700                        TAG, "Exiting empty application process "
15701                        + app.processName + " ("
15702                        + (app.thread != null ? app.thread.asBinder() : null)
15703                        + ")\n");
15704                    if (app.pid > 0 && app.pid != MY_PID) {
15705                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15706                                app.processName, app.setAdj, "empty");
15707                        app.killedByAm = true;
15708                        Process.killProcessQuiet(app.pid);
15709                    } else {
15710                        try {
15711                            app.thread.scheduleExit();
15712                        } catch (Exception e) {
15713                            // Ignore exceptions.
15714                        }
15715                    }
15716                    cleanUpApplicationRecordLocked(app, false, true, -1);
15717                    mRemovedProcesses.remove(i);
15718
15719                    if (app.persistent) {
15720                        if (app.persistent) {
15721                            addAppLocked(app.info, false);
15722                        }
15723                    }
15724                }
15725            }
15726
15727            // Now update the oom adj for all processes.
15728            updateOomAdjLocked();
15729        }
15730    }
15731
15732    /** This method sends the specified signal to each of the persistent apps */
15733    public void signalPersistentProcesses(int sig) throws RemoteException {
15734        if (sig != Process.SIGNAL_USR1) {
15735            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15736        }
15737
15738        synchronized (this) {
15739            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15740                    != PackageManager.PERMISSION_GRANTED) {
15741                throw new SecurityException("Requires permission "
15742                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15743            }
15744
15745            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15746                ProcessRecord r = mLruProcesses.get(i);
15747                if (r.thread != null && r.persistent) {
15748                    Process.sendSignal(r.pid, sig);
15749                }
15750            }
15751        }
15752    }
15753
15754    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15755        if (proc == null || proc == mProfileProc) {
15756            proc = mProfileProc;
15757            path = mProfileFile;
15758            profileType = mProfileType;
15759            clearProfilerLocked();
15760        }
15761        if (proc == null) {
15762            return;
15763        }
15764        try {
15765            proc.thread.profilerControl(false, path, null, profileType);
15766        } catch (RemoteException e) {
15767            throw new IllegalStateException("Process disappeared");
15768        }
15769    }
15770
15771    private void clearProfilerLocked() {
15772        if (mProfileFd != null) {
15773            try {
15774                mProfileFd.close();
15775            } catch (IOException e) {
15776            }
15777        }
15778        mProfileApp = null;
15779        mProfileProc = null;
15780        mProfileFile = null;
15781        mProfileType = 0;
15782        mAutoStopProfiler = false;
15783    }
15784
15785    public boolean profileControl(String process, int userId, boolean start,
15786            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15787
15788        try {
15789            synchronized (this) {
15790                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15791                // its own permission.
15792                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15793                        != PackageManager.PERMISSION_GRANTED) {
15794                    throw new SecurityException("Requires permission "
15795                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15796                }
15797
15798                if (start && fd == null) {
15799                    throw new IllegalArgumentException("null fd");
15800                }
15801
15802                ProcessRecord proc = null;
15803                if (process != null) {
15804                    proc = findProcessLocked(process, userId, "profileControl");
15805                }
15806
15807                if (start && (proc == null || proc.thread == null)) {
15808                    throw new IllegalArgumentException("Unknown process: " + process);
15809                }
15810
15811                if (start) {
15812                    stopProfilerLocked(null, null, 0);
15813                    setProfileApp(proc.info, proc.processName, path, fd, false);
15814                    mProfileProc = proc;
15815                    mProfileType = profileType;
15816                    try {
15817                        fd = fd.dup();
15818                    } catch (IOException e) {
15819                        fd = null;
15820                    }
15821                    proc.thread.profilerControl(start, path, fd, profileType);
15822                    fd = null;
15823                    mProfileFd = null;
15824                } else {
15825                    stopProfilerLocked(proc, path, profileType);
15826                    if (fd != null) {
15827                        try {
15828                            fd.close();
15829                        } catch (IOException e) {
15830                        }
15831                    }
15832                }
15833
15834                return true;
15835            }
15836        } catch (RemoteException e) {
15837            throw new IllegalStateException("Process disappeared");
15838        } finally {
15839            if (fd != null) {
15840                try {
15841                    fd.close();
15842                } catch (IOException e) {
15843                }
15844            }
15845        }
15846    }
15847
15848    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15849        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15850                userId, true, true, callName, null);
15851        ProcessRecord proc = null;
15852        try {
15853            int pid = Integer.parseInt(process);
15854            synchronized (mPidsSelfLocked) {
15855                proc = mPidsSelfLocked.get(pid);
15856            }
15857        } catch (NumberFormatException e) {
15858        }
15859
15860        if (proc == null) {
15861            ArrayMap<String, SparseArray<ProcessRecord>> all
15862                    = mProcessNames.getMap();
15863            SparseArray<ProcessRecord> procs = all.get(process);
15864            if (procs != null && procs.size() > 0) {
15865                proc = procs.valueAt(0);
15866                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15867                    for (int i=1; i<procs.size(); i++) {
15868                        ProcessRecord thisProc = procs.valueAt(i);
15869                        if (thisProc.userId == userId) {
15870                            proc = thisProc;
15871                            break;
15872                        }
15873                    }
15874                }
15875            }
15876        }
15877
15878        return proc;
15879    }
15880
15881    public boolean dumpHeap(String process, int userId, boolean managed,
15882            String path, ParcelFileDescriptor fd) throws RemoteException {
15883
15884        try {
15885            synchronized (this) {
15886                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15887                // its own permission (same as profileControl).
15888                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15889                        != PackageManager.PERMISSION_GRANTED) {
15890                    throw new SecurityException("Requires permission "
15891                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15892                }
15893
15894                if (fd == null) {
15895                    throw new IllegalArgumentException("null fd");
15896                }
15897
15898                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15899                if (proc == null || proc.thread == null) {
15900                    throw new IllegalArgumentException("Unknown process: " + process);
15901                }
15902
15903                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15904                if (!isDebuggable) {
15905                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15906                        throw new SecurityException("Process not debuggable: " + proc);
15907                    }
15908                }
15909
15910                proc.thread.dumpHeap(managed, path, fd);
15911                fd = null;
15912                return true;
15913            }
15914        } catch (RemoteException e) {
15915            throw new IllegalStateException("Process disappeared");
15916        } finally {
15917            if (fd != null) {
15918                try {
15919                    fd.close();
15920                } catch (IOException e) {
15921                }
15922            }
15923        }
15924    }
15925
15926    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15927    public void monitor() {
15928        synchronized (this) { }
15929    }
15930
15931    void onCoreSettingsChange(Bundle settings) {
15932        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15933            ProcessRecord processRecord = mLruProcesses.get(i);
15934            try {
15935                if (processRecord.thread != null) {
15936                    processRecord.thread.setCoreSettings(settings);
15937                }
15938            } catch (RemoteException re) {
15939                /* ignore */
15940            }
15941        }
15942    }
15943
15944    // Multi-user methods
15945
15946    @Override
15947    public boolean switchUser(final int userId) {
15948        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15949                != PackageManager.PERMISSION_GRANTED) {
15950            String msg = "Permission Denial: switchUser() from pid="
15951                    + Binder.getCallingPid()
15952                    + ", uid=" + Binder.getCallingUid()
15953                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15954            Slog.w(TAG, msg);
15955            throw new SecurityException(msg);
15956        }
15957
15958        final long ident = Binder.clearCallingIdentity();
15959        try {
15960            synchronized (this) {
15961                final int oldUserId = mCurrentUserId;
15962                if (oldUserId == userId) {
15963                    return true;
15964                }
15965
15966                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15967                if (userInfo == null) {
15968                    Slog.w(TAG, "No user info for user #" + userId);
15969                    return false;
15970                }
15971
15972                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15973                        R.anim.screen_user_enter);
15974
15975                boolean needStart = false;
15976
15977                // If the user we are switching to is not currently started, then
15978                // we need to start it now.
15979                if (mStartedUsers.get(userId) == null) {
15980                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
15981                    updateStartedUserArrayLocked();
15982                    needStart = true;
15983                }
15984
15985                mCurrentUserId = userId;
15986                final Integer userIdInt = Integer.valueOf(userId);
15987                mUserLru.remove(userIdInt);
15988                mUserLru.add(userIdInt);
15989
15990                mWindowManager.setCurrentUser(userId);
15991
15992                // Once the internal notion of the active user has switched, we lock the device
15993                // with the option to show the user switcher on the keyguard.
15994                mWindowManager.lockNow(null);
15995
15996                final UserStartedState uss = mStartedUsers.get(userId);
15997
15998                // Make sure user is in the started state.  If it is currently
15999                // stopping, we need to knock that off.
16000                if (uss.mState == UserStartedState.STATE_STOPPING) {
16001                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16002                    // so we can just fairly silently bring the user back from
16003                    // the almost-dead.
16004                    uss.mState = UserStartedState.STATE_RUNNING;
16005                    updateStartedUserArrayLocked();
16006                    needStart = true;
16007                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16008                    // This means ACTION_SHUTDOWN has been sent, so we will
16009                    // need to treat this as a new boot of the user.
16010                    uss.mState = UserStartedState.STATE_BOOTING;
16011                    updateStartedUserArrayLocked();
16012                    needStart = true;
16013                }
16014
16015                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16016                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16017                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16018                        oldUserId, userId, uss));
16019                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16020                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16021                if (needStart) {
16022                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16023                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16024                            | Intent.FLAG_RECEIVER_FOREGROUND);
16025                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16026                    broadcastIntentLocked(null, null, intent,
16027                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16028                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16029                }
16030
16031                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16032                    if (userId != 0) {
16033                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16034                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16035                        broadcastIntentLocked(null, null, intent, null,
16036                                new IIntentReceiver.Stub() {
16037                                    public void performReceive(Intent intent, int resultCode,
16038                                            String data, Bundle extras, boolean ordered,
16039                                            boolean sticky, int sendingUser) {
16040                                        userInitialized(uss, userId);
16041                                    }
16042                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16043                                true, false, MY_PID, Process.SYSTEM_UID,
16044                                userId);
16045                        uss.initializing = true;
16046                    } else {
16047                        getUserManagerLocked().makeInitialized(userInfo.id);
16048                    }
16049                }
16050
16051                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16052                if (homeInFront) {
16053                    startHomeActivityLocked(userId);
16054                } else {
16055                    mStackSupervisor.resumeTopActivitiesLocked();
16056                }
16057
16058                EventLogTags.writeAmSwitchUser(userId);
16059                getUserManagerLocked().userForeground(userId);
16060                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16061                if (needStart) {
16062                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16063                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16064                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16065                    broadcastIntentLocked(null, null, intent,
16066                            null, new IIntentReceiver.Stub() {
16067                                @Override
16068                                public void performReceive(Intent intent, int resultCode, String data,
16069                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16070                                        throws RemoteException {
16071                                }
16072                            }, 0, null, null,
16073                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16074                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16075                }
16076            }
16077        } finally {
16078            Binder.restoreCallingIdentity(ident);
16079        }
16080
16081        return true;
16082    }
16083
16084    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16085        long ident = Binder.clearCallingIdentity();
16086        try {
16087            Intent intent;
16088            if (oldUserId >= 0) {
16089                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16090                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16091                        | Intent.FLAG_RECEIVER_FOREGROUND);
16092                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16093                broadcastIntentLocked(null, null, intent,
16094                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16095                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16096            }
16097            if (newUserId >= 0) {
16098                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16099                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16100                        | Intent.FLAG_RECEIVER_FOREGROUND);
16101                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16102                broadcastIntentLocked(null, null, intent,
16103                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16104                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16105                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16106                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16107                        | Intent.FLAG_RECEIVER_FOREGROUND);
16108                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16109                broadcastIntentLocked(null, null, intent,
16110                        null, null, 0, null, null,
16111                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16112                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16113            }
16114        } finally {
16115            Binder.restoreCallingIdentity(ident);
16116        }
16117    }
16118
16119    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16120            final int newUserId) {
16121        final int N = mUserSwitchObservers.beginBroadcast();
16122        if (N > 0) {
16123            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16124                int mCount = 0;
16125                @Override
16126                public void sendResult(Bundle data) throws RemoteException {
16127                    synchronized (ActivityManagerService.this) {
16128                        if (mCurUserSwitchCallback == this) {
16129                            mCount++;
16130                            if (mCount == N) {
16131                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16132                            }
16133                        }
16134                    }
16135                }
16136            };
16137            synchronized (this) {
16138                uss.switching = true;
16139                mCurUserSwitchCallback = callback;
16140            }
16141            for (int i=0; i<N; i++) {
16142                try {
16143                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16144                            newUserId, callback);
16145                } catch (RemoteException e) {
16146                }
16147            }
16148        } else {
16149            synchronized (this) {
16150                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16151            }
16152        }
16153        mUserSwitchObservers.finishBroadcast();
16154    }
16155
16156    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16157        synchronized (this) {
16158            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16159            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16160        }
16161    }
16162
16163    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16164        mCurUserSwitchCallback = null;
16165        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16166        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16167                oldUserId, newUserId, uss));
16168    }
16169
16170    void userInitialized(UserStartedState uss, int newUserId) {
16171        completeSwitchAndInitalize(uss, newUserId, true, false);
16172    }
16173
16174    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16175        completeSwitchAndInitalize(uss, newUserId, false, true);
16176    }
16177
16178    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16179            boolean clearInitializing, boolean clearSwitching) {
16180        boolean unfrozen = false;
16181        synchronized (this) {
16182            if (clearInitializing) {
16183                uss.initializing = false;
16184                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16185            }
16186            if (clearSwitching) {
16187                uss.switching = false;
16188            }
16189            if (!uss.switching && !uss.initializing) {
16190                mWindowManager.stopFreezingScreen();
16191                unfrozen = true;
16192            }
16193        }
16194        if (unfrozen) {
16195            final int N = mUserSwitchObservers.beginBroadcast();
16196            for (int i=0; i<N; i++) {
16197                try {
16198                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16199                } catch (RemoteException e) {
16200                }
16201            }
16202            mUserSwitchObservers.finishBroadcast();
16203        }
16204    }
16205
16206    void finishUserSwitch(UserStartedState uss) {
16207        synchronized (this) {
16208            if (uss.mState == UserStartedState.STATE_BOOTING
16209                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16210                uss.mState = UserStartedState.STATE_RUNNING;
16211                final int userId = uss.mHandle.getIdentifier();
16212                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16213                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16214                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16215                broadcastIntentLocked(null, null, intent,
16216                        null, null, 0, null, null,
16217                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16218                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16219            }
16220            int num = mUserLru.size();
16221            int i = 0;
16222            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16223                Integer oldUserId = mUserLru.get(i);
16224                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16225                if (oldUss == null) {
16226                    // Shouldn't happen, but be sane if it does.
16227                    mUserLru.remove(i);
16228                    num--;
16229                    continue;
16230                }
16231                if (oldUss.mState == UserStartedState.STATE_STOPPING
16232                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16233                    // This user is already stopping, doesn't count.
16234                    num--;
16235                    i++;
16236                    continue;
16237                }
16238                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16239                    // Owner and current can't be stopped, but count as running.
16240                    i++;
16241                    continue;
16242                }
16243                // This is a user to be stopped.
16244                stopUserLocked(oldUserId, null);
16245                num--;
16246                i++;
16247            }
16248        }
16249    }
16250
16251    @Override
16252    public int stopUser(final int userId, final IStopUserCallback callback) {
16253        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16254                != PackageManager.PERMISSION_GRANTED) {
16255            String msg = "Permission Denial: switchUser() from pid="
16256                    + Binder.getCallingPid()
16257                    + ", uid=" + Binder.getCallingUid()
16258                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16259            Slog.w(TAG, msg);
16260            throw new SecurityException(msg);
16261        }
16262        if (userId <= 0) {
16263            throw new IllegalArgumentException("Can't stop primary user " + userId);
16264        }
16265        synchronized (this) {
16266            return stopUserLocked(userId, callback);
16267        }
16268    }
16269
16270    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16271        if (mCurrentUserId == userId) {
16272            return ActivityManager.USER_OP_IS_CURRENT;
16273        }
16274
16275        final UserStartedState uss = mStartedUsers.get(userId);
16276        if (uss == null) {
16277            // User is not started, nothing to do...  but we do need to
16278            // callback if requested.
16279            if (callback != null) {
16280                mHandler.post(new Runnable() {
16281                    @Override
16282                    public void run() {
16283                        try {
16284                            callback.userStopped(userId);
16285                        } catch (RemoteException e) {
16286                        }
16287                    }
16288                });
16289            }
16290            return ActivityManager.USER_OP_SUCCESS;
16291        }
16292
16293        if (callback != null) {
16294            uss.mStopCallbacks.add(callback);
16295        }
16296
16297        if (uss.mState != UserStartedState.STATE_STOPPING
16298                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16299            uss.mState = UserStartedState.STATE_STOPPING;
16300            updateStartedUserArrayLocked();
16301
16302            long ident = Binder.clearCallingIdentity();
16303            try {
16304                // We are going to broadcast ACTION_USER_STOPPING and then
16305                // once that is done send a final ACTION_SHUTDOWN and then
16306                // stop the user.
16307                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16308                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16309                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16310                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16311                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16312                // This is the result receiver for the final shutdown broadcast.
16313                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16314                    @Override
16315                    public void performReceive(Intent intent, int resultCode, String data,
16316                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16317                        finishUserStop(uss);
16318                    }
16319                };
16320                // This is the result receiver for the initial stopping broadcast.
16321                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16322                    @Override
16323                    public void performReceive(Intent intent, int resultCode, String data,
16324                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16325                        // On to the next.
16326                        synchronized (ActivityManagerService.this) {
16327                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16328                                // Whoops, we are being started back up.  Abort, abort!
16329                                return;
16330                            }
16331                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16332                        }
16333                        broadcastIntentLocked(null, null, shutdownIntent,
16334                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16335                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16336                    }
16337                };
16338                // Kick things off.
16339                broadcastIntentLocked(null, null, stoppingIntent,
16340                        null, stoppingReceiver, 0, null, null,
16341                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16342                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16343            } finally {
16344                Binder.restoreCallingIdentity(ident);
16345            }
16346        }
16347
16348        return ActivityManager.USER_OP_SUCCESS;
16349    }
16350
16351    void finishUserStop(UserStartedState uss) {
16352        final int userId = uss.mHandle.getIdentifier();
16353        boolean stopped;
16354        ArrayList<IStopUserCallback> callbacks;
16355        synchronized (this) {
16356            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16357            if (mStartedUsers.get(userId) != uss) {
16358                stopped = false;
16359            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16360                stopped = false;
16361            } else {
16362                stopped = true;
16363                // User can no longer run.
16364                mStartedUsers.remove(userId);
16365                mUserLru.remove(Integer.valueOf(userId));
16366                updateStartedUserArrayLocked();
16367
16368                // Clean up all state and processes associated with the user.
16369                // Kill all the processes for the user.
16370                forceStopUserLocked(userId, "finish user");
16371            }
16372        }
16373
16374        for (int i=0; i<callbacks.size(); i++) {
16375            try {
16376                if (stopped) callbacks.get(i).userStopped(userId);
16377                else callbacks.get(i).userStopAborted(userId);
16378            } catch (RemoteException e) {
16379            }
16380        }
16381
16382        mStackSupervisor.removeUserLocked(userId);
16383    }
16384
16385    @Override
16386    public UserInfo getCurrentUser() {
16387        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16388                != PackageManager.PERMISSION_GRANTED) && (
16389                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16390                != PackageManager.PERMISSION_GRANTED)) {
16391            String msg = "Permission Denial: getCurrentUser() from pid="
16392                    + Binder.getCallingPid()
16393                    + ", uid=" + Binder.getCallingUid()
16394                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16395            Slog.w(TAG, msg);
16396            throw new SecurityException(msg);
16397        }
16398        synchronized (this) {
16399            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16400        }
16401    }
16402
16403    int getCurrentUserIdLocked() {
16404        return mCurrentUserId;
16405    }
16406
16407    @Override
16408    public boolean isUserRunning(int userId, boolean orStopped) {
16409        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16410                != PackageManager.PERMISSION_GRANTED) {
16411            String msg = "Permission Denial: isUserRunning() from pid="
16412                    + Binder.getCallingPid()
16413                    + ", uid=" + Binder.getCallingUid()
16414                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16415            Slog.w(TAG, msg);
16416            throw new SecurityException(msg);
16417        }
16418        synchronized (this) {
16419            return isUserRunningLocked(userId, orStopped);
16420        }
16421    }
16422
16423    boolean isUserRunningLocked(int userId, boolean orStopped) {
16424        UserStartedState state = mStartedUsers.get(userId);
16425        if (state == null) {
16426            return false;
16427        }
16428        if (orStopped) {
16429            return true;
16430        }
16431        return state.mState != UserStartedState.STATE_STOPPING
16432                && state.mState != UserStartedState.STATE_SHUTDOWN;
16433    }
16434
16435    @Override
16436    public int[] getRunningUserIds() {
16437        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16438                != PackageManager.PERMISSION_GRANTED) {
16439            String msg = "Permission Denial: isUserRunning() from pid="
16440                    + Binder.getCallingPid()
16441                    + ", uid=" + Binder.getCallingUid()
16442                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16443            Slog.w(TAG, msg);
16444            throw new SecurityException(msg);
16445        }
16446        synchronized (this) {
16447            return mStartedUserArray;
16448        }
16449    }
16450
16451    private void updateStartedUserArrayLocked() {
16452        int num = 0;
16453        for (int i=0; i<mStartedUsers.size();  i++) {
16454            UserStartedState uss = mStartedUsers.valueAt(i);
16455            // This list does not include stopping users.
16456            if (uss.mState != UserStartedState.STATE_STOPPING
16457                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16458                num++;
16459            }
16460        }
16461        mStartedUserArray = new int[num];
16462        num = 0;
16463        for (int i=0; i<mStartedUsers.size();  i++) {
16464            UserStartedState uss = mStartedUsers.valueAt(i);
16465            if (uss.mState != UserStartedState.STATE_STOPPING
16466                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16467                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16468                num++;
16469            }
16470        }
16471    }
16472
16473    @Override
16474    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16475        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16476                != PackageManager.PERMISSION_GRANTED) {
16477            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16478                    + Binder.getCallingPid()
16479                    + ", uid=" + Binder.getCallingUid()
16480                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16481            Slog.w(TAG, msg);
16482            throw new SecurityException(msg);
16483        }
16484
16485        mUserSwitchObservers.register(observer);
16486    }
16487
16488    @Override
16489    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16490        mUserSwitchObservers.unregister(observer);
16491    }
16492
16493    private boolean userExists(int userId) {
16494        if (userId == 0) {
16495            return true;
16496        }
16497        UserManagerService ums = getUserManagerLocked();
16498        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16499    }
16500
16501    int[] getUsersLocked() {
16502        UserManagerService ums = getUserManagerLocked();
16503        return ums != null ? ums.getUserIds() : new int[] { 0 };
16504    }
16505
16506    UserManagerService getUserManagerLocked() {
16507        if (mUserManager == null) {
16508            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16509            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16510        }
16511        return mUserManager;
16512    }
16513
16514    private int applyUserId(int uid, int userId) {
16515        return UserHandle.getUid(userId, uid);
16516    }
16517
16518    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16519        if (info == null) return null;
16520        ApplicationInfo newInfo = new ApplicationInfo(info);
16521        newInfo.uid = applyUserId(info.uid, userId);
16522        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16523                + info.packageName;
16524        return newInfo;
16525    }
16526
16527    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16528        if (aInfo == null
16529                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16530            return aInfo;
16531        }
16532
16533        ActivityInfo info = new ActivityInfo(aInfo);
16534        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16535        return info;
16536    }
16537
16538    private final class LocalService extends ActivityManagerInternal {
16539        @Override
16540        public void goingToSleep() {
16541            ActivityManagerService.this.goingToSleep();
16542        }
16543
16544        @Override
16545        public void wakingUp() {
16546            ActivityManagerService.this.wakingUp();
16547        }
16548    }
16549}
16550