ActivityManagerService.java revision 6143a02f96a5c6c7a0a84f5dbe70732998256a72
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27
28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
29
30import android.app.AppOpsManager;
31import android.app.IActivityContainer;
32import android.app.IActivityContainerCallback;
33import android.appwidget.AppWidgetManager;
34import android.graphics.Rect;
35import android.os.BatteryStats;
36import android.util.ArrayMap;
37import com.android.internal.R;
38import com.android.internal.annotations.GuardedBy;
39import com.android.internal.app.IAppOpsService;
40import com.android.internal.app.ProcessMap;
41import com.android.internal.app.ProcessStats;
42import com.android.internal.os.BackgroundThread;
43import com.android.internal.os.BatteryStatsImpl;
44import com.android.internal.os.ProcessCpuTracker;
45import com.android.internal.os.TransferPipe;
46import com.android.internal.util.FastPrintWriter;
47import com.android.internal.util.FastXmlSerializer;
48import com.android.internal.util.MemInfoReader;
49import com.android.internal.util.Preconditions;
50import com.android.server.AppOpsService;
51import com.android.server.AttributeCache;
52import com.android.server.IntentResolver;
53import com.android.server.ServiceThread;
54import com.android.server.SystemService;
55import com.android.server.Watchdog;
56import com.android.server.am.ActivityStack.ActivityState;
57import com.android.server.firewall.IntentFirewall;
58import com.android.server.pm.UserManagerService;
59import com.android.server.wm.AppTransition;
60import com.android.server.wm.WindowManagerService;
61import com.google.android.collect.Lists;
62import com.google.android.collect.Maps;
63
64import dalvik.system.Zygote;
65
66import libcore.io.IoUtils;
67
68import org.xmlpull.v1.XmlPullParser;
69import org.xmlpull.v1.XmlPullParserException;
70import org.xmlpull.v1.XmlSerializer;
71
72import android.app.Activity;
73import android.app.ActivityManager;
74import android.app.ActivityManager.RunningTaskInfo;
75import android.app.ActivityManager.StackInfo;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.ApplicationErrorReport;
82import android.app.Dialog;
83import android.app.IActivityController;
84import android.app.IApplicationThread;
85import android.app.IInstrumentationWatcher;
86import android.app.INotificationManager;
87import android.app.IProcessObserver;
88import android.app.IServiceConnection;
89import android.app.IStopUserCallback;
90import android.app.IThumbnailReceiver;
91import android.app.IUiAutomationConnection;
92import android.app.IUserSwitchObserver;
93import android.app.Instrumentation;
94import android.app.Notification;
95import android.app.NotificationManager;
96import android.app.PendingIntent;
97import android.app.backup.IBackupManager;
98import android.content.ActivityNotFoundException;
99import android.content.BroadcastReceiver;
100import android.content.ClipData;
101import android.content.ComponentCallbacks2;
102import android.content.ComponentName;
103import android.content.ContentProvider;
104import android.content.ContentResolver;
105import android.content.Context;
106import android.content.DialogInterface;
107import android.content.IContentProvider;
108import android.content.IIntentReceiver;
109import android.content.IIntentSender;
110import android.content.Intent;
111import android.content.IntentFilter;
112import android.content.IntentSender;
113import android.content.pm.ActivityInfo;
114import android.content.pm.ApplicationInfo;
115import android.content.pm.ConfigurationInfo;
116import android.content.pm.IPackageDataObserver;
117import android.content.pm.IPackageManager;
118import android.content.pm.InstrumentationInfo;
119import android.content.pm.PackageInfo;
120import android.content.pm.PackageManager;
121import android.content.pm.ParceledListSlice;
122import android.content.pm.UserInfo;
123import android.content.pm.PackageManager.NameNotFoundException;
124import android.content.pm.PathPermission;
125import android.content.pm.ProviderInfo;
126import android.content.pm.ResolveInfo;
127import android.content.pm.ServiceInfo;
128import android.content.res.CompatibilityInfo;
129import android.content.res.Configuration;
130import android.graphics.Bitmap;
131import android.net.Proxy;
132import android.net.ProxyProperties;
133import android.net.Uri;
134import android.os.Binder;
135import android.os.Build;
136import android.os.Bundle;
137import android.os.Debug;
138import android.os.DropBoxManager;
139import android.os.Environment;
140import android.os.FactoryTest;
141import android.os.FileObserver;
142import android.os.FileUtils;
143import android.os.Handler;
144import android.os.IBinder;
145import android.os.IPermissionController;
146import android.os.IRemoteCallback;
147import android.os.IUserManager;
148import android.os.Looper;
149import android.os.Message;
150import android.os.Parcel;
151import android.os.ParcelFileDescriptor;
152import android.os.Process;
153import android.os.RemoteCallbackList;
154import android.os.RemoteException;
155import android.os.SELinux;
156import android.os.ServiceManager;
157import android.os.StrictMode;
158import android.os.SystemClock;
159import android.os.SystemProperties;
160import android.os.UpdateLock;
161import android.os.UserHandle;
162import android.provider.Settings;
163import android.text.format.DateUtils;
164import android.text.format.Time;
165import android.util.AtomicFile;
166import android.util.EventLog;
167import android.util.Log;
168import android.util.Pair;
169import android.util.PrintWriterPrinter;
170import android.util.Slog;
171import android.util.SparseArray;
172import android.util.TimeUtils;
173import android.util.Xml;
174import android.view.Gravity;
175import android.view.LayoutInflater;
176import android.view.View;
177import android.view.WindowManager;
178
179import java.io.BufferedInputStream;
180import java.io.BufferedOutputStream;
181import java.io.DataInputStream;
182import java.io.DataOutputStream;
183import java.io.File;
184import java.io.FileDescriptor;
185import java.io.FileInputStream;
186import java.io.FileNotFoundException;
187import java.io.FileOutputStream;
188import java.io.IOException;
189import java.io.InputStreamReader;
190import java.io.PrintWriter;
191import java.io.StringWriter;
192import java.lang.ref.WeakReference;
193import java.util.ArrayList;
194import java.util.Arrays;
195import java.util.Collections;
196import java.util.Comparator;
197import java.util.HashMap;
198import java.util.HashSet;
199import java.util.Iterator;
200import java.util.List;
201import java.util.Locale;
202import java.util.Map;
203import java.util.Set;
204import java.util.concurrent.atomic.AtomicBoolean;
205import java.util.concurrent.atomic.AtomicLong;
206
207public final class ActivityManagerService extends ActivityManagerNative
208        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
209    private static final String USER_DATA_DIR = "/data/user/";
210    static final String TAG = "ActivityManager";
211    static final String TAG_MU = "ActivityManagerServiceMU";
212    static final boolean DEBUG = false;
213    static final boolean localLOGV = DEBUG;
214    static final boolean DEBUG_BACKUP = localLOGV || false;
215    static final boolean DEBUG_BROADCAST = localLOGV || false;
216    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_CLEANUP = localLOGV || false;
219    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
220    static final boolean DEBUG_FOCUS = false;
221    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
222    static final boolean DEBUG_MU = localLOGV || false;
223    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
224    static final boolean DEBUG_LRU = localLOGV || false;
225    static final boolean DEBUG_PAUSE = localLOGV || false;
226    static final boolean DEBUG_POWER = localLOGV || false;
227    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
228    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
229    static final boolean DEBUG_PROCESSES = localLOGV || false;
230    static final boolean DEBUG_PROVIDER = localLOGV || false;
231    static final boolean DEBUG_RESULTS = localLOGV || false;
232    static final boolean DEBUG_SERVICE = localLOGV || false;
233    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
234    static final boolean DEBUG_STACK = localLOGV || false;
235    static final boolean DEBUG_SWITCH = localLOGV || false;
236    static final boolean DEBUG_TASKS = localLOGV || false;
237    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
238    static final boolean DEBUG_TRANSITION = localLOGV || false;
239    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
240    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
241    static final boolean DEBUG_VISBILITY = localLOGV || false;
242    static final boolean DEBUG_PSS = localLOGV || false;
243    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
244    static final boolean VALIDATE_TOKENS = false;
245    static final boolean SHOW_ACTIVITY_START_TIME = true;
246
247    // Control over CPU and battery monitoring.
248    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
249    static final boolean MONITOR_CPU_USAGE = true;
250    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
251    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
252    static final boolean MONITOR_THREAD_CPU_USAGE = false;
253
254    // The flags that are set for all calls we make to the package manager.
255    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
256
257    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
258
259    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
260
261    // Maximum number of recent tasks that we can remember.
262    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
263
264    // Amount of time after a call to stopAppSwitches() during which we will
265    // prevent further untrusted switches from happening.
266    static final long APP_SWITCH_DELAY_TIME = 5*1000;
267
268    // How long we wait for a launched process to attach to the activity manager
269    // before we decide it's never going to come up for real.
270    static final int PROC_START_TIMEOUT = 10*1000;
271
272    // How long we wait for a launched process to attach to the activity manager
273    // before we decide it's never going to come up for real, when the process was
274    // started with a wrapper for instrumentation (such as Valgrind) because it
275    // could take much longer than usual.
276    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
277
278    // How long to wait after going idle before forcing apps to GC.
279    static final int GC_TIMEOUT = 5*1000;
280
281    // The minimum amount of time between successive GC requests for a process.
282    static final int GC_MIN_INTERVAL = 60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process.
285    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
286
287    // The minimum amount of time between successive PSS requests for a process
288    // when the request is due to the memory state being lowered.
289    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
290
291    // The rate at which we check for apps using excessive power -- 15 mins.
292    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
293
294    // The minimum sample duration we will allow before deciding we have
295    // enough data on wake locks to start killing things.
296    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
297
298    // The minimum sample duration we will allow before deciding we have
299    // enough data on CPU usage to start killing things.
300    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
301
302    // How long we allow a receiver to run before giving up on it.
303    static final int BROADCAST_FG_TIMEOUT = 10*1000;
304    static final int BROADCAST_BG_TIMEOUT = 60*1000;
305
306    // How long we wait until we timeout on key dispatching.
307    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
308
309    // How long we wait until we timeout on key dispatching during instrumentation.
310    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
311
312    // Amount of time we wait for observers to handle a user switch before
313    // giving up on them and unfreezing the screen.
314    static final int USER_SWITCH_TIMEOUT = 2*1000;
315
316    // Maximum number of users we allow to be running at a time.
317    static final int MAX_RUNNING_USERS = 3;
318
319    // How long to wait in getAssistContextExtras for the activity and foreground services
320    // to respond with the result.
321    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
322
323    // Maximum number of persisted Uri grants a package is allowed
324    static final int MAX_PERSISTED_URI_GRANTS = 128;
325
326    static final int MY_PID = Process.myPid();
327
328    static final String[] EMPTY_STRING_ARRAY = new String[0];
329
330    // How many bytes to write into the dropbox log before truncating
331    static final int DROPBOX_MAX_SIZE = 256 * 1024;
332
333    /** Run all ActivityStacks through this */
334    ActivityStackSupervisor mStackSupervisor;
335
336    public IntentFirewall mIntentFirewall;
337
338    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
339    // default actuion automatically.  Important for devices without direct input
340    // devices.
341    private boolean mShowDialogs = true;
342
343    /**
344     * Description of a request to start a new activity, which has been held
345     * due to app switches being disabled.
346     */
347    static class PendingActivityLaunch {
348        final ActivityRecord r;
349        final ActivityRecord sourceRecord;
350        final int startFlags;
351        final ActivityStack stack;
352
353        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
354                int _startFlags, ActivityStack _stack) {
355            r = _r;
356            sourceRecord = _sourceRecord;
357            startFlags = _startFlags;
358            stack = _stack;
359        }
360    }
361
362    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
363            = new ArrayList<PendingActivityLaunch>();
364
365    BroadcastQueue mFgBroadcastQueue;
366    BroadcastQueue mBgBroadcastQueue;
367    // Convenient for easy iteration over the queues. Foreground is first
368    // so that dispatch of foreground broadcasts gets precedence.
369    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
370
371    BroadcastQueue broadcastQueueForIntent(Intent intent) {
372        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
373        if (DEBUG_BACKGROUND_BROADCAST) {
374            Slog.i(TAG, "Broadcast intent " + intent + " on "
375                    + (isFg ? "foreground" : "background")
376                    + " queue");
377        }
378        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
379    }
380
381    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
382        for (BroadcastQueue queue : mBroadcastQueues) {
383            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
384            if (r != null) {
385                return r;
386            }
387        }
388        return null;
389    }
390
391    /**
392     * Activity we have told the window manager to have key focus.
393     */
394    ActivityRecord mFocusedActivity = null;
395
396    /**
397     * List of intents that were used to start the most recent tasks.
398     */
399    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
400
401    public class PendingAssistExtras extends Binder implements Runnable {
402        public final ActivityRecord activity;
403        public boolean haveResult = false;
404        public Bundle result = null;
405        public PendingAssistExtras(ActivityRecord _activity) {
406            activity = _activity;
407        }
408        @Override
409        public void run() {
410            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
411            synchronized (this) {
412                haveResult = true;
413                notifyAll();
414            }
415        }
416    }
417
418    final ArrayList<PendingAssistExtras> mPendingAssistExtras
419            = new ArrayList<PendingAssistExtras>();
420
421    /**
422     * Process management.
423     */
424    final ProcessList mProcessList = new ProcessList();
425
426    /**
427     * All of the applications we currently have running organized by name.
428     * The keys are strings of the application package name (as
429     * returned by the package manager), and the keys are ApplicationRecord
430     * objects.
431     */
432    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
433
434    /**
435     * Tracking long-term execution of processes to look for abuse and other
436     * bad app behavior.
437     */
438    final ProcessStatsService mProcessStats;
439
440    /**
441     * The currently running isolated processes.
442     */
443    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
444
445    /**
446     * Counter for assigning isolated process uids, to avoid frequently reusing the
447     * same ones.
448     */
449    int mNextIsolatedProcessUid = 0;
450
451    /**
452     * The currently running heavy-weight process, if any.
453     */
454    ProcessRecord mHeavyWeightProcess = null;
455
456    /**
457     * The last time that various processes have crashed.
458     */
459    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
460
461    /**
462     * Information about a process that is currently marked as bad.
463     */
464    static final class BadProcessInfo {
465        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
466            this.time = time;
467            this.shortMsg = shortMsg;
468            this.longMsg = longMsg;
469            this.stack = stack;
470        }
471
472        final long time;
473        final String shortMsg;
474        final String longMsg;
475        final String stack;
476    }
477
478    /**
479     * Set of applications that we consider to be bad, and will reject
480     * incoming broadcasts from (which the user has no control over).
481     * Processes are added to this set when they have crashed twice within
482     * a minimum amount of time; they are removed from it when they are
483     * later restarted (hopefully due to some user action).  The value is the
484     * time it was added to the list.
485     */
486    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
487
488    /**
489     * All of the processes we currently have running organized by pid.
490     * The keys are the pid running the application.
491     *
492     * <p>NOTE: This object is protected by its own lock, NOT the global
493     * activity manager lock!
494     */
495    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
496
497    /**
498     * All of the processes that have been forced to be foreground.  The key
499     * is the pid of the caller who requested it (we hold a death
500     * link on it).
501     */
502    abstract class ForegroundToken implements IBinder.DeathRecipient {
503        int pid;
504        IBinder token;
505    }
506    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
507
508    /**
509     * List of records for processes that someone had tried to start before the
510     * system was ready.  We don't start them at that point, but ensure they
511     * are started by the time booting is complete.
512     */
513    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
514
515    /**
516     * List of persistent applications that are in the process
517     * of being started.
518     */
519    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
520
521    /**
522     * Processes that are being forcibly torn down.
523     */
524    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of running applications, sorted by recent usage.
528     * The first entry in the list is the least recently used.
529     */
530    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Where in mLruProcesses that the processes hosting activities start.
534     */
535    int mLruProcessActivityStart = 0;
536
537    /**
538     * Where in mLruProcesses that the processes hosting services start.
539     * This is after (lower index) than mLruProcessesActivityStart.
540     */
541    int mLruProcessServiceStart = 0;
542
543    /**
544     * List of processes that should gc as soon as things are idle.
545     */
546    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
547
548    /**
549     * Processes we want to collect PSS data from.
550     */
551    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Last time we requested PSS data of all processes.
555     */
556    long mLastFullPssTime = SystemClock.uptimeMillis();
557
558    /**
559     * This is the process holding what we currently consider to be
560     * the "home" activity.
561     */
562    ProcessRecord mHomeProcess;
563
564    /**
565     * This is the process holding the activity the user last visited that
566     * is in a different process from the one they are currently in.
567     */
568    ProcessRecord mPreviousProcess;
569
570    /**
571     * The time at which the previous process was last visible.
572     */
573    long mPreviousProcessVisibleTime;
574
575    /**
576     * Which uses have been started, so are allowed to run code.
577     */
578    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
579
580    /**
581     * LRU list of history of current users.  Most recently current is at the end.
582     */
583    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
584
585    /**
586     * Constant array of the users that are currently started.
587     */
588    int[] mStartedUserArray = new int[] { 0 };
589
590    /**
591     * Registered observers of the user switching mechanics.
592     */
593    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
594            = new RemoteCallbackList<IUserSwitchObserver>();
595
596    /**
597     * Currently active user switch.
598     */
599    Object mCurUserSwitchCallback;
600
601    /**
602     * Packages that the user has asked to have run in screen size
603     * compatibility mode instead of filling the screen.
604     */
605    final CompatModePackages mCompatModePackages;
606
607    /**
608     * Set of IntentSenderRecord objects that are currently active.
609     */
610    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
611            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
612
613    /**
614     * Fingerprints (hashCode()) of stack traces that we've
615     * already logged DropBox entries for.  Guarded by itself.  If
616     * something (rogue user app) forces this over
617     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
618     */
619    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
620    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
621
622    /**
623     * Strict Mode background batched logging state.
624     *
625     * The string buffer is guarded by itself, and its lock is also
626     * used to determine if another batched write is already
627     * in-flight.
628     */
629    private final StringBuilder mStrictModeBuffer = new StringBuilder();
630
631    /**
632     * Keeps track of all IIntentReceivers that have been registered for
633     * broadcasts.  Hash keys are the receiver IBinder, hash value is
634     * a ReceiverList.
635     */
636    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
637            new HashMap<IBinder, ReceiverList>();
638
639    /**
640     * Resolver for broadcast intents to registered receivers.
641     * Holds BroadcastFilter (subclass of IntentFilter).
642     */
643    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
644            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
645        @Override
646        protected boolean allowFilterResult(
647                BroadcastFilter filter, List<BroadcastFilter> dest) {
648            IBinder target = filter.receiverList.receiver.asBinder();
649            for (int i=dest.size()-1; i>=0; i--) {
650                if (dest.get(i).receiverList.receiver.asBinder() == target) {
651                    return false;
652                }
653            }
654            return true;
655        }
656
657        @Override
658        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
659            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
660                    || userId == filter.owningUserId) {
661                return super.newResult(filter, match, userId);
662            }
663            return null;
664        }
665
666        @Override
667        protected BroadcastFilter[] newArray(int size) {
668            return new BroadcastFilter[size];
669        }
670
671        @Override
672        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
673            return packageName.equals(filter.packageName);
674        }
675    };
676
677    /**
678     * State of all active sticky broadcasts per user.  Keys are the action of the
679     * sticky Intent, values are an ArrayList of all broadcasted intents with
680     * that action (which should usually be one).  The SparseArray is keyed
681     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
682     * for stickies that are sent to all users.
683     */
684    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
685            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
686
687    final ActiveServices mServices;
688
689    /**
690     * Backup/restore process management
691     */
692    String mBackupAppName = null;
693    BackupRecord mBackupTarget = null;
694
695    /**
696     * List of PendingThumbnailsRecord objects of clients who are still
697     * waiting to receive all of the thumbnails for a task.
698     */
699    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
700            new ArrayList<PendingThumbnailsRecord>();
701
702    final ProviderMap mProviderMap;
703
704    /**
705     * List of content providers who have clients waiting for them.  The
706     * application is currently being launched and the provider will be
707     * removed from this list once it is published.
708     */
709    final ArrayList<ContentProviderRecord> mLaunchingProviders
710            = new ArrayList<ContentProviderRecord>();
711
712    /**
713     * File storing persisted {@link #mGrantedUriPermissions}.
714     */
715    private final AtomicFile mGrantFile;
716
717    /** XML constants used in {@link #mGrantFile} */
718    private static final String TAG_URI_GRANTS = "uri-grants";
719    private static final String TAG_URI_GRANT = "uri-grant";
720    private static final String ATTR_USER_HANDLE = "userHandle";
721    private static final String ATTR_SOURCE_PKG = "sourcePkg";
722    private static final String ATTR_TARGET_PKG = "targetPkg";
723    private static final String ATTR_URI = "uri";
724    private static final String ATTR_MODE_FLAGS = "modeFlags";
725    private static final String ATTR_CREATED_TIME = "createdTime";
726
727    /**
728     * Global set of specific {@link Uri} permissions that have been granted.
729     * This optimized lookup structure maps from {@link UriPermission#targetUid}
730     * to {@link UriPermission#uri} to {@link UriPermission}.
731     */
732    @GuardedBy("this")
733    private final SparseArray<ArrayMap<Uri, UriPermission>>
734            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
735
736    CoreSettingsObserver mCoreSettingsObserver;
737
738    /**
739     * Thread-local storage used to carry caller permissions over through
740     * indirect content-provider access.
741     */
742    private class Identity {
743        public int pid;
744        public int uid;
745
746        Identity(int _pid, int _uid) {
747            pid = _pid;
748            uid = _uid;
749        }
750    }
751
752    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
753
754    /**
755     * All information we have collected about the runtime performance of
756     * any user id that can impact battery performance.
757     */
758    final BatteryStatsService mBatteryStatsService;
759
760    /**
761     * Information about component usage
762     */
763    final UsageStatsService mUsageStatsService;
764
765    /**
766     * Information about and control over application operations
767     */
768    final AppOpsService mAppOpsService;
769
770    /**
771     * Current configuration information.  HistoryRecord objects are given
772     * a reference to this object to indicate which configuration they are
773     * currently running in, so this object must be kept immutable.
774     */
775    Configuration mConfiguration = new Configuration();
776
777    /**
778     * Current sequencing integer of the configuration, for skipping old
779     * configurations.
780     */
781    int mConfigurationSeq = 0;
782
783    /**
784     * Hardware-reported OpenGLES version.
785     */
786    final int GL_ES_VERSION;
787
788    /**
789     * List of initialization arguments to pass to all processes when binding applications to them.
790     * For example, references to the commonly used services.
791     */
792    HashMap<String, IBinder> mAppBindArgs;
793
794    /**
795     * Temporary to avoid allocations.  Protected by main lock.
796     */
797    final StringBuilder mStringBuilder = new StringBuilder(256);
798
799    /**
800     * Used to control how we initialize the service.
801     */
802    boolean mStartRunning = false;
803    ComponentName mTopComponent;
804    String mTopAction;
805    String mTopData;
806    boolean mProcessesReady = false;
807    boolean mSystemReady = false;
808    boolean mBooting = false;
809    boolean mWaitingUpdate = false;
810    boolean mDidUpdate = false;
811    boolean mOnBattery = false;
812    boolean mLaunchWarningShown = false;
813
814    Context mContext;
815
816    int mFactoryTest;
817
818    boolean mCheckedForSetup;
819
820    /**
821     * The time at which we will allow normal application switches again,
822     * after a call to {@link #stopAppSwitches()}.
823     */
824    long mAppSwitchesAllowedTime;
825
826    /**
827     * This is set to true after the first switch after mAppSwitchesAllowedTime
828     * is set; any switches after that will clear the time.
829     */
830    boolean mDidAppSwitch;
831
832    /**
833     * Last time (in realtime) at which we checked for power usage.
834     */
835    long mLastPowerCheckRealtime;
836
837    /**
838     * Last time (in uptime) at which we checked for power usage.
839     */
840    long mLastPowerCheckUptime;
841
842    /**
843     * Set while we are wanting to sleep, to prevent any
844     * activities from being started/resumed.
845     */
846    boolean mSleeping = false;
847
848    /**
849     * State of external calls telling us if the device is asleep.
850     */
851    boolean mWentToSleep = false;
852
853    /**
854     * State of external call telling us if the lock screen is shown.
855     */
856    boolean mLockScreenShown = false;
857
858    /**
859     * Set if we are shutting down the system, similar to sleeping.
860     */
861    boolean mShuttingDown = false;
862
863    /**
864     * Current sequence id for oom_adj computation traversal.
865     */
866    int mAdjSeq = 0;
867
868    /**
869     * Current sequence id for process LRU updating.
870     */
871    int mLruSeq = 0;
872
873    /**
874     * Keep track of the non-cached/empty process we last found, to help
875     * determine how to distribute cached/empty processes next time.
876     */
877    int mNumNonCachedProcs = 0;
878
879    /**
880     * Keep track of the number of cached hidden procs, to balance oom adj
881     * distribution between those and empty procs.
882     */
883    int mNumCachedHiddenProcs = 0;
884
885    /**
886     * Keep track of the number of service processes we last found, to
887     * determine on the next iteration which should be B services.
888     */
889    int mNumServiceProcs = 0;
890    int mNewNumAServiceProcs = 0;
891    int mNewNumServiceProcs = 0;
892
893    /**
894     * Allow the current computed overall memory level of the system to go down?
895     * This is set to false when we are killing processes for reasons other than
896     * memory management, so that the now smaller process list will not be taken as
897     * an indication that memory is tighter.
898     */
899    boolean mAllowLowerMemLevel = false;
900
901    /**
902     * The last computed memory level, for holding when we are in a state that
903     * processes are going away for other reasons.
904     */
905    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
906
907    /**
908     * The last total number of process we have, to determine if changes actually look
909     * like a shrinking number of process due to lower RAM.
910     */
911    int mLastNumProcesses;
912
913    /**
914     * The uptime of the last time we performed idle maintenance.
915     */
916    long mLastIdleTime = SystemClock.uptimeMillis();
917
918    /**
919     * Total time spent with RAM that has been added in the past since the last idle time.
920     */
921    long mLowRamTimeSinceLastIdle = 0;
922
923    /**
924     * If RAM is currently low, when that horrible situation started.
925     */
926    long mLowRamStartTime = 0;
927
928    /**
929     * For reporting to battery stats the current top application.
930     */
931    private String mCurResumedPackage = null;
932    private int mCurResumedUid = -1;
933
934    /**
935     * For reporting to battery stats the apps currently running foreground
936     * service.  The ProcessMap is package/uid tuples; each of these contain
937     * an array of the currently foreground processes.
938     */
939    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
940            = new ProcessMap<ArrayList<ProcessRecord>>();
941
942    /**
943     * This is set if we had to do a delayed dexopt of an app before launching
944     * it, to increasing the ANR timeouts in that case.
945     */
946    boolean mDidDexOpt;
947
948    String mDebugApp = null;
949    boolean mWaitForDebugger = false;
950    boolean mDebugTransient = false;
951    String mOrigDebugApp = null;
952    boolean mOrigWaitForDebugger = false;
953    boolean mAlwaysFinishActivities = false;
954    IActivityController mController = null;
955    String mProfileApp = null;
956    ProcessRecord mProfileProc = null;
957    String mProfileFile;
958    ParcelFileDescriptor mProfileFd;
959    int mProfileType = 0;
960    boolean mAutoStopProfiler = false;
961    String mOpenGlTraceApp = null;
962
963    static class ProcessChangeItem {
964        static final int CHANGE_ACTIVITIES = 1<<0;
965        static final int CHANGE_IMPORTANCE= 1<<1;
966        int changes;
967        int uid;
968        int pid;
969        int importance;
970        boolean foregroundActivities;
971    }
972
973    final RemoteCallbackList<IProcessObserver> mProcessObservers
974            = new RemoteCallbackList<IProcessObserver>();
975    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
976
977    final ArrayList<ProcessChangeItem> mPendingProcessChanges
978            = new ArrayList<ProcessChangeItem>();
979    final ArrayList<ProcessChangeItem> mAvailProcessChanges
980            = new ArrayList<ProcessChangeItem>();
981
982    /**
983     * Runtime CPU use collection thread.  This object's lock is used to
984     * protect all related state.
985     */
986    final Thread mProcessCpuThread;
987
988    /**
989     * Used to collect process stats when showing not responding dialog.
990     * Protected by mProcessCpuThread.
991     */
992    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
993            MONITOR_THREAD_CPU_USAGE);
994    final AtomicLong mLastCpuTime = new AtomicLong(0);
995    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
996
997    long mLastWriteTime = 0;
998
999    /**
1000     * Used to retain an update lock when the foreground activity is in
1001     * immersive mode.
1002     */
1003    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1004
1005    /**
1006     * Set to true after the system has finished booting.
1007     */
1008    boolean mBooted = false;
1009
1010    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1011    int mProcessLimitOverride = -1;
1012
1013    WindowManagerService mWindowManager;
1014
1015    final ActivityThread mSystemThread;
1016
1017    int mCurrentUserId = 0;
1018    private UserManagerService mUserManager;
1019
1020    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1021        final ProcessRecord mApp;
1022        final int mPid;
1023        final IApplicationThread mAppThread;
1024
1025        AppDeathRecipient(ProcessRecord app, int pid,
1026                IApplicationThread thread) {
1027            if (localLOGV) Slog.v(
1028                TAG, "New death recipient " + this
1029                + " for thread " + thread.asBinder());
1030            mApp = app;
1031            mPid = pid;
1032            mAppThread = thread;
1033        }
1034
1035        @Override
1036        public void binderDied() {
1037            if (localLOGV) Slog.v(
1038                TAG, "Death received in " + this
1039                + " for thread " + mAppThread.asBinder());
1040            synchronized(ActivityManagerService.this) {
1041                appDiedLocked(mApp, mPid, mAppThread);
1042            }
1043        }
1044    }
1045
1046    static final int SHOW_ERROR_MSG = 1;
1047    static final int SHOW_NOT_RESPONDING_MSG = 2;
1048    static final int SHOW_FACTORY_ERROR_MSG = 3;
1049    static final int UPDATE_CONFIGURATION_MSG = 4;
1050    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1051    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1052    static final int SERVICE_TIMEOUT_MSG = 12;
1053    static final int UPDATE_TIME_ZONE = 13;
1054    static final int SHOW_UID_ERROR_MSG = 14;
1055    static final int IM_FEELING_LUCKY_MSG = 15;
1056    static final int PROC_START_TIMEOUT_MSG = 20;
1057    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1058    static final int KILL_APPLICATION_MSG = 22;
1059    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1060    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1061    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1062    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1063    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1064    static final int CLEAR_DNS_CACHE_MSG = 28;
1065    static final int UPDATE_HTTP_PROXY_MSG = 29;
1066    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1067    static final int DISPATCH_PROCESSES_CHANGED = 31;
1068    static final int DISPATCH_PROCESS_DIED = 32;
1069    static final int REPORT_MEM_USAGE_MSG = 33;
1070    static final int REPORT_USER_SWITCH_MSG = 34;
1071    static final int CONTINUE_USER_SWITCH_MSG = 35;
1072    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1073    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1074    static final int PERSIST_URI_GRANTS_MSG = 38;
1075    static final int REQUEST_ALL_PSS_MSG = 39;
1076    static final int START_RELATED_USERS_MSG = 40;
1077
1078    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1079    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1080    static final int FIRST_COMPAT_MODE_MSG = 300;
1081    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1082
1083    AlertDialog mUidAlert;
1084    CompatModeDialog mCompatModeDialog;
1085    long mLastMemUsageReportTime = 0;
1086
1087    /**
1088     * Flag whether the current user is a "monkey", i.e. whether
1089     * the UI is driven by a UI automation tool.
1090     */
1091    private boolean mUserIsMonkey;
1092
1093    final ServiceThread mHandlerThread;
1094    final MainHandler mHandler;
1095
1096    final class MainHandler extends Handler {
1097        public MainHandler(Looper looper) {
1098            super(looper, null, true);
1099        }
1100
1101        @Override
1102        public void handleMessage(Message msg) {
1103            switch (msg.what) {
1104            case SHOW_ERROR_MSG: {
1105                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1106                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1107                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1108                synchronized (ActivityManagerService.this) {
1109                    ProcessRecord proc = (ProcessRecord)data.get("app");
1110                    AppErrorResult res = (AppErrorResult) data.get("result");
1111                    if (proc != null && proc.crashDialog != null) {
1112                        Slog.e(TAG, "App already has crash dialog: " + proc);
1113                        if (res != null) {
1114                            res.set(0);
1115                        }
1116                        return;
1117                    }
1118                    if (!showBackground && UserHandle.getAppId(proc.uid)
1119                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1120                            && proc.pid != MY_PID) {
1121                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1122                        if (res != null) {
1123                            res.set(0);
1124                        }
1125                        return;
1126                    }
1127                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1128                        Dialog d = new AppErrorDialog(mContext,
1129                                ActivityManagerService.this, res, proc);
1130                        d.show();
1131                        proc.crashDialog = d;
1132                    } else {
1133                        // The device is asleep, so just pretend that the user
1134                        // saw a crash dialog and hit "force quit".
1135                        if (res != null) {
1136                            res.set(0);
1137                        }
1138                    }
1139                }
1140
1141                ensureBootCompleted();
1142            } break;
1143            case SHOW_NOT_RESPONDING_MSG: {
1144                synchronized (ActivityManagerService.this) {
1145                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1146                    ProcessRecord proc = (ProcessRecord)data.get("app");
1147                    if (proc != null && proc.anrDialog != null) {
1148                        Slog.e(TAG, "App already has anr dialog: " + proc);
1149                        return;
1150                    }
1151
1152                    Intent intent = new Intent("android.intent.action.ANR");
1153                    if (!mProcessesReady) {
1154                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1155                                | Intent.FLAG_RECEIVER_FOREGROUND);
1156                    }
1157                    broadcastIntentLocked(null, null, intent,
1158                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1159                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1160
1161                    if (mShowDialogs) {
1162                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1163                                mContext, proc, (ActivityRecord)data.get("activity"),
1164                                msg.arg1 != 0);
1165                        d.show();
1166                        proc.anrDialog = d;
1167                    } else {
1168                        // Just kill the app if there is no dialog to be shown.
1169                        killAppAtUsersRequest(proc, null);
1170                    }
1171                }
1172
1173                ensureBootCompleted();
1174            } break;
1175            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1176                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1177                synchronized (ActivityManagerService.this) {
1178                    ProcessRecord proc = (ProcessRecord) data.get("app");
1179                    if (proc == null) {
1180                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1181                        break;
1182                    }
1183                    if (proc.crashDialog != null) {
1184                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1185                        return;
1186                    }
1187                    AppErrorResult res = (AppErrorResult) data.get("result");
1188                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1189                        Dialog d = new StrictModeViolationDialog(mContext,
1190                                ActivityManagerService.this, res, proc);
1191                        d.show();
1192                        proc.crashDialog = d;
1193                    } else {
1194                        // The device is asleep, so just pretend that the user
1195                        // saw a crash dialog and hit "force quit".
1196                        res.set(0);
1197                    }
1198                }
1199                ensureBootCompleted();
1200            } break;
1201            case SHOW_FACTORY_ERROR_MSG: {
1202                Dialog d = new FactoryErrorDialog(
1203                    mContext, msg.getData().getCharSequence("msg"));
1204                d.show();
1205                ensureBootCompleted();
1206            } break;
1207            case UPDATE_CONFIGURATION_MSG: {
1208                final ContentResolver resolver = mContext.getContentResolver();
1209                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1210            } break;
1211            case GC_BACKGROUND_PROCESSES_MSG: {
1212                synchronized (ActivityManagerService.this) {
1213                    performAppGcsIfAppropriateLocked();
1214                }
1215            } break;
1216            case WAIT_FOR_DEBUGGER_MSG: {
1217                synchronized (ActivityManagerService.this) {
1218                    ProcessRecord app = (ProcessRecord)msg.obj;
1219                    if (msg.arg1 != 0) {
1220                        if (!app.waitedForDebugger) {
1221                            Dialog d = new AppWaitingForDebuggerDialog(
1222                                    ActivityManagerService.this,
1223                                    mContext, app);
1224                            app.waitDialog = d;
1225                            app.waitedForDebugger = true;
1226                            d.show();
1227                        }
1228                    } else {
1229                        if (app.waitDialog != null) {
1230                            app.waitDialog.dismiss();
1231                            app.waitDialog = null;
1232                        }
1233                    }
1234                }
1235            } break;
1236            case SERVICE_TIMEOUT_MSG: {
1237                if (mDidDexOpt) {
1238                    mDidDexOpt = false;
1239                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1240                    nmsg.obj = msg.obj;
1241                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1242                    return;
1243                }
1244                mServices.serviceTimeout((ProcessRecord)msg.obj);
1245            } break;
1246            case UPDATE_TIME_ZONE: {
1247                synchronized (ActivityManagerService.this) {
1248                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1249                        ProcessRecord r = mLruProcesses.get(i);
1250                        if (r.thread != null) {
1251                            try {
1252                                r.thread.updateTimeZone();
1253                            } catch (RemoteException ex) {
1254                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1255                            }
1256                        }
1257                    }
1258                }
1259            } break;
1260            case CLEAR_DNS_CACHE_MSG: {
1261                synchronized (ActivityManagerService.this) {
1262                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1263                        ProcessRecord r = mLruProcesses.get(i);
1264                        if (r.thread != null) {
1265                            try {
1266                                r.thread.clearDnsCache();
1267                            } catch (RemoteException ex) {
1268                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1269                            }
1270                        }
1271                    }
1272                }
1273            } break;
1274            case UPDATE_HTTP_PROXY_MSG: {
1275                ProxyProperties proxy = (ProxyProperties)msg.obj;
1276                String host = "";
1277                String port = "";
1278                String exclList = "";
1279                String pacFileUrl = null;
1280                if (proxy != null) {
1281                    host = proxy.getHost();
1282                    port = Integer.toString(proxy.getPort());
1283                    exclList = proxy.getExclusionList();
1284                    pacFileUrl = proxy.getPacFileUrl();
1285                }
1286                synchronized (ActivityManagerService.this) {
1287                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1288                        ProcessRecord r = mLruProcesses.get(i);
1289                        if (r.thread != null) {
1290                            try {
1291                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1292                            } catch (RemoteException ex) {
1293                                Slog.w(TAG, "Failed to update http proxy for: " +
1294                                        r.info.processName);
1295                            }
1296                        }
1297                    }
1298                }
1299            } break;
1300            case SHOW_UID_ERROR_MSG: {
1301                String title = "System UIDs Inconsistent";
1302                String text = "UIDs on the system are inconsistent, you need to wipe your"
1303                        + " data partition or your device will be unstable.";
1304                Log.e(TAG, title + ": " + text);
1305                if (mShowDialogs) {
1306                    // XXX This is a temporary dialog, no need to localize.
1307                    AlertDialog d = new BaseErrorDialog(mContext);
1308                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1309                    d.setCancelable(false);
1310                    d.setTitle(title);
1311                    d.setMessage(text);
1312                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1313                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1314                    mUidAlert = d;
1315                    d.show();
1316                }
1317            } break;
1318            case IM_FEELING_LUCKY_MSG: {
1319                if (mUidAlert != null) {
1320                    mUidAlert.dismiss();
1321                    mUidAlert = null;
1322                }
1323            } break;
1324            case PROC_START_TIMEOUT_MSG: {
1325                if (mDidDexOpt) {
1326                    mDidDexOpt = false;
1327                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1328                    nmsg.obj = msg.obj;
1329                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1330                    return;
1331                }
1332                ProcessRecord app = (ProcessRecord)msg.obj;
1333                synchronized (ActivityManagerService.this) {
1334                    processStartTimedOutLocked(app);
1335                }
1336            } break;
1337            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1338                synchronized (ActivityManagerService.this) {
1339                    doPendingActivityLaunchesLocked(true);
1340                }
1341            } break;
1342            case KILL_APPLICATION_MSG: {
1343                synchronized (ActivityManagerService.this) {
1344                    int appid = msg.arg1;
1345                    boolean restart = (msg.arg2 == 1);
1346                    Bundle bundle = (Bundle)msg.obj;
1347                    String pkg = bundle.getString("pkg");
1348                    String reason = bundle.getString("reason");
1349                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1350                            false, UserHandle.USER_ALL, reason);
1351                }
1352            } break;
1353            case FINALIZE_PENDING_INTENT_MSG: {
1354                ((PendingIntentRecord)msg.obj).completeFinalize();
1355            } break;
1356            case POST_HEAVY_NOTIFICATION_MSG: {
1357                INotificationManager inm = NotificationManager.getService();
1358                if (inm == null) {
1359                    return;
1360                }
1361
1362                ActivityRecord root = (ActivityRecord)msg.obj;
1363                ProcessRecord process = root.app;
1364                if (process == null) {
1365                    return;
1366                }
1367
1368                try {
1369                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1370                    String text = mContext.getString(R.string.heavy_weight_notification,
1371                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1372                    Notification notification = new Notification();
1373                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1374                    notification.when = 0;
1375                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1376                    notification.tickerText = text;
1377                    notification.defaults = 0; // please be quiet
1378                    notification.sound = null;
1379                    notification.vibrate = null;
1380                    notification.setLatestEventInfo(context, text,
1381                            mContext.getText(R.string.heavy_weight_notification_detail),
1382                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1383                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1384                                    new UserHandle(root.userId)));
1385
1386                    try {
1387                        int[] outId = new int[1];
1388                        inm.enqueueNotificationWithTag("android", "android", null,
1389                                R.string.heavy_weight_notification,
1390                                notification, outId, root.userId);
1391                    } catch (RuntimeException e) {
1392                        Slog.w(ActivityManagerService.TAG,
1393                                "Error showing notification for heavy-weight app", e);
1394                    } catch (RemoteException e) {
1395                    }
1396                } catch (NameNotFoundException e) {
1397                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1398                }
1399            } break;
1400            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1401                INotificationManager inm = NotificationManager.getService();
1402                if (inm == null) {
1403                    return;
1404                }
1405                try {
1406                    inm.cancelNotificationWithTag("android", null,
1407                            R.string.heavy_weight_notification,  msg.arg1);
1408                } catch (RuntimeException e) {
1409                    Slog.w(ActivityManagerService.TAG,
1410                            "Error canceling notification for service", e);
1411                } catch (RemoteException e) {
1412                }
1413            } break;
1414            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1415                synchronized (ActivityManagerService.this) {
1416                    checkExcessivePowerUsageLocked(true);
1417                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1418                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1419                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1420                }
1421            } break;
1422            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1423                synchronized (ActivityManagerService.this) {
1424                    ActivityRecord ar = (ActivityRecord)msg.obj;
1425                    if (mCompatModeDialog != null) {
1426                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1427                                ar.info.applicationInfo.packageName)) {
1428                            return;
1429                        }
1430                        mCompatModeDialog.dismiss();
1431                        mCompatModeDialog = null;
1432                    }
1433                    if (ar != null && false) {
1434                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1435                                ar.packageName)) {
1436                            int mode = mCompatModePackages.computeCompatModeLocked(
1437                                    ar.info.applicationInfo);
1438                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1439                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1440                                mCompatModeDialog = new CompatModeDialog(
1441                                        ActivityManagerService.this, mContext,
1442                                        ar.info.applicationInfo);
1443                                mCompatModeDialog.show();
1444                            }
1445                        }
1446                    }
1447                }
1448                break;
1449            }
1450            case DISPATCH_PROCESSES_CHANGED: {
1451                dispatchProcessesChanged();
1452                break;
1453            }
1454            case DISPATCH_PROCESS_DIED: {
1455                final int pid = msg.arg1;
1456                final int uid = msg.arg2;
1457                dispatchProcessDied(pid, uid);
1458                break;
1459            }
1460            case REPORT_MEM_USAGE_MSG: {
1461                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1462                Thread thread = new Thread() {
1463                    @Override public void run() {
1464                        final SparseArray<ProcessMemInfo> infoMap
1465                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1466                        for (int i=0, N=memInfos.size(); i<N; i++) {
1467                            ProcessMemInfo mi = memInfos.get(i);
1468                            infoMap.put(mi.pid, mi);
1469                        }
1470                        updateCpuStatsNow();
1471                        synchronized (mProcessCpuThread) {
1472                            final int N = mProcessCpuTracker.countStats();
1473                            for (int i=0; i<N; i++) {
1474                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1475                                if (st.vsize > 0) {
1476                                    long pss = Debug.getPss(st.pid, null);
1477                                    if (pss > 0) {
1478                                        if (infoMap.indexOfKey(st.pid) < 0) {
1479                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1480                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1481                                            mi.pss = pss;
1482                                            memInfos.add(mi);
1483                                        }
1484                                    }
1485                                }
1486                            }
1487                        }
1488
1489                        long totalPss = 0;
1490                        for (int i=0, N=memInfos.size(); i<N; i++) {
1491                            ProcessMemInfo mi = memInfos.get(i);
1492                            if (mi.pss == 0) {
1493                                mi.pss = Debug.getPss(mi.pid, null);
1494                            }
1495                            totalPss += mi.pss;
1496                        }
1497                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1498                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1499                                if (lhs.oomAdj != rhs.oomAdj) {
1500                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1501                                }
1502                                if (lhs.pss != rhs.pss) {
1503                                    return lhs.pss < rhs.pss ? 1 : -1;
1504                                }
1505                                return 0;
1506                            }
1507                        });
1508
1509                        StringBuilder tag = new StringBuilder(128);
1510                        StringBuilder stack = new StringBuilder(128);
1511                        tag.append("Low on memory -- ");
1512                        appendMemBucket(tag, totalPss, "total", false);
1513                        appendMemBucket(stack, totalPss, "total", true);
1514
1515                        StringBuilder logBuilder = new StringBuilder(1024);
1516                        logBuilder.append("Low on memory:\n");
1517
1518                        boolean firstLine = true;
1519                        int lastOomAdj = Integer.MIN_VALUE;
1520                        for (int i=0, N=memInfos.size(); i<N; i++) {
1521                            ProcessMemInfo mi = memInfos.get(i);
1522
1523                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1524                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1525                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1526                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1527                                if (lastOomAdj != mi.oomAdj) {
1528                                    lastOomAdj = mi.oomAdj;
1529                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1530                                        tag.append(" / ");
1531                                    }
1532                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1533                                        if (firstLine) {
1534                                            stack.append(":");
1535                                            firstLine = false;
1536                                        }
1537                                        stack.append("\n\t at ");
1538                                    } else {
1539                                        stack.append("$");
1540                                    }
1541                                } else {
1542                                    tag.append(" ");
1543                                    stack.append("$");
1544                                }
1545                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1546                                    appendMemBucket(tag, mi.pss, mi.name, false);
1547                                }
1548                                appendMemBucket(stack, mi.pss, mi.name, true);
1549                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1550                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1551                                    stack.append("(");
1552                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1553                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1554                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1555                                            stack.append(":");
1556                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1557                                        }
1558                                    }
1559                                    stack.append(")");
1560                                }
1561                            }
1562
1563                            logBuilder.append("  ");
1564                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1565                            logBuilder.append(' ');
1566                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1567                            logBuilder.append(' ');
1568                            ProcessList.appendRamKb(logBuilder, mi.pss);
1569                            logBuilder.append(" kB: ");
1570                            logBuilder.append(mi.name);
1571                            logBuilder.append(" (");
1572                            logBuilder.append(mi.pid);
1573                            logBuilder.append(") ");
1574                            logBuilder.append(mi.adjType);
1575                            logBuilder.append('\n');
1576                            if (mi.adjReason != null) {
1577                                logBuilder.append("                      ");
1578                                logBuilder.append(mi.adjReason);
1579                                logBuilder.append('\n');
1580                            }
1581                        }
1582
1583                        logBuilder.append("           ");
1584                        ProcessList.appendRamKb(logBuilder, totalPss);
1585                        logBuilder.append(" kB: TOTAL\n");
1586
1587                        long[] infos = new long[Debug.MEMINFO_COUNT];
1588                        Debug.getMemInfo(infos);
1589                        logBuilder.append("  MemInfo: ");
1590                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1591                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1592                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1593                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1594                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1595                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1596                            logBuilder.append("  ZRAM: ");
1597                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1598                            logBuilder.append(" kB RAM, ");
1599                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1600                            logBuilder.append(" kB swap total, ");
1601                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1602                            logBuilder.append(" kB swap free\n");
1603                        }
1604                        Slog.i(TAG, logBuilder.toString());
1605
1606                        StringBuilder dropBuilder = new StringBuilder(1024);
1607                        /*
1608                        StringWriter oomSw = new StringWriter();
1609                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1610                        StringWriter catSw = new StringWriter();
1611                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1612                        String[] emptyArgs = new String[] { };
1613                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1614                        oomPw.flush();
1615                        String oomString = oomSw.toString();
1616                        */
1617                        dropBuilder.append(stack);
1618                        dropBuilder.append('\n');
1619                        dropBuilder.append('\n');
1620                        dropBuilder.append(logBuilder);
1621                        dropBuilder.append('\n');
1622                        /*
1623                        dropBuilder.append(oomString);
1624                        dropBuilder.append('\n');
1625                        */
1626                        StringWriter catSw = new StringWriter();
1627                        synchronized (ActivityManagerService.this) {
1628                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1629                            String[] emptyArgs = new String[] { };
1630                            catPw.println();
1631                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1632                            catPw.println();
1633                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1634                                    false, false, null);
1635                            catPw.println();
1636                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1637                            catPw.flush();
1638                        }
1639                        dropBuilder.append(catSw.toString());
1640                        addErrorToDropBox("lowmem", null, "system_server", null,
1641                                null, tag.toString(), dropBuilder.toString(), null, null);
1642                        //Slog.i(TAG, "Sent to dropbox:");
1643                        //Slog.i(TAG, dropBuilder.toString());
1644                        synchronized (ActivityManagerService.this) {
1645                            long now = SystemClock.uptimeMillis();
1646                            if (mLastMemUsageReportTime < now) {
1647                                mLastMemUsageReportTime = now;
1648                            }
1649                        }
1650                    }
1651                };
1652                thread.start();
1653                break;
1654            }
1655            case REPORT_USER_SWITCH_MSG: {
1656                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1657                break;
1658            }
1659            case CONTINUE_USER_SWITCH_MSG: {
1660                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1661                break;
1662            }
1663            case USER_SWITCH_TIMEOUT_MSG: {
1664                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1665                break;
1666            }
1667            case IMMERSIVE_MODE_LOCK_MSG: {
1668                final boolean nextState = (msg.arg1 != 0);
1669                if (mUpdateLock.isHeld() != nextState) {
1670                    if (DEBUG_IMMERSIVE) {
1671                        final ActivityRecord r = (ActivityRecord) msg.obj;
1672                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1673                    }
1674                    if (nextState) {
1675                        mUpdateLock.acquire();
1676                    } else {
1677                        mUpdateLock.release();
1678                    }
1679                }
1680                break;
1681            }
1682            case PERSIST_URI_GRANTS_MSG: {
1683                writeGrantedUriPermissions();
1684                break;
1685            }
1686            case REQUEST_ALL_PSS_MSG: {
1687                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1688                break;
1689            }
1690            case START_RELATED_USERS_MSG: {
1691                synchronized (ActivityManagerService.this) {
1692                    startRelatedUsersLocked();
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        startRunning(null, null, null, null);
2011    }
2012
2013    @Override
2014    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2015            throws RemoteException {
2016        if (code == SYSPROPS_TRANSACTION) {
2017            // We need to tell all apps about the system property change.
2018            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2019            synchronized(this) {
2020                final int NP = mProcessNames.getMap().size();
2021                for (int ip=0; ip<NP; ip++) {
2022                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2023                    final int NA = apps.size();
2024                    for (int ia=0; ia<NA; ia++) {
2025                        ProcessRecord app = apps.valueAt(ia);
2026                        if (app.thread != null) {
2027                            procs.add(app.thread.asBinder());
2028                        }
2029                    }
2030                }
2031            }
2032
2033            int N = procs.size();
2034            for (int i=0; i<N; i++) {
2035                Parcel data2 = Parcel.obtain();
2036                try {
2037                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2038                } catch (RemoteException e) {
2039                }
2040                data2.recycle();
2041            }
2042        }
2043        try {
2044            return super.onTransact(code, data, reply, flags);
2045        } catch (RuntimeException e) {
2046            // The activity manager only throws security exceptions, so let's
2047            // log all others.
2048            if (!(e instanceof SecurityException)) {
2049                Slog.wtf(TAG, "Activity Manager Crash", e);
2050            }
2051            throw e;
2052        }
2053    }
2054
2055    void updateCpuStats() {
2056        final long now = SystemClock.uptimeMillis();
2057        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2058            return;
2059        }
2060        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2061            synchronized (mProcessCpuThread) {
2062                mProcessCpuThread.notify();
2063            }
2064        }
2065    }
2066
2067    void updateCpuStatsNow() {
2068        synchronized (mProcessCpuThread) {
2069            mProcessCpuMutexFree.set(false);
2070            final long now = SystemClock.uptimeMillis();
2071            boolean haveNewCpuStats = false;
2072
2073            if (MONITOR_CPU_USAGE &&
2074                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2075                mLastCpuTime.set(now);
2076                haveNewCpuStats = true;
2077                mProcessCpuTracker.update();
2078                //Slog.i(TAG, mProcessCpu.printCurrentState());
2079                //Slog.i(TAG, "Total CPU usage: "
2080                //        + mProcessCpu.getTotalCpuPercent() + "%");
2081
2082                // Slog the cpu usage if the property is set.
2083                if ("true".equals(SystemProperties.get("events.cpu"))) {
2084                    int user = mProcessCpuTracker.getLastUserTime();
2085                    int system = mProcessCpuTracker.getLastSystemTime();
2086                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2087                    int irq = mProcessCpuTracker.getLastIrqTime();
2088                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2089                    int idle = mProcessCpuTracker.getLastIdleTime();
2090
2091                    int total = user + system + iowait + irq + softIrq + idle;
2092                    if (total == 0) total = 1;
2093
2094                    EventLog.writeEvent(EventLogTags.CPU,
2095                            ((user+system+iowait+irq+softIrq) * 100) / total,
2096                            (user * 100) / total,
2097                            (system * 100) / total,
2098                            (iowait * 100) / total,
2099                            (irq * 100) / total,
2100                            (softIrq * 100) / total);
2101                }
2102            }
2103
2104            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2105            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2106            synchronized(bstats) {
2107                synchronized(mPidsSelfLocked) {
2108                    if (haveNewCpuStats) {
2109                        if (mOnBattery) {
2110                            int perc = bstats.startAddingCpuLocked();
2111                            int totalUTime = 0;
2112                            int totalSTime = 0;
2113                            final int N = mProcessCpuTracker.countStats();
2114                            for (int i=0; i<N; i++) {
2115                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2116                                if (!st.working) {
2117                                    continue;
2118                                }
2119                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2120                                int otherUTime = (st.rel_utime*perc)/100;
2121                                int otherSTime = (st.rel_stime*perc)/100;
2122                                totalUTime += otherUTime;
2123                                totalSTime += otherSTime;
2124                                if (pr != null) {
2125                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2126                                    if (ps == null || !ps.isActive()) {
2127                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2128                                                pr.info.uid, pr.processName);
2129                                    }
2130                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2131                                            st.rel_stime-otherSTime);
2132                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2133                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2134                                } else {
2135                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2136                                    if (ps == null || !ps.isActive()) {
2137                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2138                                                bstats.mapUid(st.uid), st.name);
2139                                    }
2140                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2141                                            st.rel_stime-otherSTime);
2142                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2143                                }
2144                            }
2145                            bstats.finishAddingCpuLocked(perc, totalUTime,
2146                                    totalSTime, cpuSpeedTimes);
2147                        }
2148                    }
2149                }
2150
2151                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2152                    mLastWriteTime = now;
2153                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2154                }
2155            }
2156        }
2157    }
2158
2159    @Override
2160    public void batteryNeedsCpuUpdate() {
2161        updateCpuStatsNow();
2162    }
2163
2164    @Override
2165    public void batteryPowerChanged(boolean onBattery) {
2166        // When plugging in, update the CPU stats first before changing
2167        // the plug state.
2168        updateCpuStatsNow();
2169        synchronized (this) {
2170            synchronized(mPidsSelfLocked) {
2171                mOnBattery = DEBUG_POWER ? true : onBattery;
2172            }
2173        }
2174    }
2175
2176    /**
2177     * Initialize the application bind args. These are passed to each
2178     * process when the bindApplication() IPC is sent to the process. They're
2179     * lazily setup to make sure the services are running when they're asked for.
2180     */
2181    private HashMap<String, IBinder> getCommonServicesLocked() {
2182        if (mAppBindArgs == null) {
2183            mAppBindArgs = new HashMap<String, IBinder>();
2184
2185            // Setup the application init args
2186            mAppBindArgs.put("package", ServiceManager.getService("package"));
2187            mAppBindArgs.put("window", ServiceManager.getService("window"));
2188            mAppBindArgs.put(Context.ALARM_SERVICE,
2189                    ServiceManager.getService(Context.ALARM_SERVICE));
2190        }
2191        return mAppBindArgs;
2192    }
2193
2194    final void setFocusedActivityLocked(ActivityRecord r) {
2195        if (mFocusedActivity != r) {
2196            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2197            mFocusedActivity = r;
2198            mStackSupervisor.setFocusedStack(r);
2199            if (r != null) {
2200                mWindowManager.setFocusedApp(r.appToken, true);
2201            }
2202            applyUpdateLockStateLocked(r);
2203        }
2204    }
2205
2206    @Override
2207    public void setFocusedStack(int stackId) {
2208        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2209        synchronized (ActivityManagerService.this) {
2210            ActivityStack stack = mStackSupervisor.getStack(stackId);
2211            if (stack != null) {
2212                ActivityRecord r = stack.topRunningActivityLocked(null);
2213                if (r != null) {
2214                    setFocusedActivityLocked(r);
2215                }
2216            }
2217        }
2218    }
2219
2220    @Override
2221    public void notifyActivityDrawn(IBinder token) {
2222        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2223        synchronized (this) {
2224            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2225            if (r != null) {
2226                r.task.stack.notifyActivityDrawnLocked(r);
2227            }
2228        }
2229    }
2230
2231    final void applyUpdateLockStateLocked(ActivityRecord r) {
2232        // Modifications to the UpdateLock state are done on our handler, outside
2233        // the activity manager's locks.  The new state is determined based on the
2234        // state *now* of the relevant activity record.  The object is passed to
2235        // the handler solely for logging detail, not to be consulted/modified.
2236        final boolean nextState = r != null && r.immersive;
2237        mHandler.sendMessage(
2238                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2239    }
2240
2241    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2242        Message msg = Message.obtain();
2243        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2244        msg.obj = r.task.askedCompatMode ? null : r;
2245        mHandler.sendMessage(msg);
2246    }
2247
2248    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2249            String what, Object obj, ProcessRecord srcApp) {
2250        app.lastActivityTime = now;
2251
2252        if (app.activities.size() > 0) {
2253            // Don't want to touch dependent processes that are hosting activities.
2254            return index;
2255        }
2256
2257        int lrui = mLruProcesses.lastIndexOf(app);
2258        if (lrui < 0) {
2259            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2260                    + what + " " + obj + " from " + srcApp);
2261            return index;
2262        }
2263
2264        if (lrui >= index) {
2265            // Don't want to cause this to move dependent processes *back* in the
2266            // list as if they were less frequently used.
2267            return index;
2268        }
2269
2270        if (lrui >= mLruProcessActivityStart) {
2271            // Don't want to touch dependent processes that are hosting activities.
2272            return index;
2273        }
2274
2275        mLruProcesses.remove(lrui);
2276        if (index > 0) {
2277            index--;
2278        }
2279        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2280                + " in LRU list: " + app);
2281        mLruProcesses.add(index, app);
2282        return index;
2283    }
2284
2285    final void removeLruProcessLocked(ProcessRecord app) {
2286        int lrui = mLruProcesses.lastIndexOf(app);
2287        if (lrui >= 0) {
2288            if (lrui <= mLruProcessActivityStart) {
2289                mLruProcessActivityStart--;
2290            }
2291            if (lrui <= mLruProcessServiceStart) {
2292                mLruProcessServiceStart--;
2293            }
2294            mLruProcesses.remove(lrui);
2295        }
2296    }
2297
2298    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2299            ProcessRecord client) {
2300        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2301        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2302        if (!activityChange && hasActivity) {
2303            // The process has activties, so we are only going to allow activity-based
2304            // adjustments move it.  It should be kept in the front of the list with other
2305            // processes that have activities, and we don't want those to change their
2306            // order except due to activity operations.
2307            return;
2308        }
2309
2310        mLruSeq++;
2311        final long now = SystemClock.uptimeMillis();
2312        app.lastActivityTime = now;
2313
2314        // First a quick reject: if the app is already at the position we will
2315        // put it, then there is nothing to do.
2316        if (hasActivity) {
2317            final int N = mLruProcesses.size();
2318            if (N > 0 && mLruProcesses.get(N-1) == app) {
2319                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2320                return;
2321            }
2322        } else {
2323            if (mLruProcessServiceStart > 0
2324                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2325                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2326                return;
2327            }
2328        }
2329
2330        int lrui = mLruProcesses.lastIndexOf(app);
2331
2332        if (app.persistent && lrui >= 0) {
2333            // We don't care about the position of persistent processes, as long as
2334            // they are in the list.
2335            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2336            return;
2337        }
2338
2339        /* In progress: compute new position first, so we can avoid doing work
2340           if the process is not actually going to move.  Not yet working.
2341        int addIndex;
2342        int nextIndex;
2343        boolean inActivity = false, inService = false;
2344        if (hasActivity) {
2345            // Process has activities, put it at the very tipsy-top.
2346            addIndex = mLruProcesses.size();
2347            nextIndex = mLruProcessServiceStart;
2348            inActivity = true;
2349        } else if (hasService) {
2350            // Process has services, put it at the top of the service list.
2351            addIndex = mLruProcessActivityStart;
2352            nextIndex = mLruProcessServiceStart;
2353            inActivity = true;
2354            inService = true;
2355        } else  {
2356            // Process not otherwise of interest, it goes to the top of the non-service area.
2357            addIndex = mLruProcessServiceStart;
2358            if (client != null) {
2359                int clientIndex = mLruProcesses.lastIndexOf(client);
2360                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2361                        + app);
2362                if (clientIndex >= 0 && addIndex > clientIndex) {
2363                    addIndex = clientIndex;
2364                }
2365            }
2366            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2367        }
2368
2369        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2370                + mLruProcessActivityStart + "): " + app);
2371        */
2372
2373        if (lrui >= 0) {
2374            if (lrui < mLruProcessActivityStart) {
2375                mLruProcessActivityStart--;
2376            }
2377            if (lrui < mLruProcessServiceStart) {
2378                mLruProcessServiceStart--;
2379            }
2380            /*
2381            if (addIndex > lrui) {
2382                addIndex--;
2383            }
2384            if (nextIndex > lrui) {
2385                nextIndex--;
2386            }
2387            */
2388            mLruProcesses.remove(lrui);
2389        }
2390
2391        /*
2392        mLruProcesses.add(addIndex, app);
2393        if (inActivity) {
2394            mLruProcessActivityStart++;
2395        }
2396        if (inService) {
2397            mLruProcessActivityStart++;
2398        }
2399        */
2400
2401        int nextIndex;
2402        if (hasActivity) {
2403            final int N = mLruProcesses.size();
2404            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2405                // Process doesn't have activities, but has clients with
2406                // activities...  move it up, but one below the top (the top
2407                // should always have a real activity).
2408                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2409                mLruProcesses.add(N-1, app);
2410                // To keep it from spamming the LRU list (by making a bunch of clients),
2411                // we will push down any other entries owned by the app.
2412                final int uid = app.info.uid;
2413                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2414                    ProcessRecord subProc = mLruProcesses.get(i);
2415                    if (subProc.info.uid == uid) {
2416                        // We want to push this one down the list.  If the process after
2417                        // it is for the same uid, however, don't do so, because we don't
2418                        // want them internally to be re-ordered.
2419                        if (mLruProcesses.get(i-1).info.uid != uid) {
2420                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2421                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2422                            ProcessRecord tmp = mLruProcesses.get(i);
2423                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2424                            mLruProcesses.set(i-1, tmp);
2425                            i--;
2426                        }
2427                    } else {
2428                        // A gap, we can stop here.
2429                        break;
2430                    }
2431                }
2432            } else {
2433                // Process has activities, put it at the very tipsy-top.
2434                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2435                mLruProcesses.add(app);
2436            }
2437            nextIndex = mLruProcessServiceStart;
2438        } else if (hasService) {
2439            // Process has services, put it at the top of the service list.
2440            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2441            mLruProcesses.add(mLruProcessActivityStart, app);
2442            nextIndex = mLruProcessServiceStart;
2443            mLruProcessActivityStart++;
2444        } else  {
2445            // Process not otherwise of interest, it goes to the top of the non-service area.
2446            int index = mLruProcessServiceStart;
2447            if (client != null) {
2448                // If there is a client, don't allow the process to be moved up higher
2449                // in the list than that client.
2450                int clientIndex = mLruProcesses.lastIndexOf(client);
2451                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2452                        + " when updating " + app);
2453                if (clientIndex <= lrui) {
2454                    // Don't allow the client index restriction to push it down farther in the
2455                    // list than it already is.
2456                    clientIndex = lrui;
2457                }
2458                if (clientIndex >= 0 && index > clientIndex) {
2459                    index = clientIndex;
2460                }
2461            }
2462            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2463            mLruProcesses.add(index, app);
2464            nextIndex = index-1;
2465            mLruProcessActivityStart++;
2466            mLruProcessServiceStart++;
2467        }
2468
2469        // If the app is currently using a content provider or service,
2470        // bump those processes as well.
2471        for (int j=app.connections.size()-1; j>=0; j--) {
2472            ConnectionRecord cr = app.connections.valueAt(j);
2473            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2474                    && cr.binding.service.app != null
2475                    && cr.binding.service.app.lruSeq != mLruSeq
2476                    && !cr.binding.service.app.persistent) {
2477                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2478                        "service connection", cr, app);
2479            }
2480        }
2481        for (int j=app.conProviders.size()-1; j>=0; j--) {
2482            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2483            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2484                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2485                        "provider reference", cpr, app);
2486            }
2487        }
2488    }
2489
2490    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2491        if (uid == Process.SYSTEM_UID) {
2492            // The system gets to run in any process.  If there are multiple
2493            // processes with the same uid, just pick the first (this
2494            // should never happen).
2495            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2496            if (procs == null) return null;
2497            final int N = procs.size();
2498            for (int i = 0; i < N; i++) {
2499                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2500            }
2501        }
2502        ProcessRecord proc = mProcessNames.get(processName, uid);
2503        if (false && proc != null && !keepIfLarge
2504                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2505                && proc.lastCachedPss >= 4000) {
2506            // Turn this condition on to cause killing to happen regularly, for testing.
2507            if (proc.baseProcessTracker != null) {
2508                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2509            }
2510            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2511                    + "k from cached");
2512        } else if (proc != null && !keepIfLarge
2513                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2514                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2515            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2516            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2517                if (proc.baseProcessTracker != null) {
2518                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2519                }
2520                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2521                        + "k from cached");
2522            }
2523        }
2524        return proc;
2525    }
2526
2527    void ensurePackageDexOpt(String packageName) {
2528        IPackageManager pm = AppGlobals.getPackageManager();
2529        try {
2530            if (pm.performDexOpt(packageName)) {
2531                mDidDexOpt = true;
2532            }
2533        } catch (RemoteException e) {
2534        }
2535    }
2536
2537    boolean isNextTransitionForward() {
2538        int transit = mWindowManager.getPendingAppTransition();
2539        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2540                || transit == AppTransition.TRANSIT_TASK_OPEN
2541                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2542    }
2543
2544    final ProcessRecord startProcessLocked(String processName,
2545            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2546            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2547            boolean isolated, boolean keepIfLarge) {
2548        ProcessRecord app;
2549        if (!isolated) {
2550            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2551        } else {
2552            // If this is an isolated process, it can't re-use an existing process.
2553            app = null;
2554        }
2555        // We don't have to do anything more if:
2556        // (1) There is an existing application record; and
2557        // (2) The caller doesn't think it is dead, OR there is no thread
2558        //     object attached to it so we know it couldn't have crashed; and
2559        // (3) There is a pid assigned to it, so it is either starting or
2560        //     already running.
2561        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2562                + " app=" + app + " knownToBeDead=" + knownToBeDead
2563                + " thread=" + (app != null ? app.thread : null)
2564                + " pid=" + (app != null ? app.pid : -1));
2565        if (app != null && app.pid > 0) {
2566            if (!knownToBeDead || app.thread == null) {
2567                // We already have the app running, or are waiting for it to
2568                // come up (we have a pid but not yet its thread), so keep it.
2569                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2570                // If this is a new package in the process, add the package to the list
2571                app.addPackage(info.packageName, mProcessStats);
2572                return app;
2573            }
2574
2575            // An application record is attached to a previous process,
2576            // clean it up now.
2577            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2578            handleAppDiedLocked(app, true, true);
2579        }
2580
2581        String hostingNameStr = hostingName != null
2582                ? hostingName.flattenToShortString() : null;
2583
2584        if (!isolated) {
2585            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2586                // If we are in the background, then check to see if this process
2587                // is bad.  If so, we will just silently fail.
2588                if (mBadProcesses.get(info.processName, info.uid) != null) {
2589                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2590                            + "/" + info.processName);
2591                    return null;
2592                }
2593            } else {
2594                // When the user is explicitly starting a process, then clear its
2595                // crash count so that we won't make it bad until they see at
2596                // least one crash dialog again, and make the process good again
2597                // if it had been bad.
2598                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2599                        + "/" + info.processName);
2600                mProcessCrashTimes.remove(info.processName, info.uid);
2601                if (mBadProcesses.get(info.processName, info.uid) != null) {
2602                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2603                            UserHandle.getUserId(info.uid), info.uid,
2604                            info.processName);
2605                    mBadProcesses.remove(info.processName, info.uid);
2606                    if (app != null) {
2607                        app.bad = false;
2608                    }
2609                }
2610            }
2611        }
2612
2613        if (app == null) {
2614            app = newProcessRecordLocked(info, processName, isolated);
2615            if (app == null) {
2616                Slog.w(TAG, "Failed making new process record for "
2617                        + processName + "/" + info.uid + " isolated=" + isolated);
2618                return null;
2619            }
2620            mProcessNames.put(processName, app.uid, app);
2621            if (isolated) {
2622                mIsolatedProcesses.put(app.uid, app);
2623            }
2624        } else {
2625            // If this is a new package in the process, add the package to the list
2626            app.addPackage(info.packageName, mProcessStats);
2627        }
2628
2629        // If the system is not ready yet, then hold off on starting this
2630        // process until it is.
2631        if (!mProcessesReady
2632                && !isAllowedWhileBooting(info)
2633                && !allowWhileBooting) {
2634            if (!mProcessesOnHold.contains(app)) {
2635                mProcessesOnHold.add(app);
2636            }
2637            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2638            return app;
2639        }
2640
2641        startProcessLocked(app, hostingType, hostingNameStr);
2642        return (app.pid != 0) ? app : null;
2643    }
2644
2645    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2646        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2647    }
2648
2649    private final void startProcessLocked(ProcessRecord app,
2650            String hostingType, String hostingNameStr) {
2651        if (app.pid > 0 && app.pid != MY_PID) {
2652            synchronized (mPidsSelfLocked) {
2653                mPidsSelfLocked.remove(app.pid);
2654                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2655            }
2656            app.setPid(0);
2657        }
2658
2659        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2660                "startProcessLocked removing on hold: " + app);
2661        mProcessesOnHold.remove(app);
2662
2663        updateCpuStats();
2664
2665        try {
2666            int uid = app.uid;
2667
2668            int[] gids = null;
2669            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2670            if (!app.isolated) {
2671                int[] permGids = null;
2672                try {
2673                    final PackageManager pm = mContext.getPackageManager();
2674                    permGids = pm.getPackageGids(app.info.packageName);
2675
2676                    if (Environment.isExternalStorageEmulated()) {
2677                        if (pm.checkPermission(
2678                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2679                                app.info.packageName) == PERMISSION_GRANTED) {
2680                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2681                        } else {
2682                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2683                        }
2684                    }
2685                } catch (PackageManager.NameNotFoundException e) {
2686                    Slog.w(TAG, "Unable to retrieve gids", e);
2687                }
2688
2689                /*
2690                 * Add shared application GID so applications can share some
2691                 * resources like shared libraries
2692                 */
2693                if (permGids == null) {
2694                    gids = new int[1];
2695                } else {
2696                    gids = new int[permGids.length + 1];
2697                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2698                }
2699                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2700            }
2701            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2702                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2703                        && mTopComponent != null
2704                        && app.processName.equals(mTopComponent.getPackageName())) {
2705                    uid = 0;
2706                }
2707                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2708                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2709                    uid = 0;
2710                }
2711            }
2712            int debugFlags = 0;
2713            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2714                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2715                // Also turn on CheckJNI for debuggable apps. It's quite
2716                // awkward to turn on otherwise.
2717                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2718            }
2719            // Run the app in safe mode if its manifest requests so or the
2720            // system is booted in safe mode.
2721            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2722                Zygote.systemInSafeMode == true) {
2723                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2724            }
2725            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2726                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2727            }
2728            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2729                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2730            }
2731            if ("1".equals(SystemProperties.get("debug.assert"))) {
2732                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2733            }
2734
2735            // Start the process.  It will either succeed and return a result containing
2736            // the PID of the new process, or else throw a RuntimeException.
2737            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2738                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2739                    app.info.targetSdkVersion, app.info.seinfo, null);
2740
2741            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2742            synchronized (bs) {
2743                if (bs.isOnBattery()) {
2744                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2745                }
2746            }
2747
2748            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2749                    UserHandle.getUserId(uid), startResult.pid, uid,
2750                    app.processName, hostingType,
2751                    hostingNameStr != null ? hostingNameStr : "");
2752
2753            if (app.persistent) {
2754                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2755            }
2756
2757            StringBuilder buf = mStringBuilder;
2758            buf.setLength(0);
2759            buf.append("Start proc ");
2760            buf.append(app.processName);
2761            buf.append(" for ");
2762            buf.append(hostingType);
2763            if (hostingNameStr != null) {
2764                buf.append(" ");
2765                buf.append(hostingNameStr);
2766            }
2767            buf.append(": pid=");
2768            buf.append(startResult.pid);
2769            buf.append(" uid=");
2770            buf.append(uid);
2771            buf.append(" gids={");
2772            if (gids != null) {
2773                for (int gi=0; gi<gids.length; gi++) {
2774                    if (gi != 0) buf.append(", ");
2775                    buf.append(gids[gi]);
2776
2777                }
2778            }
2779            buf.append("}");
2780            Slog.i(TAG, buf.toString());
2781            app.setPid(startResult.pid);
2782            app.usingWrapper = startResult.usingWrapper;
2783            app.removed = false;
2784            synchronized (mPidsSelfLocked) {
2785                this.mPidsSelfLocked.put(startResult.pid, app);
2786                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2787                msg.obj = app;
2788                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2789                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2790            }
2791            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2792                    app.processName, app.info.uid);
2793            if (app.isolated) {
2794                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2795            }
2796        } catch (RuntimeException e) {
2797            // XXX do better error recovery.
2798            app.setPid(0);
2799            Slog.e(TAG, "Failure starting process " + app.processName, e);
2800        }
2801    }
2802
2803    void updateUsageStats(ActivityRecord component, boolean resumed) {
2804        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2805        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2806        if (resumed) {
2807            mUsageStatsService.noteResumeComponent(component.realActivity);
2808            synchronized (stats) {
2809                stats.noteActivityResumedLocked(component.app.uid);
2810            }
2811        } else {
2812            mUsageStatsService.notePauseComponent(component.realActivity);
2813            synchronized (stats) {
2814                stats.noteActivityPausedLocked(component.app.uid);
2815            }
2816        }
2817    }
2818
2819    Intent getHomeIntent() {
2820        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2821        intent.setComponent(mTopComponent);
2822        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2823            intent.addCategory(Intent.CATEGORY_HOME);
2824        }
2825        return intent;
2826    }
2827
2828    boolean startHomeActivityLocked(int userId) {
2829        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2830                && mTopAction == null) {
2831            // We are running in factory test mode, but unable to find
2832            // the factory test app, so just sit around displaying the
2833            // error message and don't try to start anything.
2834            return false;
2835        }
2836        Intent intent = getHomeIntent();
2837        ActivityInfo aInfo =
2838            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2839        if (aInfo != null) {
2840            intent.setComponent(new ComponentName(
2841                    aInfo.applicationInfo.packageName, aInfo.name));
2842            // Don't do this if the home app is currently being
2843            // instrumented.
2844            aInfo = new ActivityInfo(aInfo);
2845            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2846            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2847                    aInfo.applicationInfo.uid, true);
2848            if (app == null || app.instrumentationClass == null) {
2849                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2850                mStackSupervisor.startHomeActivity(intent, aInfo);
2851            }
2852        }
2853
2854        return true;
2855    }
2856
2857    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2858        ActivityInfo ai = null;
2859        ComponentName comp = intent.getComponent();
2860        try {
2861            if (comp != null) {
2862                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2863            } else {
2864                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2865                        intent,
2866                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2867                            flags, userId);
2868
2869                if (info != null) {
2870                    ai = info.activityInfo;
2871                }
2872            }
2873        } catch (RemoteException e) {
2874            // ignore
2875        }
2876
2877        return ai;
2878    }
2879
2880    /**
2881     * Starts the "new version setup screen" if appropriate.
2882     */
2883    void startSetupActivityLocked() {
2884        // Only do this once per boot.
2885        if (mCheckedForSetup) {
2886            return;
2887        }
2888
2889        // We will show this screen if the current one is a different
2890        // version than the last one shown, and we are not running in
2891        // low-level factory test mode.
2892        final ContentResolver resolver = mContext.getContentResolver();
2893        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2894                Settings.Global.getInt(resolver,
2895                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2896            mCheckedForSetup = true;
2897
2898            // See if we should be showing the platform update setup UI.
2899            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2900            List<ResolveInfo> ris = mContext.getPackageManager()
2901                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2902
2903            // We don't allow third party apps to replace this.
2904            ResolveInfo ri = null;
2905            for (int i=0; ris != null && i<ris.size(); i++) {
2906                if ((ris.get(i).activityInfo.applicationInfo.flags
2907                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2908                    ri = ris.get(i);
2909                    break;
2910                }
2911            }
2912
2913            if (ri != null) {
2914                String vers = ri.activityInfo.metaData != null
2915                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2916                        : null;
2917                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2918                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2919                            Intent.METADATA_SETUP_VERSION);
2920                }
2921                String lastVers = Settings.Secure.getString(
2922                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2923                if (vers != null && !vers.equals(lastVers)) {
2924                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2925                    intent.setComponent(new ComponentName(
2926                            ri.activityInfo.packageName, ri.activityInfo.name));
2927                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2928                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2929                }
2930            }
2931        }
2932    }
2933
2934    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2935        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2936    }
2937
2938    void enforceNotIsolatedCaller(String caller) {
2939        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2940            throw new SecurityException("Isolated process not allowed to call " + caller);
2941        }
2942    }
2943
2944    @Override
2945    public int getFrontActivityScreenCompatMode() {
2946        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2947        synchronized (this) {
2948            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2949        }
2950    }
2951
2952    @Override
2953    public void setFrontActivityScreenCompatMode(int mode) {
2954        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2955                "setFrontActivityScreenCompatMode");
2956        synchronized (this) {
2957            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2958        }
2959    }
2960
2961    @Override
2962    public int getPackageScreenCompatMode(String packageName) {
2963        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2964        synchronized (this) {
2965            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2966        }
2967    }
2968
2969    @Override
2970    public void setPackageScreenCompatMode(String packageName, int mode) {
2971        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2972                "setPackageScreenCompatMode");
2973        synchronized (this) {
2974            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2975        }
2976    }
2977
2978    @Override
2979    public boolean getPackageAskScreenCompat(String packageName) {
2980        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2981        synchronized (this) {
2982            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2983        }
2984    }
2985
2986    @Override
2987    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2988        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2989                "setPackageAskScreenCompat");
2990        synchronized (this) {
2991            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2992        }
2993    }
2994
2995    private void dispatchProcessesChanged() {
2996        int N;
2997        synchronized (this) {
2998            N = mPendingProcessChanges.size();
2999            if (mActiveProcessChanges.length < N) {
3000                mActiveProcessChanges = new ProcessChangeItem[N];
3001            }
3002            mPendingProcessChanges.toArray(mActiveProcessChanges);
3003            mAvailProcessChanges.addAll(mPendingProcessChanges);
3004            mPendingProcessChanges.clear();
3005            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3006        }
3007
3008        int i = mProcessObservers.beginBroadcast();
3009        while (i > 0) {
3010            i--;
3011            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3012            if (observer != null) {
3013                try {
3014                    for (int j=0; j<N; j++) {
3015                        ProcessChangeItem item = mActiveProcessChanges[j];
3016                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3017                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3018                                    + item.pid + " uid=" + item.uid + ": "
3019                                    + item.foregroundActivities);
3020                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3021                                    item.foregroundActivities);
3022                        }
3023                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3024                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3025                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3026                            observer.onImportanceChanged(item.pid, item.uid,
3027                                    item.importance);
3028                        }
3029                    }
3030                } catch (RemoteException e) {
3031                }
3032            }
3033        }
3034        mProcessObservers.finishBroadcast();
3035    }
3036
3037    private void dispatchProcessDied(int pid, int uid) {
3038        int i = mProcessObservers.beginBroadcast();
3039        while (i > 0) {
3040            i--;
3041            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3042            if (observer != null) {
3043                try {
3044                    observer.onProcessDied(pid, uid);
3045                } catch (RemoteException e) {
3046                }
3047            }
3048        }
3049        mProcessObservers.finishBroadcast();
3050    }
3051
3052    final void doPendingActivityLaunchesLocked(boolean doResume) {
3053        final int N = mPendingActivityLaunches.size();
3054        if (N <= 0) {
3055            return;
3056        }
3057        for (int i=0; i<N; i++) {
3058            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3059            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3060                    doResume && i == (N-1), null);
3061        }
3062        mPendingActivityLaunches.clear();
3063    }
3064
3065    @Override
3066    public final int startActivity(IApplicationThread caller, String callingPackage,
3067            Intent intent, String resolvedType, IBinder resultTo,
3068            String resultWho, int requestCode, int startFlags,
3069            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3070        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3071                resultWho, requestCode,
3072                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3073    }
3074
3075    @Override
3076    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3077            Intent intent, String resolvedType, IBinder resultTo,
3078            String resultWho, int requestCode, int startFlags,
3079            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3080        enforceNotIsolatedCaller("startActivity");
3081        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3082                false, true, "startActivity", null);
3083        // TODO: Switch to user app stacks here.
3084        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3085                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3086                null, null, options, userId, null);
3087    }
3088
3089    @Override
3090    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3091            Intent intent, String resolvedType, IBinder resultTo,
3092            String resultWho, int requestCode, int startFlags, String profileFile,
3093            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3094        enforceNotIsolatedCaller("startActivityAndWait");
3095        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3096                false, true, "startActivityAndWait", null);
3097        WaitResult res = new WaitResult();
3098        // TODO: Switch to user app stacks here.
3099        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3100                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3101                res, null, options, UserHandle.getCallingUserId(), null);
3102        return res;
3103    }
3104
3105    @Override
3106    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3107            Intent intent, String resolvedType, IBinder resultTo,
3108            String resultWho, int requestCode, int startFlags, Configuration config,
3109            Bundle options, int userId) {
3110        enforceNotIsolatedCaller("startActivityWithConfig");
3111        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3112                false, true, "startActivityWithConfig", null);
3113        // TODO: Switch to user app stacks here.
3114        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3115                resolvedType, resultTo, resultWho, requestCode, startFlags,
3116                null, null, null, config, options, userId, null);
3117        return ret;
3118    }
3119
3120    @Override
3121    public int startActivityIntentSender(IApplicationThread caller,
3122            IntentSender intent, Intent fillInIntent, String resolvedType,
3123            IBinder resultTo, String resultWho, int requestCode,
3124            int flagsMask, int flagsValues, Bundle options) {
3125        enforceNotIsolatedCaller("startActivityIntentSender");
3126        // Refuse possible leaked file descriptors
3127        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3128            throw new IllegalArgumentException("File descriptors passed in Intent");
3129        }
3130
3131        IIntentSender sender = intent.getTarget();
3132        if (!(sender instanceof PendingIntentRecord)) {
3133            throw new IllegalArgumentException("Bad PendingIntent object");
3134        }
3135
3136        PendingIntentRecord pir = (PendingIntentRecord)sender;
3137
3138        synchronized (this) {
3139            // If this is coming from the currently resumed activity, it is
3140            // effectively saying that app switches are allowed at this point.
3141            final ActivityStack stack = getFocusedStack();
3142            if (stack.mResumedActivity != null &&
3143                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3144                mAppSwitchesAllowedTime = 0;
3145            }
3146        }
3147        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3148                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3149        return ret;
3150    }
3151
3152    @Override
3153    public boolean startNextMatchingActivity(IBinder callingActivity,
3154            Intent intent, Bundle options) {
3155        // Refuse possible leaked file descriptors
3156        if (intent != null && intent.hasFileDescriptors() == true) {
3157            throw new IllegalArgumentException("File descriptors passed in Intent");
3158        }
3159
3160        synchronized (this) {
3161            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3162            if (r == null) {
3163                ActivityOptions.abort(options);
3164                return false;
3165            }
3166            if (r.app == null || r.app.thread == null) {
3167                // The caller is not running...  d'oh!
3168                ActivityOptions.abort(options);
3169                return false;
3170            }
3171            intent = new Intent(intent);
3172            // The caller is not allowed to change the data.
3173            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3174            // And we are resetting to find the next component...
3175            intent.setComponent(null);
3176
3177            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3178
3179            ActivityInfo aInfo = null;
3180            try {
3181                List<ResolveInfo> resolves =
3182                    AppGlobals.getPackageManager().queryIntentActivities(
3183                            intent, r.resolvedType,
3184                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3185                            UserHandle.getCallingUserId());
3186
3187                // Look for the original activity in the list...
3188                final int N = resolves != null ? resolves.size() : 0;
3189                for (int i=0; i<N; i++) {
3190                    ResolveInfo rInfo = resolves.get(i);
3191                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3192                            && rInfo.activityInfo.name.equals(r.info.name)) {
3193                        // We found the current one...  the next matching is
3194                        // after it.
3195                        i++;
3196                        if (i<N) {
3197                            aInfo = resolves.get(i).activityInfo;
3198                        }
3199                        if (debug) {
3200                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3201                                    + "/" + r.info.name);
3202                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3203                                    + "/" + aInfo.name);
3204                        }
3205                        break;
3206                    }
3207                }
3208            } catch (RemoteException e) {
3209            }
3210
3211            if (aInfo == null) {
3212                // Nobody who is next!
3213                ActivityOptions.abort(options);
3214                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3215                return false;
3216            }
3217
3218            intent.setComponent(new ComponentName(
3219                    aInfo.applicationInfo.packageName, aInfo.name));
3220            intent.setFlags(intent.getFlags()&~(
3221                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3222                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3223                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3224                    Intent.FLAG_ACTIVITY_NEW_TASK));
3225
3226            // Okay now we need to start the new activity, replacing the
3227            // currently running activity.  This is a little tricky because
3228            // we want to start the new one as if the current one is finished,
3229            // but not finish the current one first so that there is no flicker.
3230            // And thus...
3231            final boolean wasFinishing = r.finishing;
3232            r.finishing = true;
3233
3234            // Propagate reply information over to the new activity.
3235            final ActivityRecord resultTo = r.resultTo;
3236            final String resultWho = r.resultWho;
3237            final int requestCode = r.requestCode;
3238            r.resultTo = null;
3239            if (resultTo != null) {
3240                resultTo.removeResultsLocked(r, resultWho, requestCode);
3241            }
3242
3243            final long origId = Binder.clearCallingIdentity();
3244            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3245                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3246                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3247                    options, false, null, null);
3248            Binder.restoreCallingIdentity(origId);
3249
3250            r.finishing = wasFinishing;
3251            if (res != ActivityManager.START_SUCCESS) {
3252                return false;
3253            }
3254            return true;
3255        }
3256    }
3257
3258    final int startActivityInPackage(int uid, String callingPackage,
3259            Intent intent, String resolvedType, IBinder resultTo,
3260            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3261                    IActivityContainer container) {
3262
3263        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3264                false, true, "startActivityInPackage", null);
3265
3266        // TODO: Switch to user app stacks here.
3267        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3268                resultTo, resultWho, requestCode, startFlags,
3269                null, null, null, null, options, userId, container);
3270        return ret;
3271    }
3272
3273    @Override
3274    public final int startActivities(IApplicationThread caller, String callingPackage,
3275            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3276            int userId) {
3277        enforceNotIsolatedCaller("startActivities");
3278        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3279                false, true, "startActivity", null);
3280        // TODO: Switch to user app stacks here.
3281        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3282                resolvedTypes, resultTo, options, userId);
3283        return ret;
3284    }
3285
3286    final int startActivitiesInPackage(int uid, String callingPackage,
3287            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3288            Bundle options, int userId) {
3289
3290        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3291                false, true, "startActivityInPackage", null);
3292        // TODO: Switch to user app stacks here.
3293        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3294                resultTo, options, userId);
3295        return ret;
3296    }
3297
3298    final void addRecentTaskLocked(TaskRecord task) {
3299        int N = mRecentTasks.size();
3300        // Quick case: check if the top-most recent task is the same.
3301        if (N > 0 && mRecentTasks.get(0) == task) {
3302            return;
3303        }
3304        // Remove any existing entries that are the same kind of task.
3305        for (int i=0; i<N; i++) {
3306            TaskRecord tr = mRecentTasks.get(i);
3307            if (task.userId == tr.userId
3308                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3309                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3310                tr.disposeThumbnail();
3311                mRecentTasks.remove(i);
3312                i--;
3313                N--;
3314                if (task.intent == null) {
3315                    // If the new recent task we are adding is not fully
3316                    // specified, then replace it with the existing recent task.
3317                    task = tr;
3318                }
3319            }
3320        }
3321        if (N >= MAX_RECENT_TASKS) {
3322            mRecentTasks.remove(N-1).disposeThumbnail();
3323        }
3324        mRecentTasks.add(0, task);
3325    }
3326
3327    @Override
3328    public void reportActivityFullyDrawn(IBinder token) {
3329        synchronized (this) {
3330            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3331            if (r == null) {
3332                return;
3333            }
3334            r.reportFullyDrawnLocked();
3335        }
3336    }
3337
3338    @Override
3339    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3340        synchronized (this) {
3341            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3342            if (r == null) {
3343                return;
3344            }
3345            final long origId = Binder.clearCallingIdentity();
3346            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3347            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3348                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3349            if (config != null) {
3350                r.frozenBeforeDestroy = true;
3351                if (!updateConfigurationLocked(config, r, false, false)) {
3352                    mStackSupervisor.resumeTopActivitiesLocked();
3353                }
3354            }
3355            Binder.restoreCallingIdentity(origId);
3356        }
3357    }
3358
3359    @Override
3360    public int getRequestedOrientation(IBinder token) {
3361        synchronized (this) {
3362            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3363            if (r == null) {
3364                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3365            }
3366            return mWindowManager.getAppOrientation(r.appToken);
3367        }
3368    }
3369
3370    /**
3371     * This is the internal entry point for handling Activity.finish().
3372     *
3373     * @param token The Binder token referencing the Activity we want to finish.
3374     * @param resultCode Result code, if any, from this Activity.
3375     * @param resultData Result data (Intent), if any, from this Activity.
3376     *
3377     * @return Returns true if the activity successfully finished, or false if it is still running.
3378     */
3379    @Override
3380    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3381        // Refuse possible leaked file descriptors
3382        if (resultData != null && resultData.hasFileDescriptors() == true) {
3383            throw new IllegalArgumentException("File descriptors passed in Intent");
3384        }
3385
3386        synchronized(this) {
3387            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3388            if (r == null) {
3389                return true;
3390            }
3391            if (mController != null) {
3392                // Find the first activity that is not finishing.
3393                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3394                if (next != null) {
3395                    // ask watcher if this is allowed
3396                    boolean resumeOK = true;
3397                    try {
3398                        resumeOK = mController.activityResuming(next.packageName);
3399                    } catch (RemoteException e) {
3400                        mController = null;
3401                        Watchdog.getInstance().setActivityController(null);
3402                    }
3403
3404                    if (!resumeOK) {
3405                        return false;
3406                    }
3407                }
3408            }
3409            final long origId = Binder.clearCallingIdentity();
3410            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3411                    resultData, "app-request", true);
3412            Binder.restoreCallingIdentity(origId);
3413            return res;
3414        }
3415    }
3416
3417    @Override
3418    public final void finishHeavyWeightApp() {
3419        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3420                != PackageManager.PERMISSION_GRANTED) {
3421            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3422                    + Binder.getCallingPid()
3423                    + ", uid=" + Binder.getCallingUid()
3424                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3425            Slog.w(TAG, msg);
3426            throw new SecurityException(msg);
3427        }
3428
3429        synchronized(this) {
3430            if (mHeavyWeightProcess == null) {
3431                return;
3432            }
3433
3434            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3435                    mHeavyWeightProcess.activities);
3436            for (int i=0; i<activities.size(); i++) {
3437                ActivityRecord r = activities.get(i);
3438                if (!r.finishing) {
3439                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3440                            null, "finish-heavy", true);
3441                }
3442            }
3443
3444            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3445                    mHeavyWeightProcess.userId, 0));
3446            mHeavyWeightProcess = null;
3447        }
3448    }
3449
3450    @Override
3451    public void crashApplication(int uid, int initialPid, String packageName,
3452            String message) {
3453        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3454                != PackageManager.PERMISSION_GRANTED) {
3455            String msg = "Permission Denial: crashApplication() from pid="
3456                    + Binder.getCallingPid()
3457                    + ", uid=" + Binder.getCallingUid()
3458                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3459            Slog.w(TAG, msg);
3460            throw new SecurityException(msg);
3461        }
3462
3463        synchronized(this) {
3464            ProcessRecord proc = null;
3465
3466            // Figure out which process to kill.  We don't trust that initialPid
3467            // still has any relation to current pids, so must scan through the
3468            // list.
3469            synchronized (mPidsSelfLocked) {
3470                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3471                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3472                    if (p.uid != uid) {
3473                        continue;
3474                    }
3475                    if (p.pid == initialPid) {
3476                        proc = p;
3477                        break;
3478                    }
3479                    if (p.pkgList.containsKey(packageName)) {
3480                        proc = p;
3481                    }
3482                }
3483            }
3484
3485            if (proc == null) {
3486                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3487                        + " initialPid=" + initialPid
3488                        + " packageName=" + packageName);
3489                return;
3490            }
3491
3492            if (proc.thread != null) {
3493                if (proc.pid == Process.myPid()) {
3494                    Log.w(TAG, "crashApplication: trying to crash self!");
3495                    return;
3496                }
3497                long ident = Binder.clearCallingIdentity();
3498                try {
3499                    proc.thread.scheduleCrash(message);
3500                } catch (RemoteException e) {
3501                }
3502                Binder.restoreCallingIdentity(ident);
3503            }
3504        }
3505    }
3506
3507    @Override
3508    public final void finishSubActivity(IBinder token, String resultWho,
3509            int requestCode) {
3510        synchronized(this) {
3511            final long origId = Binder.clearCallingIdentity();
3512            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3513            if (r != null) {
3514                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3515            }
3516            Binder.restoreCallingIdentity(origId);
3517        }
3518    }
3519
3520    @Override
3521    public boolean finishActivityAffinity(IBinder token) {
3522        synchronized(this) {
3523            final long origId = Binder.clearCallingIdentity();
3524            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3525            boolean res = false;
3526            if (r != null) {
3527                res = r.task.stack.finishActivityAffinityLocked(r);
3528            }
3529            Binder.restoreCallingIdentity(origId);
3530            return res;
3531        }
3532    }
3533
3534    @Override
3535    public boolean willActivityBeVisible(IBinder token) {
3536        synchronized(this) {
3537            ActivityStack stack = ActivityRecord.getStackLocked(token);
3538            if (stack != null) {
3539                return stack.willActivityBeVisibleLocked(token);
3540            }
3541            return false;
3542        }
3543    }
3544
3545    @Override
3546    public void overridePendingTransition(IBinder token, String packageName,
3547            int enterAnim, int exitAnim) {
3548        synchronized(this) {
3549            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3550            if (self == null) {
3551                return;
3552            }
3553
3554            final long origId = Binder.clearCallingIdentity();
3555
3556            if (self.state == ActivityState.RESUMED
3557                    || self.state == ActivityState.PAUSING) {
3558                mWindowManager.overridePendingAppTransition(packageName,
3559                        enterAnim, exitAnim, null);
3560            }
3561
3562            Binder.restoreCallingIdentity(origId);
3563        }
3564    }
3565
3566    /**
3567     * Main function for removing an existing process from the activity manager
3568     * as a result of that process going away.  Clears out all connections
3569     * to the process.
3570     */
3571    private final void handleAppDiedLocked(ProcessRecord app,
3572            boolean restarting, boolean allowRestart) {
3573        int pid = app.pid;
3574        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3575        if (!restarting) {
3576            removeLruProcessLocked(app);
3577            if (pid > 0) {
3578                ProcessList.remove(pid);
3579            }
3580        }
3581
3582        if (mProfileProc == app) {
3583            clearProfilerLocked();
3584        }
3585
3586        // Remove this application's activities from active lists.
3587        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3588
3589        app.activities.clear();
3590
3591        if (app.instrumentationClass != null) {
3592            Slog.w(TAG, "Crash of app " + app.processName
3593                  + " running instrumentation " + app.instrumentationClass);
3594            Bundle info = new Bundle();
3595            info.putString("shortMsg", "Process crashed.");
3596            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3597        }
3598
3599        if (!restarting) {
3600            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3601                // If there was nothing to resume, and we are not already
3602                // restarting this process, but there is a visible activity that
3603                // is hosted by the process...  then make sure all visible
3604                // activities are running, taking care of restarting this
3605                // process.
3606                if (hasVisibleActivities) {
3607                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3608                }
3609            }
3610        }
3611    }
3612
3613    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3614        IBinder threadBinder = thread.asBinder();
3615        // Find the application record.
3616        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3617            ProcessRecord rec = mLruProcesses.get(i);
3618            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3619                return i;
3620            }
3621        }
3622        return -1;
3623    }
3624
3625    final ProcessRecord getRecordForAppLocked(
3626            IApplicationThread thread) {
3627        if (thread == null) {
3628            return null;
3629        }
3630
3631        int appIndex = getLRURecordIndexForAppLocked(thread);
3632        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3633    }
3634
3635    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3636        // If there are no longer any background processes running,
3637        // and the app that died was not running instrumentation,
3638        // then tell everyone we are now low on memory.
3639        boolean haveBg = false;
3640        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3641            ProcessRecord rec = mLruProcesses.get(i);
3642            if (rec.thread != null
3643                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3644                haveBg = true;
3645                break;
3646            }
3647        }
3648
3649        if (!haveBg) {
3650            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3651            if (doReport) {
3652                long now = SystemClock.uptimeMillis();
3653                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3654                    doReport = false;
3655                } else {
3656                    mLastMemUsageReportTime = now;
3657                }
3658            }
3659            final ArrayList<ProcessMemInfo> memInfos
3660                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3661            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3662            long now = SystemClock.uptimeMillis();
3663            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3664                ProcessRecord rec = mLruProcesses.get(i);
3665                if (rec == dyingProc || rec.thread == null) {
3666                    continue;
3667                }
3668                if (doReport) {
3669                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3670                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3671                }
3672                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3673                    // The low memory report is overriding any current
3674                    // state for a GC request.  Make sure to do
3675                    // heavy/important/visible/foreground processes first.
3676                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3677                        rec.lastRequestedGc = 0;
3678                    } else {
3679                        rec.lastRequestedGc = rec.lastLowMemory;
3680                    }
3681                    rec.reportLowMemory = true;
3682                    rec.lastLowMemory = now;
3683                    mProcessesToGc.remove(rec);
3684                    addProcessToGcListLocked(rec);
3685                }
3686            }
3687            if (doReport) {
3688                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3689                mHandler.sendMessage(msg);
3690            }
3691            scheduleAppGcsLocked();
3692        }
3693    }
3694
3695    final void appDiedLocked(ProcessRecord app, int pid,
3696            IApplicationThread thread) {
3697
3698        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3699        synchronized (stats) {
3700            stats.noteProcessDiedLocked(app.info.uid, pid);
3701        }
3702
3703        // Clean up already done if the process has been re-started.
3704        if (app.pid == pid && app.thread != null &&
3705                app.thread.asBinder() == thread.asBinder()) {
3706            boolean doLowMem = app.instrumentationClass == null;
3707            boolean doOomAdj = doLowMem;
3708            if (!app.killedByAm) {
3709                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3710                        + ") has died.");
3711                mAllowLowerMemLevel = true;
3712            } else {
3713                // Note that we always want to do oom adj to update our state with the
3714                // new number of procs.
3715                mAllowLowerMemLevel = false;
3716                doLowMem = false;
3717            }
3718            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3719            if (DEBUG_CLEANUP) Slog.v(
3720                TAG, "Dying app: " + app + ", pid: " + pid
3721                + ", thread: " + thread.asBinder());
3722            handleAppDiedLocked(app, false, true);
3723
3724            if (doOomAdj) {
3725                updateOomAdjLocked();
3726            }
3727            if (doLowMem) {
3728                doLowMemReportIfNeededLocked(app);
3729            }
3730        } else if (app.pid != pid) {
3731            // A new process has already been started.
3732            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3733                    + ") has died and restarted (pid " + app.pid + ").");
3734            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3735        } else if (DEBUG_PROCESSES) {
3736            Slog.d(TAG, "Received spurious death notification for thread "
3737                    + thread.asBinder());
3738        }
3739    }
3740
3741    /**
3742     * If a stack trace dump file is configured, dump process stack traces.
3743     * @param clearTraces causes the dump file to be erased prior to the new
3744     *    traces being written, if true; when false, the new traces will be
3745     *    appended to any existing file content.
3746     * @param firstPids of dalvik VM processes to dump stack traces for first
3747     * @param lastPids of dalvik VM processes to dump stack traces for last
3748     * @param nativeProcs optional list of native process names to dump stack crawls
3749     * @return file containing stack traces, or null if no dump file is configured
3750     */
3751    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3752            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3753        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3754        if (tracesPath == null || tracesPath.length() == 0) {
3755            return null;
3756        }
3757
3758        File tracesFile = new File(tracesPath);
3759        try {
3760            File tracesDir = tracesFile.getParentFile();
3761            if (!tracesDir.exists()) {
3762                tracesFile.mkdirs();
3763                if (!SELinux.restorecon(tracesDir)) {
3764                    return null;
3765                }
3766            }
3767            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3768
3769            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3770            tracesFile.createNewFile();
3771            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3772        } catch (IOException e) {
3773            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3774            return null;
3775        }
3776
3777        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3778        return tracesFile;
3779    }
3780
3781    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3782            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3783        // Use a FileObserver to detect when traces finish writing.
3784        // The order of traces is considered important to maintain for legibility.
3785        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3786            @Override
3787            public synchronized void onEvent(int event, String path) { notify(); }
3788        };
3789
3790        try {
3791            observer.startWatching();
3792
3793            // First collect all of the stacks of the most important pids.
3794            if (firstPids != null) {
3795                try {
3796                    int num = firstPids.size();
3797                    for (int i = 0; i < num; i++) {
3798                        synchronized (observer) {
3799                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3800                            observer.wait(200);  // Wait for write-close, give up after 200msec
3801                        }
3802                    }
3803                } catch (InterruptedException e) {
3804                    Log.wtf(TAG, e);
3805                }
3806            }
3807
3808            // Next collect the stacks of the native pids
3809            if (nativeProcs != null) {
3810                int[] pids = Process.getPidsForCommands(nativeProcs);
3811                if (pids != null) {
3812                    for (int pid : pids) {
3813                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3814                    }
3815                }
3816            }
3817
3818            // Lastly, measure CPU usage.
3819            if (processCpuTracker != null) {
3820                processCpuTracker.init();
3821                System.gc();
3822                processCpuTracker.update();
3823                try {
3824                    synchronized (processCpuTracker) {
3825                        processCpuTracker.wait(500); // measure over 1/2 second.
3826                    }
3827                } catch (InterruptedException e) {
3828                }
3829                processCpuTracker.update();
3830
3831                // We'll take the stack crawls of just the top apps using CPU.
3832                final int N = processCpuTracker.countWorkingStats();
3833                int numProcs = 0;
3834                for (int i=0; i<N && numProcs<5; i++) {
3835                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3836                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3837                        numProcs++;
3838                        try {
3839                            synchronized (observer) {
3840                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3841                                observer.wait(200);  // Wait for write-close, give up after 200msec
3842                            }
3843                        } catch (InterruptedException e) {
3844                            Log.wtf(TAG, e);
3845                        }
3846
3847                    }
3848                }
3849            }
3850        } finally {
3851            observer.stopWatching();
3852        }
3853    }
3854
3855    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3856        if (true || IS_USER_BUILD) {
3857            return;
3858        }
3859        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3860        if (tracesPath == null || tracesPath.length() == 0) {
3861            return;
3862        }
3863
3864        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3865        StrictMode.allowThreadDiskWrites();
3866        try {
3867            final File tracesFile = new File(tracesPath);
3868            final File tracesDir = tracesFile.getParentFile();
3869            final File tracesTmp = new File(tracesDir, "__tmp__");
3870            try {
3871                if (!tracesDir.exists()) {
3872                    tracesFile.mkdirs();
3873                    if (!SELinux.restorecon(tracesDir.getPath())) {
3874                        return;
3875                    }
3876                }
3877                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3878
3879                if (tracesFile.exists()) {
3880                    tracesTmp.delete();
3881                    tracesFile.renameTo(tracesTmp);
3882                }
3883                StringBuilder sb = new StringBuilder();
3884                Time tobj = new Time();
3885                tobj.set(System.currentTimeMillis());
3886                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3887                sb.append(": ");
3888                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3889                sb.append(" since ");
3890                sb.append(msg);
3891                FileOutputStream fos = new FileOutputStream(tracesFile);
3892                fos.write(sb.toString().getBytes());
3893                if (app == null) {
3894                    fos.write("\n*** No application process!".getBytes());
3895                }
3896                fos.close();
3897                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3898            } catch (IOException e) {
3899                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3900                return;
3901            }
3902
3903            if (app != null) {
3904                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3905                firstPids.add(app.pid);
3906                dumpStackTraces(tracesPath, firstPids, null, null, null);
3907            }
3908
3909            File lastTracesFile = null;
3910            File curTracesFile = null;
3911            for (int i=9; i>=0; i--) {
3912                String name = String.format(Locale.US, "slow%02d.txt", i);
3913                curTracesFile = new File(tracesDir, name);
3914                if (curTracesFile.exists()) {
3915                    if (lastTracesFile != null) {
3916                        curTracesFile.renameTo(lastTracesFile);
3917                    } else {
3918                        curTracesFile.delete();
3919                    }
3920                }
3921                lastTracesFile = curTracesFile;
3922            }
3923            tracesFile.renameTo(curTracesFile);
3924            if (tracesTmp.exists()) {
3925                tracesTmp.renameTo(tracesFile);
3926            }
3927        } finally {
3928            StrictMode.setThreadPolicy(oldPolicy);
3929        }
3930    }
3931
3932    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3933            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3934        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3935        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3936
3937        if (mController != null) {
3938            try {
3939                // 0 == continue, -1 = kill process immediately
3940                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3941                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3942            } catch (RemoteException e) {
3943                mController = null;
3944                Watchdog.getInstance().setActivityController(null);
3945            }
3946        }
3947
3948        long anrTime = SystemClock.uptimeMillis();
3949        if (MONITOR_CPU_USAGE) {
3950            updateCpuStatsNow();
3951        }
3952
3953        synchronized (this) {
3954            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3955            if (mShuttingDown) {
3956                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3957                return;
3958            } else if (app.notResponding) {
3959                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3960                return;
3961            } else if (app.crashing) {
3962                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3963                return;
3964            }
3965
3966            // In case we come through here for the same app before completing
3967            // this one, mark as anring now so we will bail out.
3968            app.notResponding = true;
3969
3970            // Log the ANR to the event log.
3971            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3972                    app.processName, app.info.flags, annotation);
3973
3974            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3975            firstPids.add(app.pid);
3976
3977            int parentPid = app.pid;
3978            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3979            if (parentPid != app.pid) firstPids.add(parentPid);
3980
3981            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3982
3983            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3984                ProcessRecord r = mLruProcesses.get(i);
3985                if (r != null && r.thread != null) {
3986                    int pid = r.pid;
3987                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3988                        if (r.persistent) {
3989                            firstPids.add(pid);
3990                        } else {
3991                            lastPids.put(pid, Boolean.TRUE);
3992                        }
3993                    }
3994                }
3995            }
3996        }
3997
3998        // Log the ANR to the main log.
3999        StringBuilder info = new StringBuilder();
4000        info.setLength(0);
4001        info.append("ANR in ").append(app.processName);
4002        if (activity != null && activity.shortComponentName != null) {
4003            info.append(" (").append(activity.shortComponentName).append(")");
4004        }
4005        info.append("\n");
4006        info.append("PID: ").append(app.pid).append("\n");
4007        if (annotation != null) {
4008            info.append("Reason: ").append(annotation).append("\n");
4009        }
4010        if (parent != null && parent != activity) {
4011            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4012        }
4013
4014        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4015
4016        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4017                NATIVE_STACKS_OF_INTEREST);
4018
4019        String cpuInfo = null;
4020        if (MONITOR_CPU_USAGE) {
4021            updateCpuStatsNow();
4022            synchronized (mProcessCpuThread) {
4023                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4024            }
4025            info.append(processCpuTracker.printCurrentLoad());
4026            info.append(cpuInfo);
4027        }
4028
4029        info.append(processCpuTracker.printCurrentState(anrTime));
4030
4031        Slog.e(TAG, info.toString());
4032        if (tracesFile == null) {
4033            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4034            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4035        }
4036
4037        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4038                cpuInfo, tracesFile, null);
4039
4040        if (mController != null) {
4041            try {
4042                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4043                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4044                if (res != 0) {
4045                    if (res < 0 && app.pid != MY_PID) {
4046                        Process.killProcess(app.pid);
4047                    } else {
4048                        synchronized (this) {
4049                            mServices.scheduleServiceTimeoutLocked(app);
4050                        }
4051                    }
4052                    return;
4053                }
4054            } catch (RemoteException e) {
4055                mController = null;
4056                Watchdog.getInstance().setActivityController(null);
4057            }
4058        }
4059
4060        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4061        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4062                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4063
4064        synchronized (this) {
4065            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4066                killUnneededProcessLocked(app, "background ANR");
4067                return;
4068            }
4069
4070            // Set the app's notResponding state, and look up the errorReportReceiver
4071            makeAppNotRespondingLocked(app,
4072                    activity != null ? activity.shortComponentName : null,
4073                    annotation != null ? "ANR " + annotation : "ANR",
4074                    info.toString());
4075
4076            // Bring up the infamous App Not Responding dialog
4077            Message msg = Message.obtain();
4078            HashMap<String, Object> map = new HashMap<String, Object>();
4079            msg.what = SHOW_NOT_RESPONDING_MSG;
4080            msg.obj = map;
4081            msg.arg1 = aboveSystem ? 1 : 0;
4082            map.put("app", app);
4083            if (activity != null) {
4084                map.put("activity", activity);
4085            }
4086
4087            mHandler.sendMessage(msg);
4088        }
4089    }
4090
4091    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4092        if (!mLaunchWarningShown) {
4093            mLaunchWarningShown = true;
4094            mHandler.post(new Runnable() {
4095                @Override
4096                public void run() {
4097                    synchronized (ActivityManagerService.this) {
4098                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4099                        d.show();
4100                        mHandler.postDelayed(new Runnable() {
4101                            @Override
4102                            public void run() {
4103                                synchronized (ActivityManagerService.this) {
4104                                    d.dismiss();
4105                                    mLaunchWarningShown = false;
4106                                }
4107                            }
4108                        }, 4000);
4109                    }
4110                }
4111            });
4112        }
4113    }
4114
4115    @Override
4116    public boolean clearApplicationUserData(final String packageName,
4117            final IPackageDataObserver observer, int userId) {
4118        enforceNotIsolatedCaller("clearApplicationUserData");
4119        int uid = Binder.getCallingUid();
4120        int pid = Binder.getCallingPid();
4121        userId = handleIncomingUser(pid, uid,
4122                userId, false, true, "clearApplicationUserData", null);
4123        long callingId = Binder.clearCallingIdentity();
4124        try {
4125            IPackageManager pm = AppGlobals.getPackageManager();
4126            int pkgUid = -1;
4127            synchronized(this) {
4128                try {
4129                    pkgUid = pm.getPackageUid(packageName, userId);
4130                } catch (RemoteException e) {
4131                }
4132                if (pkgUid == -1) {
4133                    Slog.w(TAG, "Invalid packageName: " + packageName);
4134                    if (observer != null) {
4135                        try {
4136                            observer.onRemoveCompleted(packageName, false);
4137                        } catch (RemoteException e) {
4138                            Slog.i(TAG, "Observer no longer exists.");
4139                        }
4140                    }
4141                    return false;
4142                }
4143                if (uid == pkgUid || checkComponentPermission(
4144                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4145                        pid, uid, -1, true)
4146                        == PackageManager.PERMISSION_GRANTED) {
4147                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4148                } else {
4149                    throw new SecurityException("PID " + pid + " does not have permission "
4150                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4151                                    + " of package " + packageName);
4152                }
4153            }
4154
4155            try {
4156                // Clear application user data
4157                pm.clearApplicationUserData(packageName, observer, userId);
4158
4159                // Remove all permissions granted from/to this package
4160                removeUriPermissionsForPackageLocked(packageName, userId, true);
4161
4162                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4163                        Uri.fromParts("package", packageName, null));
4164                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4165                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4166                        null, null, 0, null, null, null, false, false, userId);
4167            } catch (RemoteException e) {
4168            }
4169        } finally {
4170            Binder.restoreCallingIdentity(callingId);
4171        }
4172        return true;
4173    }
4174
4175    @Override
4176    public void killBackgroundProcesses(final String packageName, int userId) {
4177        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4178                != PackageManager.PERMISSION_GRANTED &&
4179                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4180                        != PackageManager.PERMISSION_GRANTED) {
4181            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4182                    + Binder.getCallingPid()
4183                    + ", uid=" + Binder.getCallingUid()
4184                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4185            Slog.w(TAG, msg);
4186            throw new SecurityException(msg);
4187        }
4188
4189        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4190                userId, true, true, "killBackgroundProcesses", null);
4191        long callingId = Binder.clearCallingIdentity();
4192        try {
4193            IPackageManager pm = AppGlobals.getPackageManager();
4194            synchronized(this) {
4195                int appId = -1;
4196                try {
4197                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4198                } catch (RemoteException e) {
4199                }
4200                if (appId == -1) {
4201                    Slog.w(TAG, "Invalid packageName: " + packageName);
4202                    return;
4203                }
4204                killPackageProcessesLocked(packageName, appId, userId,
4205                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4206            }
4207        } finally {
4208            Binder.restoreCallingIdentity(callingId);
4209        }
4210    }
4211
4212    @Override
4213    public void killAllBackgroundProcesses() {
4214        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4215                != PackageManager.PERMISSION_GRANTED) {
4216            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4217                    + Binder.getCallingPid()
4218                    + ", uid=" + Binder.getCallingUid()
4219                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4220            Slog.w(TAG, msg);
4221            throw new SecurityException(msg);
4222        }
4223
4224        long callingId = Binder.clearCallingIdentity();
4225        try {
4226            synchronized(this) {
4227                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4228                final int NP = mProcessNames.getMap().size();
4229                for (int ip=0; ip<NP; ip++) {
4230                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4231                    final int NA = apps.size();
4232                    for (int ia=0; ia<NA; ia++) {
4233                        ProcessRecord app = apps.valueAt(ia);
4234                        if (app.persistent) {
4235                            // we don't kill persistent processes
4236                            continue;
4237                        }
4238                        if (app.removed) {
4239                            procs.add(app);
4240                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4241                            app.removed = true;
4242                            procs.add(app);
4243                        }
4244                    }
4245                }
4246
4247                int N = procs.size();
4248                for (int i=0; i<N; i++) {
4249                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4250                }
4251                mAllowLowerMemLevel = true;
4252                updateOomAdjLocked();
4253                doLowMemReportIfNeededLocked(null);
4254            }
4255        } finally {
4256            Binder.restoreCallingIdentity(callingId);
4257        }
4258    }
4259
4260    @Override
4261    public void forceStopPackage(final String packageName, int userId) {
4262        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4263                != PackageManager.PERMISSION_GRANTED) {
4264            String msg = "Permission Denial: forceStopPackage() from pid="
4265                    + Binder.getCallingPid()
4266                    + ", uid=" + Binder.getCallingUid()
4267                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4268            Slog.w(TAG, msg);
4269            throw new SecurityException(msg);
4270        }
4271        final int callingPid = Binder.getCallingPid();
4272        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4273                userId, true, true, "forceStopPackage", null);
4274        long callingId = Binder.clearCallingIdentity();
4275        try {
4276            IPackageManager pm = AppGlobals.getPackageManager();
4277            synchronized(this) {
4278                int[] users = userId == UserHandle.USER_ALL
4279                        ? getUsersLocked() : new int[] { userId };
4280                for (int user : users) {
4281                    int pkgUid = -1;
4282                    try {
4283                        pkgUid = pm.getPackageUid(packageName, user);
4284                    } catch (RemoteException e) {
4285                    }
4286                    if (pkgUid == -1) {
4287                        Slog.w(TAG, "Invalid packageName: " + packageName);
4288                        continue;
4289                    }
4290                    try {
4291                        pm.setPackageStoppedState(packageName, true, user);
4292                    } catch (RemoteException e) {
4293                    } catch (IllegalArgumentException e) {
4294                        Slog.w(TAG, "Failed trying to unstop package "
4295                                + packageName + ": " + e);
4296                    }
4297                    if (isUserRunningLocked(user, false)) {
4298                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4299                    }
4300                }
4301            }
4302        } finally {
4303            Binder.restoreCallingIdentity(callingId);
4304        }
4305    }
4306
4307    /*
4308     * The pkg name and app id have to be specified.
4309     */
4310    @Override
4311    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4312        if (pkg == null) {
4313            return;
4314        }
4315        // Make sure the uid is valid.
4316        if (appid < 0) {
4317            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4318            return;
4319        }
4320        int callerUid = Binder.getCallingUid();
4321        // Only the system server can kill an application
4322        if (callerUid == Process.SYSTEM_UID) {
4323            // Post an aysnc message to kill the application
4324            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4325            msg.arg1 = appid;
4326            msg.arg2 = 0;
4327            Bundle bundle = new Bundle();
4328            bundle.putString("pkg", pkg);
4329            bundle.putString("reason", reason);
4330            msg.obj = bundle;
4331            mHandler.sendMessage(msg);
4332        } else {
4333            throw new SecurityException(callerUid + " cannot kill pkg: " +
4334                    pkg);
4335        }
4336    }
4337
4338    @Override
4339    public void closeSystemDialogs(String reason) {
4340        enforceNotIsolatedCaller("closeSystemDialogs");
4341
4342        final int pid = Binder.getCallingPid();
4343        final int uid = Binder.getCallingUid();
4344        final long origId = Binder.clearCallingIdentity();
4345        try {
4346            synchronized (this) {
4347                // Only allow this from foreground processes, so that background
4348                // applications can't abuse it to prevent system UI from being shown.
4349                if (uid >= Process.FIRST_APPLICATION_UID) {
4350                    ProcessRecord proc;
4351                    synchronized (mPidsSelfLocked) {
4352                        proc = mPidsSelfLocked.get(pid);
4353                    }
4354                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4355                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4356                                + " from background process " + proc);
4357                        return;
4358                    }
4359                }
4360                closeSystemDialogsLocked(reason);
4361            }
4362        } finally {
4363            Binder.restoreCallingIdentity(origId);
4364        }
4365    }
4366
4367    void closeSystemDialogsLocked(String reason) {
4368        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4369        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4370                | Intent.FLAG_RECEIVER_FOREGROUND);
4371        if (reason != null) {
4372            intent.putExtra("reason", reason);
4373        }
4374        mWindowManager.closeSystemDialogs(reason);
4375
4376        mStackSupervisor.closeSystemDialogsLocked();
4377
4378        broadcastIntentLocked(null, null, intent, null,
4379                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4380                Process.SYSTEM_UID, UserHandle.USER_ALL);
4381    }
4382
4383    @Override
4384    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4385        enforceNotIsolatedCaller("getProcessMemoryInfo");
4386        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4387        for (int i=pids.length-1; i>=0; i--) {
4388            ProcessRecord proc;
4389            int oomAdj;
4390            synchronized (this) {
4391                synchronized (mPidsSelfLocked) {
4392                    proc = mPidsSelfLocked.get(pids[i]);
4393                    oomAdj = proc != null ? proc.setAdj : 0;
4394                }
4395            }
4396            infos[i] = new Debug.MemoryInfo();
4397            Debug.getMemoryInfo(pids[i], infos[i]);
4398            if (proc != null) {
4399                synchronized (this) {
4400                    if (proc.thread != null && proc.setAdj == oomAdj) {
4401                        // Record this for posterity if the process has been stable.
4402                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4403                                infos[i].getTotalUss(), false, proc.pkgList);
4404                    }
4405                }
4406            }
4407        }
4408        return infos;
4409    }
4410
4411    @Override
4412    public long[] getProcessPss(int[] pids) {
4413        enforceNotIsolatedCaller("getProcessPss");
4414        long[] pss = new long[pids.length];
4415        for (int i=pids.length-1; i>=0; i--) {
4416            ProcessRecord proc;
4417            int oomAdj;
4418            synchronized (this) {
4419                synchronized (mPidsSelfLocked) {
4420                    proc = mPidsSelfLocked.get(pids[i]);
4421                    oomAdj = proc != null ? proc.setAdj : 0;
4422                }
4423            }
4424            long[] tmpUss = new long[1];
4425            pss[i] = Debug.getPss(pids[i], tmpUss);
4426            if (proc != null) {
4427                synchronized (this) {
4428                    if (proc.thread != null && proc.setAdj == oomAdj) {
4429                        // Record this for posterity if the process has been stable.
4430                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4431                    }
4432                }
4433            }
4434        }
4435        return pss;
4436    }
4437
4438    @Override
4439    public void killApplicationProcess(String processName, int uid) {
4440        if (processName == null) {
4441            return;
4442        }
4443
4444        int callerUid = Binder.getCallingUid();
4445        // Only the system server can kill an application
4446        if (callerUid == Process.SYSTEM_UID) {
4447            synchronized (this) {
4448                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4449                if (app != null && app.thread != null) {
4450                    try {
4451                        app.thread.scheduleSuicide();
4452                    } catch (RemoteException e) {
4453                        // If the other end already died, then our work here is done.
4454                    }
4455                } else {
4456                    Slog.w(TAG, "Process/uid not found attempting kill of "
4457                            + processName + " / " + uid);
4458                }
4459            }
4460        } else {
4461            throw new SecurityException(callerUid + " cannot kill app process: " +
4462                    processName);
4463        }
4464    }
4465
4466    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4467        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4468                false, true, false, false, UserHandle.getUserId(uid), reason);
4469        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4470                Uri.fromParts("package", packageName, null));
4471        if (!mProcessesReady) {
4472            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4473                    | Intent.FLAG_RECEIVER_FOREGROUND);
4474        }
4475        intent.putExtra(Intent.EXTRA_UID, uid);
4476        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4477        broadcastIntentLocked(null, null, intent,
4478                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4479                false, false,
4480                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4481    }
4482
4483    private void forceStopUserLocked(int userId, String reason) {
4484        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4485        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4486        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4487                | Intent.FLAG_RECEIVER_FOREGROUND);
4488        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4489        broadcastIntentLocked(null, null, intent,
4490                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4491                false, false,
4492                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4493    }
4494
4495    private final boolean killPackageProcessesLocked(String packageName, int appId,
4496            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4497            boolean doit, boolean evenPersistent, String reason) {
4498        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4499
4500        // Remove all processes this package may have touched: all with the
4501        // same UID (except for the system or root user), and all whose name
4502        // matches the package name.
4503        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4504        final int NP = mProcessNames.getMap().size();
4505        for (int ip=0; ip<NP; ip++) {
4506            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4507            final int NA = apps.size();
4508            for (int ia=0; ia<NA; ia++) {
4509                ProcessRecord app = apps.valueAt(ia);
4510                if (app.persistent && !evenPersistent) {
4511                    // we don't kill persistent processes
4512                    continue;
4513                }
4514                if (app.removed) {
4515                    if (doit) {
4516                        procs.add(app);
4517                    }
4518                    continue;
4519                }
4520
4521                // Skip process if it doesn't meet our oom adj requirement.
4522                if (app.setAdj < minOomAdj) {
4523                    continue;
4524                }
4525
4526                // If no package is specified, we call all processes under the
4527                // give user id.
4528                if (packageName == null) {
4529                    if (app.userId != userId) {
4530                        continue;
4531                    }
4532                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4533                        continue;
4534                    }
4535                // Package has been specified, we want to hit all processes
4536                // that match it.  We need to qualify this by the processes
4537                // that are running under the specified app and user ID.
4538                } else {
4539                    if (UserHandle.getAppId(app.uid) != appId) {
4540                        continue;
4541                    }
4542                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4543                        continue;
4544                    }
4545                    if (!app.pkgList.containsKey(packageName)) {
4546                        continue;
4547                    }
4548                }
4549
4550                // Process has passed all conditions, kill it!
4551                if (!doit) {
4552                    return true;
4553                }
4554                app.removed = true;
4555                procs.add(app);
4556            }
4557        }
4558
4559        int N = procs.size();
4560        for (int i=0; i<N; i++) {
4561            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4562        }
4563        updateOomAdjLocked();
4564        return N > 0;
4565    }
4566
4567    private final boolean forceStopPackageLocked(String name, int appId,
4568            boolean callerWillRestart, boolean purgeCache, boolean doit,
4569            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4570        int i;
4571        int N;
4572
4573        if (userId == UserHandle.USER_ALL && name == null) {
4574            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4575        }
4576
4577        if (appId < 0 && name != null) {
4578            try {
4579                appId = UserHandle.getAppId(
4580                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4581            } catch (RemoteException e) {
4582            }
4583        }
4584
4585        if (doit) {
4586            if (name != null) {
4587                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4588                        + " user=" + userId + ": " + reason);
4589            } else {
4590                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4591            }
4592
4593            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4594            for (int ip=pmap.size()-1; ip>=0; ip--) {
4595                SparseArray<Long> ba = pmap.valueAt(ip);
4596                for (i=ba.size()-1; i>=0; i--) {
4597                    boolean remove = false;
4598                    final int entUid = ba.keyAt(i);
4599                    if (name != null) {
4600                        if (userId == UserHandle.USER_ALL) {
4601                            if (UserHandle.getAppId(entUid) == appId) {
4602                                remove = true;
4603                            }
4604                        } else {
4605                            if (entUid == UserHandle.getUid(userId, appId)) {
4606                                remove = true;
4607                            }
4608                        }
4609                    } else if (UserHandle.getUserId(entUid) == userId) {
4610                        remove = true;
4611                    }
4612                    if (remove) {
4613                        ba.removeAt(i);
4614                    }
4615                }
4616                if (ba.size() == 0) {
4617                    pmap.removeAt(ip);
4618                }
4619            }
4620        }
4621
4622        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4623                -100, callerWillRestart, true, doit, evenPersistent,
4624                name == null ? ("stop user " + userId) : ("stop " + name));
4625
4626        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4627            if (!doit) {
4628                return true;
4629            }
4630            didSomething = true;
4631        }
4632
4633        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4634            if (!doit) {
4635                return true;
4636            }
4637            didSomething = true;
4638        }
4639
4640        if (name == null) {
4641            // Remove all sticky broadcasts from this user.
4642            mStickyBroadcasts.remove(userId);
4643        }
4644
4645        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4646        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4647                userId, providers)) {
4648            if (!doit) {
4649                return true;
4650            }
4651            didSomething = true;
4652        }
4653        N = providers.size();
4654        for (i=0; i<N; i++) {
4655            removeDyingProviderLocked(null, providers.get(i), true);
4656        }
4657
4658        // Remove transient permissions granted from/to this package/user
4659        removeUriPermissionsForPackageLocked(name, userId, false);
4660
4661        if (name == null || uninstalling) {
4662            // Remove pending intents.  For now we only do this when force
4663            // stopping users, because we have some problems when doing this
4664            // for packages -- app widgets are not currently cleaned up for
4665            // such packages, so they can be left with bad pending intents.
4666            if (mIntentSenderRecords.size() > 0) {
4667                Iterator<WeakReference<PendingIntentRecord>> it
4668                        = mIntentSenderRecords.values().iterator();
4669                while (it.hasNext()) {
4670                    WeakReference<PendingIntentRecord> wpir = it.next();
4671                    if (wpir == null) {
4672                        it.remove();
4673                        continue;
4674                    }
4675                    PendingIntentRecord pir = wpir.get();
4676                    if (pir == null) {
4677                        it.remove();
4678                        continue;
4679                    }
4680                    if (name == null) {
4681                        // Stopping user, remove all objects for the user.
4682                        if (pir.key.userId != userId) {
4683                            // Not the same user, skip it.
4684                            continue;
4685                        }
4686                    } else {
4687                        if (UserHandle.getAppId(pir.uid) != appId) {
4688                            // Different app id, skip it.
4689                            continue;
4690                        }
4691                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4692                            // Different user, skip it.
4693                            continue;
4694                        }
4695                        if (!pir.key.packageName.equals(name)) {
4696                            // Different package, skip it.
4697                            continue;
4698                        }
4699                    }
4700                    if (!doit) {
4701                        return true;
4702                    }
4703                    didSomething = true;
4704                    it.remove();
4705                    pir.canceled = true;
4706                    if (pir.key.activity != null) {
4707                        pir.key.activity.pendingResults.remove(pir.ref);
4708                    }
4709                }
4710            }
4711        }
4712
4713        if (doit) {
4714            if (purgeCache && name != null) {
4715                AttributeCache ac = AttributeCache.instance();
4716                if (ac != null) {
4717                    ac.removePackage(name);
4718                }
4719            }
4720            if (mBooted) {
4721                mStackSupervisor.resumeTopActivitiesLocked();
4722                mStackSupervisor.scheduleIdleLocked();
4723            }
4724        }
4725
4726        return didSomething;
4727    }
4728
4729    private final boolean removeProcessLocked(ProcessRecord app,
4730            boolean callerWillRestart, boolean allowRestart, String reason) {
4731        final String name = app.processName;
4732        final int uid = app.uid;
4733        if (DEBUG_PROCESSES) Slog.d(
4734            TAG, "Force removing proc " + app.toShortString() + " (" + name
4735            + "/" + uid + ")");
4736
4737        mProcessNames.remove(name, uid);
4738        mIsolatedProcesses.remove(app.uid);
4739        if (mHeavyWeightProcess == app) {
4740            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4741                    mHeavyWeightProcess.userId, 0));
4742            mHeavyWeightProcess = null;
4743        }
4744        boolean needRestart = false;
4745        if (app.pid > 0 && app.pid != MY_PID) {
4746            int pid = app.pid;
4747            synchronized (mPidsSelfLocked) {
4748                mPidsSelfLocked.remove(pid);
4749                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4750            }
4751            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4752                    app.processName, app.info.uid);
4753            if (app.isolated) {
4754                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4755            }
4756            killUnneededProcessLocked(app, reason);
4757            handleAppDiedLocked(app, true, allowRestart);
4758            removeLruProcessLocked(app);
4759
4760            if (app.persistent && !app.isolated) {
4761                if (!callerWillRestart) {
4762                    addAppLocked(app.info, false);
4763                } else {
4764                    needRestart = true;
4765                }
4766            }
4767        } else {
4768            mRemovedProcesses.add(app);
4769        }
4770
4771        return needRestart;
4772    }
4773
4774    private final void processStartTimedOutLocked(ProcessRecord app) {
4775        final int pid = app.pid;
4776        boolean gone = false;
4777        synchronized (mPidsSelfLocked) {
4778            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4779            if (knownApp != null && knownApp.thread == null) {
4780                mPidsSelfLocked.remove(pid);
4781                gone = true;
4782            }
4783        }
4784
4785        if (gone) {
4786            Slog.w(TAG, "Process " + app + " failed to attach");
4787            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4788                    pid, app.uid, app.processName);
4789            mProcessNames.remove(app.processName, app.uid);
4790            mIsolatedProcesses.remove(app.uid);
4791            if (mHeavyWeightProcess == app) {
4792                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4793                        mHeavyWeightProcess.userId, 0));
4794                mHeavyWeightProcess = null;
4795            }
4796            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4797                    app.processName, app.info.uid);
4798            if (app.isolated) {
4799                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4800            }
4801            // Take care of any launching providers waiting for this process.
4802            checkAppInLaunchingProvidersLocked(app, true);
4803            // Take care of any services that are waiting for the process.
4804            mServices.processStartTimedOutLocked(app);
4805            killUnneededProcessLocked(app, "start timeout");
4806            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4807                Slog.w(TAG, "Unattached app died before backup, skipping");
4808                try {
4809                    IBackupManager bm = IBackupManager.Stub.asInterface(
4810                            ServiceManager.getService(Context.BACKUP_SERVICE));
4811                    bm.agentDisconnected(app.info.packageName);
4812                } catch (RemoteException e) {
4813                    // Can't happen; the backup manager is local
4814                }
4815            }
4816            if (isPendingBroadcastProcessLocked(pid)) {
4817                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4818                skipPendingBroadcastLocked(pid);
4819            }
4820        } else {
4821            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4822        }
4823    }
4824
4825    private final boolean attachApplicationLocked(IApplicationThread thread,
4826            int pid) {
4827
4828        // Find the application record that is being attached...  either via
4829        // the pid if we are running in multiple processes, or just pull the
4830        // next app record if we are emulating process with anonymous threads.
4831        ProcessRecord app;
4832        if (pid != MY_PID && pid >= 0) {
4833            synchronized (mPidsSelfLocked) {
4834                app = mPidsSelfLocked.get(pid);
4835            }
4836        } else {
4837            app = null;
4838        }
4839
4840        if (app == null) {
4841            Slog.w(TAG, "No pending application record for pid " + pid
4842                    + " (IApplicationThread " + thread + "); dropping process");
4843            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4844            if (pid > 0 && pid != MY_PID) {
4845                Process.killProcessQuiet(pid);
4846            } else {
4847                try {
4848                    thread.scheduleExit();
4849                } catch (Exception e) {
4850                    // Ignore exceptions.
4851                }
4852            }
4853            return false;
4854        }
4855
4856        // If this application record is still attached to a previous
4857        // process, clean it up now.
4858        if (app.thread != null) {
4859            handleAppDiedLocked(app, true, true);
4860        }
4861
4862        // Tell the process all about itself.
4863
4864        if (localLOGV) Slog.v(
4865                TAG, "Binding process pid " + pid + " to record " + app);
4866
4867        final String processName = app.processName;
4868        try {
4869            AppDeathRecipient adr = new AppDeathRecipient(
4870                    app, pid, thread);
4871            thread.asBinder().linkToDeath(adr, 0);
4872            app.deathRecipient = adr;
4873        } catch (RemoteException e) {
4874            app.resetPackageList(mProcessStats);
4875            startProcessLocked(app, "link fail", processName);
4876            return false;
4877        }
4878
4879        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4880
4881        app.makeActive(thread, mProcessStats);
4882        app.curAdj = app.setAdj = -100;
4883        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4884        app.forcingToForeground = null;
4885        updateProcessForegroundLocked(app, false, false);
4886        app.hasShownUi = false;
4887        app.debugging = false;
4888        app.cached = false;
4889
4890        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4891
4892        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4893        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4894
4895        if (!normalMode) {
4896            Slog.i(TAG, "Launching preboot mode app: " + app);
4897        }
4898
4899        if (localLOGV) Slog.v(
4900            TAG, "New app record " + app
4901            + " thread=" + thread.asBinder() + " pid=" + pid);
4902        try {
4903            int testMode = IApplicationThread.DEBUG_OFF;
4904            if (mDebugApp != null && mDebugApp.equals(processName)) {
4905                testMode = mWaitForDebugger
4906                    ? IApplicationThread.DEBUG_WAIT
4907                    : IApplicationThread.DEBUG_ON;
4908                app.debugging = true;
4909                if (mDebugTransient) {
4910                    mDebugApp = mOrigDebugApp;
4911                    mWaitForDebugger = mOrigWaitForDebugger;
4912                }
4913            }
4914            String profileFile = app.instrumentationProfileFile;
4915            ParcelFileDescriptor profileFd = null;
4916            boolean profileAutoStop = false;
4917            if (mProfileApp != null && mProfileApp.equals(processName)) {
4918                mProfileProc = app;
4919                profileFile = mProfileFile;
4920                profileFd = mProfileFd;
4921                profileAutoStop = mAutoStopProfiler;
4922            }
4923            boolean enableOpenGlTrace = false;
4924            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4925                enableOpenGlTrace = true;
4926                mOpenGlTraceApp = null;
4927            }
4928
4929            // If the app is being launched for restore or full backup, set it up specially
4930            boolean isRestrictedBackupMode = false;
4931            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4932                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4933                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4934                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4935            }
4936
4937            ensurePackageDexOpt(app.instrumentationInfo != null
4938                    ? app.instrumentationInfo.packageName
4939                    : app.info.packageName);
4940            if (app.instrumentationClass != null) {
4941                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4942            }
4943            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4944                    + processName + " with config " + mConfiguration);
4945            ApplicationInfo appInfo = app.instrumentationInfo != null
4946                    ? app.instrumentationInfo : app.info;
4947            app.compat = compatibilityInfoForPackageLocked(appInfo);
4948            if (profileFd != null) {
4949                profileFd = profileFd.dup();
4950            }
4951            thread.bindApplication(processName, appInfo, providers,
4952                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4953                    app.instrumentationArguments, app.instrumentationWatcher,
4954                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4955                    isRestrictedBackupMode || !normalMode, app.persistent,
4956                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4957                    mCoreSettingsObserver.getCoreSettingsLocked());
4958            updateLruProcessLocked(app, false, null);
4959            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4960        } catch (Exception e) {
4961            // todo: Yikes!  What should we do?  For now we will try to
4962            // start another process, but that could easily get us in
4963            // an infinite loop of restarting processes...
4964            Slog.w(TAG, "Exception thrown during bind!", e);
4965
4966            app.resetPackageList(mProcessStats);
4967            app.unlinkDeathRecipient();
4968            startProcessLocked(app, "bind fail", processName);
4969            return false;
4970        }
4971
4972        // Remove this record from the list of starting applications.
4973        mPersistentStartingProcesses.remove(app);
4974        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4975                "Attach application locked removing on hold: " + app);
4976        mProcessesOnHold.remove(app);
4977
4978        boolean badApp = false;
4979        boolean didSomething = false;
4980
4981        // See if the top visible activity is waiting to run in this process...
4982        if (normalMode) {
4983            try {
4984                if (mStackSupervisor.attachApplicationLocked(app)) {
4985                    didSomething = true;
4986                }
4987            } catch (Exception e) {
4988                badApp = true;
4989            }
4990        }
4991
4992        // Find any services that should be running in this process...
4993        if (!badApp) {
4994            try {
4995                didSomething |= mServices.attachApplicationLocked(app, processName);
4996            } catch (Exception e) {
4997                badApp = true;
4998            }
4999        }
5000
5001        // Check if a next-broadcast receiver is in this process...
5002        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5003            try {
5004                didSomething |= sendPendingBroadcastsLocked(app);
5005            } catch (Exception e) {
5006                // If the app died trying to launch the receiver we declare it 'bad'
5007                badApp = true;
5008            }
5009        }
5010
5011        // Check whether the next backup agent is in this process...
5012        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5013            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5014            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5015            try {
5016                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5017                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5018                        mBackupTarget.backupMode);
5019            } catch (Exception e) {
5020                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5021                e.printStackTrace();
5022            }
5023        }
5024
5025        if (badApp) {
5026            // todo: Also need to kill application to deal with all
5027            // kinds of exceptions.
5028            handleAppDiedLocked(app, false, true);
5029            return false;
5030        }
5031
5032        if (!didSomething) {
5033            updateOomAdjLocked();
5034        }
5035
5036        return true;
5037    }
5038
5039    @Override
5040    public final void attachApplication(IApplicationThread thread) {
5041        synchronized (this) {
5042            int callingPid = Binder.getCallingPid();
5043            final long origId = Binder.clearCallingIdentity();
5044            attachApplicationLocked(thread, callingPid);
5045            Binder.restoreCallingIdentity(origId);
5046        }
5047    }
5048
5049    @Override
5050    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5051        final long origId = Binder.clearCallingIdentity();
5052        synchronized (this) {
5053            ActivityStack stack = ActivityRecord.getStackLocked(token);
5054            if (stack != null) {
5055                ActivityRecord r =
5056                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5057                if (stopProfiling) {
5058                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5059                        try {
5060                            mProfileFd.close();
5061                        } catch (IOException e) {
5062                        }
5063                        clearProfilerLocked();
5064                    }
5065                }
5066            }
5067        }
5068        Binder.restoreCallingIdentity(origId);
5069    }
5070
5071    void enableScreenAfterBoot() {
5072        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5073                SystemClock.uptimeMillis());
5074        mWindowManager.enableScreenAfterBoot();
5075
5076        synchronized (this) {
5077            updateEventDispatchingLocked();
5078        }
5079    }
5080
5081    @Override
5082    public void showBootMessage(final CharSequence msg, final boolean always) {
5083        enforceNotIsolatedCaller("showBootMessage");
5084        mWindowManager.showBootMessage(msg, always);
5085    }
5086
5087    @Override
5088    public void dismissKeyguardOnNextActivity() {
5089        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5090        final long token = Binder.clearCallingIdentity();
5091        try {
5092            synchronized (this) {
5093                if (DEBUG_LOCKSCREEN) logLockScreen("");
5094                if (mLockScreenShown) {
5095                    mLockScreenShown = false;
5096                    comeOutOfSleepIfNeededLocked();
5097                }
5098                mStackSupervisor.setDismissKeyguard(true);
5099            }
5100        } finally {
5101            Binder.restoreCallingIdentity(token);
5102        }
5103    }
5104
5105    final void finishBooting() {
5106        IntentFilter pkgFilter = new IntentFilter();
5107        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5108        pkgFilter.addDataScheme("package");
5109        mContext.registerReceiver(new BroadcastReceiver() {
5110            @Override
5111            public void onReceive(Context context, Intent intent) {
5112                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5113                if (pkgs != null) {
5114                    for (String pkg : pkgs) {
5115                        synchronized (ActivityManagerService.this) {
5116                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5117                                    "finished booting")) {
5118                                setResultCode(Activity.RESULT_OK);
5119                                return;
5120                            }
5121                        }
5122                    }
5123                }
5124            }
5125        }, pkgFilter);
5126
5127        synchronized (this) {
5128            // Ensure that any processes we had put on hold are now started
5129            // up.
5130            final int NP = mProcessesOnHold.size();
5131            if (NP > 0) {
5132                ArrayList<ProcessRecord> procs =
5133                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5134                for (int ip=0; ip<NP; ip++) {
5135                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5136                            + procs.get(ip));
5137                    startProcessLocked(procs.get(ip), "on-hold", null);
5138                }
5139            }
5140
5141            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5142                // Start looking for apps that are abusing wake locks.
5143                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5144                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5145                // Tell anyone interested that we are done booting!
5146                SystemProperties.set("sys.boot_completed", "1");
5147                SystemProperties.set("dev.bootcomplete", "1");
5148                for (int i=0; i<mStartedUsers.size(); i++) {
5149                    UserStartedState uss = mStartedUsers.valueAt(i);
5150                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5151                        uss.mState = UserStartedState.STATE_RUNNING;
5152                        final int userId = mStartedUsers.keyAt(i);
5153                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5154                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5155                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5156                        broadcastIntentLocked(null, null, intent, null,
5157                                new IIntentReceiver.Stub() {
5158                                    @Override
5159                                    public void performReceive(Intent intent, int resultCode,
5160                                            String data, Bundle extras, boolean ordered,
5161                                            boolean sticky, int sendingUser) {
5162                                        synchronized (ActivityManagerService.this) {
5163                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5164                                                    true, false);
5165                                        }
5166                                    }
5167                                },
5168                                0, null, null,
5169                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5170                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5171                                userId);
5172                    }
5173                }
5174                scheduleStartRelatedUsersLocked();
5175            }
5176        }
5177    }
5178
5179    final void ensureBootCompleted() {
5180        boolean booting;
5181        boolean enableScreen;
5182        synchronized (this) {
5183            booting = mBooting;
5184            mBooting = false;
5185            enableScreen = !mBooted;
5186            mBooted = true;
5187        }
5188
5189        if (booting) {
5190            finishBooting();
5191        }
5192
5193        if (enableScreen) {
5194            enableScreenAfterBoot();
5195        }
5196    }
5197
5198    @Override
5199    public final void activityResumed(IBinder token) {
5200        final long origId = Binder.clearCallingIdentity();
5201        synchronized(this) {
5202            ActivityStack stack = ActivityRecord.getStackLocked(token);
5203            if (stack != null) {
5204                ActivityRecord.activityResumedLocked(token);
5205            }
5206        }
5207        Binder.restoreCallingIdentity(origId);
5208    }
5209
5210    @Override
5211    public final void activityPaused(IBinder token) {
5212        final long origId = Binder.clearCallingIdentity();
5213        synchronized(this) {
5214            ActivityStack stack = ActivityRecord.getStackLocked(token);
5215            if (stack != null) {
5216                stack.activityPausedLocked(token, false);
5217            }
5218        }
5219        Binder.restoreCallingIdentity(origId);
5220    }
5221
5222    @Override
5223    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5224            CharSequence description) {
5225        if (localLOGV) Slog.v(
5226            TAG, "Activity stopped: token=" + token);
5227
5228        // Refuse possible leaked file descriptors
5229        if (icicle != null && icicle.hasFileDescriptors()) {
5230            throw new IllegalArgumentException("File descriptors passed in Bundle");
5231        }
5232
5233        ActivityRecord r = null;
5234
5235        final long origId = Binder.clearCallingIdentity();
5236
5237        synchronized (this) {
5238            r = ActivityRecord.isInStackLocked(token);
5239            if (r != null) {
5240                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5241            }
5242        }
5243
5244        if (r != null) {
5245            sendPendingThumbnail(r, null, null, null, false);
5246        }
5247
5248        trimApplications();
5249
5250        Binder.restoreCallingIdentity(origId);
5251    }
5252
5253    @Override
5254    public final void activityDestroyed(IBinder token) {
5255        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5256        synchronized (this) {
5257            ActivityStack stack = ActivityRecord.getStackLocked(token);
5258            if (stack != null) {
5259                stack.activityDestroyedLocked(token);
5260            }
5261        }
5262    }
5263
5264    @Override
5265    public String getCallingPackage(IBinder token) {
5266        synchronized (this) {
5267            ActivityRecord r = getCallingRecordLocked(token);
5268            return r != null ? r.info.packageName : null;
5269        }
5270    }
5271
5272    @Override
5273    public ComponentName getCallingActivity(IBinder token) {
5274        synchronized (this) {
5275            ActivityRecord r = getCallingRecordLocked(token);
5276            return r != null ? r.intent.getComponent() : null;
5277        }
5278    }
5279
5280    private ActivityRecord getCallingRecordLocked(IBinder token) {
5281        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5282        if (r == null) {
5283            return null;
5284        }
5285        return r.resultTo;
5286    }
5287
5288    @Override
5289    public ComponentName getActivityClassForToken(IBinder token) {
5290        synchronized(this) {
5291            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5292            if (r == null) {
5293                return null;
5294            }
5295            return r.intent.getComponent();
5296        }
5297    }
5298
5299    @Override
5300    public String getPackageForToken(IBinder token) {
5301        synchronized(this) {
5302            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5303            if (r == null) {
5304                return null;
5305            }
5306            return r.packageName;
5307        }
5308    }
5309
5310    @Override
5311    public IIntentSender getIntentSender(int type,
5312            String packageName, IBinder token, String resultWho,
5313            int requestCode, Intent[] intents, String[] resolvedTypes,
5314            int flags, Bundle options, int userId) {
5315        enforceNotIsolatedCaller("getIntentSender");
5316        // Refuse possible leaked file descriptors
5317        if (intents != null) {
5318            if (intents.length < 1) {
5319                throw new IllegalArgumentException("Intents array length must be >= 1");
5320            }
5321            for (int i=0; i<intents.length; i++) {
5322                Intent intent = intents[i];
5323                if (intent != null) {
5324                    if (intent.hasFileDescriptors()) {
5325                        throw new IllegalArgumentException("File descriptors passed in Intent");
5326                    }
5327                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5328                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5329                        throw new IllegalArgumentException(
5330                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5331                    }
5332                    intents[i] = new Intent(intent);
5333                }
5334            }
5335            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5336                throw new IllegalArgumentException(
5337                        "Intent array length does not match resolvedTypes length");
5338            }
5339        }
5340        if (options != null) {
5341            if (options.hasFileDescriptors()) {
5342                throw new IllegalArgumentException("File descriptors passed in options");
5343            }
5344        }
5345
5346        synchronized(this) {
5347            int callingUid = Binder.getCallingUid();
5348            int origUserId = userId;
5349            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5350                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5351                    "getIntentSender", null);
5352            if (origUserId == UserHandle.USER_CURRENT) {
5353                // We don't want to evaluate this until the pending intent is
5354                // actually executed.  However, we do want to always do the
5355                // security checking for it above.
5356                userId = UserHandle.USER_CURRENT;
5357            }
5358            try {
5359                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5360                    int uid = AppGlobals.getPackageManager()
5361                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5362                    if (!UserHandle.isSameApp(callingUid, uid)) {
5363                        String msg = "Permission Denial: getIntentSender() from pid="
5364                            + Binder.getCallingPid()
5365                            + ", uid=" + Binder.getCallingUid()
5366                            + ", (need uid=" + uid + ")"
5367                            + " is not allowed to send as package " + packageName;
5368                        Slog.w(TAG, msg);
5369                        throw new SecurityException(msg);
5370                    }
5371                }
5372
5373                return getIntentSenderLocked(type, packageName, callingUid, userId,
5374                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5375
5376            } catch (RemoteException e) {
5377                throw new SecurityException(e);
5378            }
5379        }
5380    }
5381
5382    IIntentSender getIntentSenderLocked(int type, String packageName,
5383            int callingUid, int userId, IBinder token, String resultWho,
5384            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5385            Bundle options) {
5386        if (DEBUG_MU)
5387            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5388        ActivityRecord activity = null;
5389        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5390            activity = ActivityRecord.isInStackLocked(token);
5391            if (activity == null) {
5392                return null;
5393            }
5394            if (activity.finishing) {
5395                return null;
5396            }
5397        }
5398
5399        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5400        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5401        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5402        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5403                |PendingIntent.FLAG_UPDATE_CURRENT);
5404
5405        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5406                type, packageName, activity, resultWho,
5407                requestCode, intents, resolvedTypes, flags, options, userId);
5408        WeakReference<PendingIntentRecord> ref;
5409        ref = mIntentSenderRecords.get(key);
5410        PendingIntentRecord rec = ref != null ? ref.get() : null;
5411        if (rec != null) {
5412            if (!cancelCurrent) {
5413                if (updateCurrent) {
5414                    if (rec.key.requestIntent != null) {
5415                        rec.key.requestIntent.replaceExtras(intents != null ?
5416                                intents[intents.length - 1] : null);
5417                    }
5418                    if (intents != null) {
5419                        intents[intents.length-1] = rec.key.requestIntent;
5420                        rec.key.allIntents = intents;
5421                        rec.key.allResolvedTypes = resolvedTypes;
5422                    } else {
5423                        rec.key.allIntents = null;
5424                        rec.key.allResolvedTypes = null;
5425                    }
5426                }
5427                return rec;
5428            }
5429            rec.canceled = true;
5430            mIntentSenderRecords.remove(key);
5431        }
5432        if (noCreate) {
5433            return rec;
5434        }
5435        rec = new PendingIntentRecord(this, key, callingUid);
5436        mIntentSenderRecords.put(key, rec.ref);
5437        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5438            if (activity.pendingResults == null) {
5439                activity.pendingResults
5440                        = new HashSet<WeakReference<PendingIntentRecord>>();
5441            }
5442            activity.pendingResults.add(rec.ref);
5443        }
5444        return rec;
5445    }
5446
5447    @Override
5448    public void cancelIntentSender(IIntentSender sender) {
5449        if (!(sender instanceof PendingIntentRecord)) {
5450            return;
5451        }
5452        synchronized(this) {
5453            PendingIntentRecord rec = (PendingIntentRecord)sender;
5454            try {
5455                int uid = AppGlobals.getPackageManager()
5456                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5457                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5458                    String msg = "Permission Denial: cancelIntentSender() from pid="
5459                        + Binder.getCallingPid()
5460                        + ", uid=" + Binder.getCallingUid()
5461                        + " is not allowed to cancel packges "
5462                        + rec.key.packageName;
5463                    Slog.w(TAG, msg);
5464                    throw new SecurityException(msg);
5465                }
5466            } catch (RemoteException e) {
5467                throw new SecurityException(e);
5468            }
5469            cancelIntentSenderLocked(rec, true);
5470        }
5471    }
5472
5473    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5474        rec.canceled = true;
5475        mIntentSenderRecords.remove(rec.key);
5476        if (cleanActivity && rec.key.activity != null) {
5477            rec.key.activity.pendingResults.remove(rec.ref);
5478        }
5479    }
5480
5481    @Override
5482    public String getPackageForIntentSender(IIntentSender pendingResult) {
5483        if (!(pendingResult instanceof PendingIntentRecord)) {
5484            return null;
5485        }
5486        try {
5487            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5488            return res.key.packageName;
5489        } catch (ClassCastException e) {
5490        }
5491        return null;
5492    }
5493
5494    @Override
5495    public int getUidForIntentSender(IIntentSender sender) {
5496        if (sender instanceof PendingIntentRecord) {
5497            try {
5498                PendingIntentRecord res = (PendingIntentRecord)sender;
5499                return res.uid;
5500            } catch (ClassCastException e) {
5501            }
5502        }
5503        return -1;
5504    }
5505
5506    @Override
5507    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5508        if (!(pendingResult instanceof PendingIntentRecord)) {
5509            return false;
5510        }
5511        try {
5512            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5513            if (res.key.allIntents == null) {
5514                return false;
5515            }
5516            for (int i=0; i<res.key.allIntents.length; i++) {
5517                Intent intent = res.key.allIntents[i];
5518                if (intent.getPackage() != null && intent.getComponent() != null) {
5519                    return false;
5520                }
5521            }
5522            return true;
5523        } catch (ClassCastException e) {
5524        }
5525        return false;
5526    }
5527
5528    @Override
5529    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5530        if (!(pendingResult instanceof PendingIntentRecord)) {
5531            return false;
5532        }
5533        try {
5534            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5535            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5536                return true;
5537            }
5538            return false;
5539        } catch (ClassCastException e) {
5540        }
5541        return false;
5542    }
5543
5544    @Override
5545    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5546        if (!(pendingResult instanceof PendingIntentRecord)) {
5547            return null;
5548        }
5549        try {
5550            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5551            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5552        } catch (ClassCastException e) {
5553        }
5554        return null;
5555    }
5556
5557    @Override
5558    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5559        if (!(pendingResult instanceof PendingIntentRecord)) {
5560            return null;
5561        }
5562        try {
5563            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5564            Intent intent = res.key.requestIntent;
5565            if (intent != null) {
5566                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5567                        || res.lastTagPrefix.equals(prefix))) {
5568                    return res.lastTag;
5569                }
5570                res.lastTagPrefix = prefix;
5571                StringBuilder sb = new StringBuilder(128);
5572                if (prefix != null) {
5573                    sb.append(prefix);
5574                }
5575                if (intent.getAction() != null) {
5576                    sb.append(intent.getAction());
5577                } else if (intent.getComponent() != null) {
5578                    intent.getComponent().appendShortString(sb);
5579                } else {
5580                    sb.append("?");
5581                }
5582                return res.lastTag = sb.toString();
5583            }
5584        } catch (ClassCastException e) {
5585        }
5586        return null;
5587    }
5588
5589    @Override
5590    public void setProcessLimit(int max) {
5591        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5592                "setProcessLimit()");
5593        synchronized (this) {
5594            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5595            mProcessLimitOverride = max;
5596        }
5597        trimApplications();
5598    }
5599
5600    @Override
5601    public int getProcessLimit() {
5602        synchronized (this) {
5603            return mProcessLimitOverride;
5604        }
5605    }
5606
5607    void foregroundTokenDied(ForegroundToken token) {
5608        synchronized (ActivityManagerService.this) {
5609            synchronized (mPidsSelfLocked) {
5610                ForegroundToken cur
5611                    = mForegroundProcesses.get(token.pid);
5612                if (cur != token) {
5613                    return;
5614                }
5615                mForegroundProcesses.remove(token.pid);
5616                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5617                if (pr == null) {
5618                    return;
5619                }
5620                pr.forcingToForeground = null;
5621                updateProcessForegroundLocked(pr, false, false);
5622            }
5623            updateOomAdjLocked();
5624        }
5625    }
5626
5627    @Override
5628    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5629        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5630                "setProcessForeground()");
5631        synchronized(this) {
5632            boolean changed = false;
5633
5634            synchronized (mPidsSelfLocked) {
5635                ProcessRecord pr = mPidsSelfLocked.get(pid);
5636                if (pr == null && isForeground) {
5637                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5638                    return;
5639                }
5640                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5641                if (oldToken != null) {
5642                    oldToken.token.unlinkToDeath(oldToken, 0);
5643                    mForegroundProcesses.remove(pid);
5644                    if (pr != null) {
5645                        pr.forcingToForeground = null;
5646                    }
5647                    changed = true;
5648                }
5649                if (isForeground && token != null) {
5650                    ForegroundToken newToken = new ForegroundToken() {
5651                        @Override
5652                        public void binderDied() {
5653                            foregroundTokenDied(this);
5654                        }
5655                    };
5656                    newToken.pid = pid;
5657                    newToken.token = token;
5658                    try {
5659                        token.linkToDeath(newToken, 0);
5660                        mForegroundProcesses.put(pid, newToken);
5661                        pr.forcingToForeground = token;
5662                        changed = true;
5663                    } catch (RemoteException e) {
5664                        // If the process died while doing this, we will later
5665                        // do the cleanup with the process death link.
5666                    }
5667                }
5668            }
5669
5670            if (changed) {
5671                updateOomAdjLocked();
5672            }
5673        }
5674    }
5675
5676    // =========================================================
5677    // PERMISSIONS
5678    // =========================================================
5679
5680    static class PermissionController extends IPermissionController.Stub {
5681        ActivityManagerService mActivityManagerService;
5682        PermissionController(ActivityManagerService activityManagerService) {
5683            mActivityManagerService = activityManagerService;
5684        }
5685
5686        @Override
5687        public boolean checkPermission(String permission, int pid, int uid) {
5688            return mActivityManagerService.checkPermission(permission, pid,
5689                    uid) == PackageManager.PERMISSION_GRANTED;
5690        }
5691    }
5692
5693    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5694        @Override
5695        public int checkComponentPermission(String permission, int pid, int uid,
5696                int owningUid, boolean exported) {
5697            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5698                    owningUid, exported);
5699        }
5700
5701        @Override
5702        public Object getAMSLock() {
5703            return ActivityManagerService.this;
5704        }
5705    }
5706
5707    /**
5708     * This can be called with or without the global lock held.
5709     */
5710    int checkComponentPermission(String permission, int pid, int uid,
5711            int owningUid, boolean exported) {
5712        // We might be performing an operation on behalf of an indirect binder
5713        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5714        // client identity accordingly before proceeding.
5715        Identity tlsIdentity = sCallerIdentity.get();
5716        if (tlsIdentity != null) {
5717            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5718                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5719            uid = tlsIdentity.uid;
5720            pid = tlsIdentity.pid;
5721        }
5722
5723        if (pid == MY_PID) {
5724            return PackageManager.PERMISSION_GRANTED;
5725        }
5726
5727        return ActivityManager.checkComponentPermission(permission, uid,
5728                owningUid, exported);
5729    }
5730
5731    /**
5732     * As the only public entry point for permissions checking, this method
5733     * can enforce the semantic that requesting a check on a null global
5734     * permission is automatically denied.  (Internally a null permission
5735     * string is used when calling {@link #checkComponentPermission} in cases
5736     * when only uid-based security is needed.)
5737     *
5738     * This can be called with or without the global lock held.
5739     */
5740    @Override
5741    public int checkPermission(String permission, int pid, int uid) {
5742        if (permission == null) {
5743            return PackageManager.PERMISSION_DENIED;
5744        }
5745        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5746    }
5747
5748    /**
5749     * Binder IPC calls go through the public entry point.
5750     * This can be called with or without the global lock held.
5751     */
5752    int checkCallingPermission(String permission) {
5753        return checkPermission(permission,
5754                Binder.getCallingPid(),
5755                UserHandle.getAppId(Binder.getCallingUid()));
5756    }
5757
5758    /**
5759     * This can be called with or without the global lock held.
5760     */
5761    void enforceCallingPermission(String permission, String func) {
5762        if (checkCallingPermission(permission)
5763                == PackageManager.PERMISSION_GRANTED) {
5764            return;
5765        }
5766
5767        String msg = "Permission Denial: " + func + " from pid="
5768                + Binder.getCallingPid()
5769                + ", uid=" + Binder.getCallingUid()
5770                + " requires " + permission;
5771        Slog.w(TAG, msg);
5772        throw new SecurityException(msg);
5773    }
5774
5775    /**
5776     * Determine if UID is holding permissions required to access {@link Uri} in
5777     * the given {@link ProviderInfo}. Final permission checking is always done
5778     * in {@link ContentProvider}.
5779     */
5780    private final boolean checkHoldingPermissionsLocked(
5781            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5782        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5783                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5784
5785        if (pi.applicationInfo.uid == uid) {
5786            return true;
5787        } else if (!pi.exported) {
5788            return false;
5789        }
5790
5791        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5792        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5793        try {
5794            // check if target holds top-level <provider> permissions
5795            if (!readMet && pi.readPermission != null
5796                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5797                readMet = true;
5798            }
5799            if (!writeMet && pi.writePermission != null
5800                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5801                writeMet = true;
5802            }
5803
5804            // track if unprotected read/write is allowed; any denied
5805            // <path-permission> below removes this ability
5806            boolean allowDefaultRead = pi.readPermission == null;
5807            boolean allowDefaultWrite = pi.writePermission == null;
5808
5809            // check if target holds any <path-permission> that match uri
5810            final PathPermission[] pps = pi.pathPermissions;
5811            if (pps != null) {
5812                final String path = uri.getPath();
5813                int i = pps.length;
5814                while (i > 0 && (!readMet || !writeMet)) {
5815                    i--;
5816                    PathPermission pp = pps[i];
5817                    if (pp.match(path)) {
5818                        if (!readMet) {
5819                            final String pprperm = pp.getReadPermission();
5820                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5821                                    + pprperm + " for " + pp.getPath()
5822                                    + ": match=" + pp.match(path)
5823                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5824                            if (pprperm != null) {
5825                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5826                                    readMet = true;
5827                                } else {
5828                                    allowDefaultRead = false;
5829                                }
5830                            }
5831                        }
5832                        if (!writeMet) {
5833                            final String ppwperm = pp.getWritePermission();
5834                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5835                                    + ppwperm + " for " + pp.getPath()
5836                                    + ": match=" + pp.match(path)
5837                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5838                            if (ppwperm != null) {
5839                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5840                                    writeMet = true;
5841                                } else {
5842                                    allowDefaultWrite = false;
5843                                }
5844                            }
5845                        }
5846                    }
5847                }
5848            }
5849
5850            // grant unprotected <provider> read/write, if not blocked by
5851            // <path-permission> above
5852            if (allowDefaultRead) readMet = true;
5853            if (allowDefaultWrite) writeMet = true;
5854
5855        } catch (RemoteException e) {
5856            return false;
5857        }
5858
5859        return readMet && writeMet;
5860    }
5861
5862    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5863        ProviderInfo pi = null;
5864        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5865        if (cpr != null) {
5866            pi = cpr.info;
5867        } else {
5868            try {
5869                pi = AppGlobals.getPackageManager().resolveContentProvider(
5870                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5871            } catch (RemoteException ex) {
5872            }
5873        }
5874        return pi;
5875    }
5876
5877    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5878        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5879        if (targetUris != null) {
5880            return targetUris.get(uri);
5881        } else {
5882            return null;
5883        }
5884    }
5885
5886    private UriPermission findOrCreateUriPermissionLocked(
5887            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5888        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5889        if (targetUris == null) {
5890            targetUris = Maps.newArrayMap();
5891            mGrantedUriPermissions.put(targetUid, targetUris);
5892        }
5893
5894        UriPermission perm = targetUris.get(uri);
5895        if (perm == null) {
5896            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5897            targetUris.put(uri, perm);
5898        }
5899
5900        return perm;
5901    }
5902
5903    private final boolean checkUriPermissionLocked(
5904            Uri uri, int uid, int modeFlags, int minStrength) {
5905        // Root gets to do everything.
5906        if (uid == 0) {
5907            return true;
5908        }
5909        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5910        if (perms == null) return false;
5911        UriPermission perm = perms.get(uri);
5912        if (perm == null) return false;
5913        return perm.getStrength(modeFlags) >= minStrength;
5914    }
5915
5916    @Override
5917    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5918        enforceNotIsolatedCaller("checkUriPermission");
5919
5920        // Another redirected-binder-call permissions check as in
5921        // {@link checkComponentPermission}.
5922        Identity tlsIdentity = sCallerIdentity.get();
5923        if (tlsIdentity != null) {
5924            uid = tlsIdentity.uid;
5925            pid = tlsIdentity.pid;
5926        }
5927
5928        // Our own process gets to do everything.
5929        if (pid == MY_PID) {
5930            return PackageManager.PERMISSION_GRANTED;
5931        }
5932        synchronized(this) {
5933            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5934                    ? PackageManager.PERMISSION_GRANTED
5935                    : PackageManager.PERMISSION_DENIED;
5936        }
5937    }
5938
5939    /**
5940     * Check if the targetPkg can be granted permission to access uri by
5941     * the callingUid using the given modeFlags.  Throws a security exception
5942     * if callingUid is not allowed to do this.  Returns the uid of the target
5943     * if the URI permission grant should be performed; returns -1 if it is not
5944     * needed (for example targetPkg already has permission to access the URI).
5945     * If you already know the uid of the target, you can supply it in
5946     * lastTargetUid else set that to -1.
5947     */
5948    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5949            Uri uri, int modeFlags, int lastTargetUid) {
5950        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5951        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5952                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5953        if (modeFlags == 0) {
5954            return -1;
5955        }
5956
5957        if (targetPkg != null) {
5958            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5959                    "Checking grant " + targetPkg + " permission to " + uri);
5960        }
5961
5962        final IPackageManager pm = AppGlobals.getPackageManager();
5963
5964        // If this is not a content: uri, we can't do anything with it.
5965        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5966            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5967                    "Can't grant URI permission for non-content URI: " + uri);
5968            return -1;
5969        }
5970
5971        final String authority = uri.getAuthority();
5972        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5973        if (pi == null) {
5974            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5975            return -1;
5976        }
5977
5978        int targetUid = lastTargetUid;
5979        if (targetUid < 0 && targetPkg != null) {
5980            try {
5981                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5982                if (targetUid < 0) {
5983                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5984                            "Can't grant URI permission no uid for: " + targetPkg);
5985                    return -1;
5986                }
5987            } catch (RemoteException ex) {
5988                return -1;
5989            }
5990        }
5991
5992        if (targetUid >= 0) {
5993            // First...  does the target actually need this permission?
5994            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5995                // No need to grant the target this permission.
5996                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5997                        "Target " + targetPkg + " already has full permission to " + uri);
5998                return -1;
5999            }
6000        } else {
6001            // First...  there is no target package, so can anyone access it?
6002            boolean allowed = pi.exported;
6003            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6004                if (pi.readPermission != null) {
6005                    allowed = false;
6006                }
6007            }
6008            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6009                if (pi.writePermission != null) {
6010                    allowed = false;
6011                }
6012            }
6013            if (allowed) {
6014                return -1;
6015            }
6016        }
6017
6018        // Second...  is the provider allowing granting of URI permissions?
6019        if (!pi.grantUriPermissions) {
6020            throw new SecurityException("Provider " + pi.packageName
6021                    + "/" + pi.name
6022                    + " does not allow granting of Uri permissions (uri "
6023                    + uri + ")");
6024        }
6025        if (pi.uriPermissionPatterns != null) {
6026            final int N = pi.uriPermissionPatterns.length;
6027            boolean allowed = false;
6028            for (int i=0; i<N; i++) {
6029                if (pi.uriPermissionPatterns[i] != null
6030                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6031                    allowed = true;
6032                    break;
6033                }
6034            }
6035            if (!allowed) {
6036                throw new SecurityException("Provider " + pi.packageName
6037                        + "/" + pi.name
6038                        + " does not allow granting of permission to path of Uri "
6039                        + uri);
6040            }
6041        }
6042
6043        // Third...  does the caller itself have permission to access
6044        // this uri?
6045        if (callingUid != Process.myUid()) {
6046            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6047                // Require they hold a strong enough Uri permission
6048                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6049                        : UriPermission.STRENGTH_OWNED;
6050                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6051                    throw new SecurityException("Uid " + callingUid
6052                            + " does not have permission to uri " + uri);
6053                }
6054            }
6055        }
6056
6057        return targetUid;
6058    }
6059
6060    @Override
6061    public int checkGrantUriPermission(int callingUid, String targetPkg,
6062            Uri uri, int modeFlags) {
6063        enforceNotIsolatedCaller("checkGrantUriPermission");
6064        synchronized(this) {
6065            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6066        }
6067    }
6068
6069    void grantUriPermissionUncheckedLocked(
6070            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6071        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6072        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6073                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6074        if (modeFlags == 0) {
6075            return;
6076        }
6077
6078        // So here we are: the caller has the assumed permission
6079        // to the uri, and the target doesn't.  Let's now give this to
6080        // the target.
6081
6082        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6083                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6084
6085        final String authority = uri.getAuthority();
6086        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6087        if (pi == null) {
6088            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6089            return;
6090        }
6091
6092        final UriPermission perm = findOrCreateUriPermissionLocked(
6093                pi.packageName, targetPkg, targetUid, uri);
6094        perm.grantModes(modeFlags, persistable, owner);
6095    }
6096
6097    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6098            int modeFlags, UriPermissionOwner owner) {
6099        if (targetPkg == null) {
6100            throw new NullPointerException("targetPkg");
6101        }
6102
6103        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6104        if (targetUid < 0) {
6105            return;
6106        }
6107
6108        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6109    }
6110
6111    static class NeededUriGrants extends ArrayList<Uri> {
6112        final String targetPkg;
6113        final int targetUid;
6114        final int flags;
6115
6116        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6117            this.targetPkg = targetPkg;
6118            this.targetUid = targetUid;
6119            this.flags = flags;
6120        }
6121    }
6122
6123    /**
6124     * Like checkGrantUriPermissionLocked, but takes an Intent.
6125     */
6126    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6127            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6128        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6129                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6130                + " clip=" + (intent != null ? intent.getClipData() : null)
6131                + " from " + intent + "; flags=0x"
6132                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6133
6134        if (targetPkg == null) {
6135            throw new NullPointerException("targetPkg");
6136        }
6137
6138        if (intent == null) {
6139            return null;
6140        }
6141        Uri data = intent.getData();
6142        ClipData clip = intent.getClipData();
6143        if (data == null && clip == null) {
6144            return null;
6145        }
6146
6147        if (data != null) {
6148            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6149                mode, needed != null ? needed.targetUid : -1);
6150            if (targetUid > 0) {
6151                if (needed == null) {
6152                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6153                }
6154                needed.add(data);
6155            }
6156        }
6157        if (clip != null) {
6158            for (int i=0; i<clip.getItemCount(); i++) {
6159                Uri uri = clip.getItemAt(i).getUri();
6160                if (uri != null) {
6161                    int targetUid = -1;
6162                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6163                            mode, needed != null ? needed.targetUid : -1);
6164                    if (targetUid > 0) {
6165                        if (needed == null) {
6166                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6167                        }
6168                        needed.add(uri);
6169                    }
6170                } else {
6171                    Intent clipIntent = clip.getItemAt(i).getIntent();
6172                    if (clipIntent != null) {
6173                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6174                                callingUid, targetPkg, clipIntent, mode, needed);
6175                        if (newNeeded != null) {
6176                            needed = newNeeded;
6177                        }
6178                    }
6179                }
6180            }
6181        }
6182
6183        return needed;
6184    }
6185
6186    /**
6187     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6188     */
6189    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6190            UriPermissionOwner owner) {
6191        if (needed != null) {
6192            for (int i=0; i<needed.size(); i++) {
6193                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6194                        needed.get(i), needed.flags, owner);
6195            }
6196        }
6197    }
6198
6199    void grantUriPermissionFromIntentLocked(int callingUid,
6200            String targetPkg, Intent intent, UriPermissionOwner owner) {
6201        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6202                intent, intent != null ? intent.getFlags() : 0, null);
6203        if (needed == null) {
6204            return;
6205        }
6206
6207        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6208    }
6209
6210    @Override
6211    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6212            Uri uri, int modeFlags) {
6213        enforceNotIsolatedCaller("grantUriPermission");
6214        synchronized(this) {
6215            final ProcessRecord r = getRecordForAppLocked(caller);
6216            if (r == null) {
6217                throw new SecurityException("Unable to find app for caller "
6218                        + caller
6219                        + " when granting permission to uri " + uri);
6220            }
6221            if (targetPkg == null) {
6222                throw new IllegalArgumentException("null target");
6223            }
6224            if (uri == null) {
6225                throw new IllegalArgumentException("null uri");
6226            }
6227
6228            // Persistable only supported through Intents
6229            Preconditions.checkFlagsArgument(modeFlags,
6230                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6231
6232            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6233                    null);
6234        }
6235    }
6236
6237    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6238        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6239                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6240            ArrayMap<Uri, UriPermission> perms
6241                    = mGrantedUriPermissions.get(perm.targetUid);
6242            if (perms != null) {
6243                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6244                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6245                perms.remove(perm.uri);
6246                if (perms.size() == 0) {
6247                    mGrantedUriPermissions.remove(perm.targetUid);
6248                }
6249            }
6250        }
6251    }
6252
6253    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6254        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6255
6256        final IPackageManager pm = AppGlobals.getPackageManager();
6257        final String authority = uri.getAuthority();
6258        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6259        if (pi == null) {
6260            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6261            return;
6262        }
6263
6264        // Does the caller have this permission on the URI?
6265        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6266            // Right now, if you are not the original owner of the permission,
6267            // you are not allowed to revoke it.
6268            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6269                throw new SecurityException("Uid " + callingUid
6270                        + " does not have permission to uri " + uri);
6271            //}
6272        }
6273
6274        boolean persistChanged = false;
6275
6276        // Go through all of the permissions and remove any that match.
6277        final List<String> SEGMENTS = uri.getPathSegments();
6278        if (SEGMENTS != null) {
6279            final int NS = SEGMENTS.size();
6280            int N = mGrantedUriPermissions.size();
6281            for (int i=0; i<N; i++) {
6282                ArrayMap<Uri, UriPermission> perms
6283                        = mGrantedUriPermissions.valueAt(i);
6284                Iterator<UriPermission> it = perms.values().iterator();
6285            toploop:
6286                while (it.hasNext()) {
6287                    UriPermission perm = it.next();
6288                    Uri targetUri = perm.uri;
6289                    if (!authority.equals(targetUri.getAuthority())) {
6290                        continue;
6291                    }
6292                    List<String> targetSegments = targetUri.getPathSegments();
6293                    if (targetSegments == null) {
6294                        continue;
6295                    }
6296                    if (targetSegments.size() < NS) {
6297                        continue;
6298                    }
6299                    for (int j=0; j<NS; j++) {
6300                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6301                            continue toploop;
6302                        }
6303                    }
6304                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6305                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6306                    persistChanged |= perm.clearModes(modeFlags, true);
6307                    if (perm.modeFlags == 0) {
6308                        it.remove();
6309                    }
6310                }
6311                if (perms.size() == 0) {
6312                    mGrantedUriPermissions.remove(
6313                            mGrantedUriPermissions.keyAt(i));
6314                    N--;
6315                    i--;
6316                }
6317            }
6318        }
6319
6320        if (persistChanged) {
6321            schedulePersistUriGrants();
6322        }
6323    }
6324
6325    @Override
6326    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6327            int modeFlags) {
6328        enforceNotIsolatedCaller("revokeUriPermission");
6329        synchronized(this) {
6330            final ProcessRecord r = getRecordForAppLocked(caller);
6331            if (r == null) {
6332                throw new SecurityException("Unable to find app for caller "
6333                        + caller
6334                        + " when revoking permission to uri " + uri);
6335            }
6336            if (uri == null) {
6337                Slog.w(TAG, "revokeUriPermission: null uri");
6338                return;
6339            }
6340
6341            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6342                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6343            if (modeFlags == 0) {
6344                return;
6345            }
6346
6347            final IPackageManager pm = AppGlobals.getPackageManager();
6348            final String authority = uri.getAuthority();
6349            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6350            if (pi == null) {
6351                Slog.w(TAG, "No content provider found for permission revoke: "
6352                        + uri.toSafeString());
6353                return;
6354            }
6355
6356            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6357        }
6358    }
6359
6360    /**
6361     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6362     * given package.
6363     *
6364     * @param packageName Package name to match, or {@code null} to apply to all
6365     *            packages.
6366     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6367     *            to all users.
6368     * @param persistable If persistable grants should be removed.
6369     */
6370    private void removeUriPermissionsForPackageLocked(
6371            String packageName, int userHandle, boolean persistable) {
6372        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6373            throw new IllegalArgumentException("Must narrow by either package or user");
6374        }
6375
6376        boolean persistChanged = false;
6377
6378        final int size = mGrantedUriPermissions.size();
6379        for (int i = 0; i < size; i++) {
6380            // Only inspect grants matching user
6381            if (userHandle == UserHandle.USER_ALL
6382                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6383                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6384                        .values().iterator();
6385                while (it.hasNext()) {
6386                    final UriPermission perm = it.next();
6387
6388                    // Only inspect grants matching package
6389                    if (packageName == null || perm.sourcePkg.equals(packageName)
6390                            || perm.targetPkg.equals(packageName)) {
6391                        persistChanged |= perm.clearModes(~0, persistable);
6392
6393                        // Only remove when no modes remain; any persisted grants
6394                        // will keep this alive.
6395                        if (perm.modeFlags == 0) {
6396                            it.remove();
6397                        }
6398                    }
6399                }
6400            }
6401        }
6402
6403        if (persistChanged) {
6404            schedulePersistUriGrants();
6405        }
6406    }
6407
6408    @Override
6409    public IBinder newUriPermissionOwner(String name) {
6410        enforceNotIsolatedCaller("newUriPermissionOwner");
6411        synchronized(this) {
6412            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6413            return owner.getExternalTokenLocked();
6414        }
6415    }
6416
6417    @Override
6418    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6419            Uri uri, int modeFlags) {
6420        synchronized(this) {
6421            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6422            if (owner == null) {
6423                throw new IllegalArgumentException("Unknown owner: " + token);
6424            }
6425            if (fromUid != Binder.getCallingUid()) {
6426                if (Binder.getCallingUid() != Process.myUid()) {
6427                    // Only system code can grant URI permissions on behalf
6428                    // of other users.
6429                    throw new SecurityException("nice try");
6430                }
6431            }
6432            if (targetPkg == null) {
6433                throw new IllegalArgumentException("null target");
6434            }
6435            if (uri == null) {
6436                throw new IllegalArgumentException("null uri");
6437            }
6438
6439            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6440        }
6441    }
6442
6443    @Override
6444    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6445        synchronized(this) {
6446            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6447            if (owner == null) {
6448                throw new IllegalArgumentException("Unknown owner: " + token);
6449            }
6450
6451            if (uri == null) {
6452                owner.removeUriPermissionsLocked(mode);
6453            } else {
6454                owner.removeUriPermissionLocked(uri, mode);
6455            }
6456        }
6457    }
6458
6459    private void schedulePersistUriGrants() {
6460        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6461            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6462                    10 * DateUtils.SECOND_IN_MILLIS);
6463        }
6464    }
6465
6466    private void writeGrantedUriPermissions() {
6467        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6468
6469        // Snapshot permissions so we can persist without lock
6470        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6471        synchronized (this) {
6472            final int size = mGrantedUriPermissions.size();
6473            for (int i = 0 ; i < size; i++) {
6474                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6475                    if (perm.persistedModeFlags != 0) {
6476                        persist.add(perm.snapshot());
6477                    }
6478                }
6479            }
6480        }
6481
6482        FileOutputStream fos = null;
6483        try {
6484            fos = mGrantFile.startWrite();
6485
6486            XmlSerializer out = new FastXmlSerializer();
6487            out.setOutput(fos, "utf-8");
6488            out.startDocument(null, true);
6489            out.startTag(null, TAG_URI_GRANTS);
6490            for (UriPermission.Snapshot perm : persist) {
6491                out.startTag(null, TAG_URI_GRANT);
6492                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6493                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6494                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6495                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6496                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6497                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6498                out.endTag(null, TAG_URI_GRANT);
6499            }
6500            out.endTag(null, TAG_URI_GRANTS);
6501            out.endDocument();
6502
6503            mGrantFile.finishWrite(fos);
6504        } catch (IOException e) {
6505            if (fos != null) {
6506                mGrantFile.failWrite(fos);
6507            }
6508        }
6509    }
6510
6511    private void readGrantedUriPermissionsLocked() {
6512        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6513
6514        final long now = System.currentTimeMillis();
6515
6516        FileInputStream fis = null;
6517        try {
6518            fis = mGrantFile.openRead();
6519            final XmlPullParser in = Xml.newPullParser();
6520            in.setInput(fis, null);
6521
6522            int type;
6523            while ((type = in.next()) != END_DOCUMENT) {
6524                final String tag = in.getName();
6525                if (type == START_TAG) {
6526                    if (TAG_URI_GRANT.equals(tag)) {
6527                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6528                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6529                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6530                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6531                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6532                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6533
6534                        // Sanity check that provider still belongs to source package
6535                        final ProviderInfo pi = getProviderInfoLocked(
6536                                uri.getAuthority(), userHandle);
6537                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6538                            int targetUid = -1;
6539                            try {
6540                                targetUid = AppGlobals.getPackageManager()
6541                                        .getPackageUid(targetPkg, userHandle);
6542                            } catch (RemoteException e) {
6543                            }
6544                            if (targetUid != -1) {
6545                                final UriPermission perm = findOrCreateUriPermissionLocked(
6546                                        sourcePkg, targetPkg, targetUid, uri);
6547                                perm.initPersistedModes(modeFlags, createdTime);
6548                            }
6549                        } else {
6550                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6551                                    + " but instead found " + pi);
6552                        }
6553                    }
6554                }
6555            }
6556        } catch (FileNotFoundException e) {
6557            // Missing grants is okay
6558        } catch (IOException e) {
6559            Log.wtf(TAG, "Failed reading Uri grants", e);
6560        } catch (XmlPullParserException e) {
6561            Log.wtf(TAG, "Failed reading Uri grants", e);
6562        } finally {
6563            IoUtils.closeQuietly(fis);
6564        }
6565    }
6566
6567    @Override
6568    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6569        enforceNotIsolatedCaller("takePersistableUriPermission");
6570
6571        Preconditions.checkFlagsArgument(modeFlags,
6572                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6573
6574        synchronized (this) {
6575            final int callingUid = Binder.getCallingUid();
6576            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6577            if (perm == null) {
6578                throw new SecurityException("No permission grant found for UID " + callingUid
6579                        + " and Uri " + uri.toSafeString());
6580            }
6581
6582            boolean persistChanged = perm.takePersistableModes(modeFlags);
6583            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6584
6585            if (persistChanged) {
6586                schedulePersistUriGrants();
6587            }
6588        }
6589    }
6590
6591    @Override
6592    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6593        enforceNotIsolatedCaller("releasePersistableUriPermission");
6594
6595        Preconditions.checkFlagsArgument(modeFlags,
6596                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6597
6598        synchronized (this) {
6599            final int callingUid = Binder.getCallingUid();
6600
6601            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6602            if (perm == null) {
6603                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6604                        + uri.toSafeString());
6605                return;
6606            }
6607
6608            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6609            removeUriPermissionIfNeededLocked(perm);
6610            if (persistChanged) {
6611                schedulePersistUriGrants();
6612            }
6613        }
6614    }
6615
6616    /**
6617     * Prune any older {@link UriPermission} for the given UID until outstanding
6618     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6619     *
6620     * @return if any mutations occured that require persisting.
6621     */
6622    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6623        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6624        if (perms == null) return false;
6625        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6626
6627        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6628        for (UriPermission perm : perms.values()) {
6629            if (perm.persistedModeFlags != 0) {
6630                persisted.add(perm);
6631            }
6632        }
6633
6634        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6635        if (trimCount <= 0) return false;
6636
6637        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6638        for (int i = 0; i < trimCount; i++) {
6639            final UriPermission perm = persisted.get(i);
6640
6641            if (DEBUG_URI_PERMISSION) {
6642                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6643            }
6644
6645            perm.releasePersistableModes(~0);
6646            removeUriPermissionIfNeededLocked(perm);
6647        }
6648
6649        return true;
6650    }
6651
6652    @Override
6653    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6654            String packageName, boolean incoming) {
6655        enforceNotIsolatedCaller("getPersistedUriPermissions");
6656        Preconditions.checkNotNull(packageName, "packageName");
6657
6658        final int callingUid = Binder.getCallingUid();
6659        final IPackageManager pm = AppGlobals.getPackageManager();
6660        try {
6661            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6662            if (packageUid != callingUid) {
6663                throw new SecurityException(
6664                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6665            }
6666        } catch (RemoteException e) {
6667            throw new SecurityException("Failed to verify package name ownership");
6668        }
6669
6670        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6671        synchronized (this) {
6672            if (incoming) {
6673                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6674                if (perms == null) {
6675                    Slog.w(TAG, "No permission grants found for " + packageName);
6676                } else {
6677                    final int size = perms.size();
6678                    for (int i = 0; i < size; i++) {
6679                        final UriPermission perm = perms.valueAt(i);
6680                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6681                            result.add(perm.buildPersistedPublicApiObject());
6682                        }
6683                    }
6684                }
6685            } else {
6686                final int size = mGrantedUriPermissions.size();
6687                for (int i = 0; i < size; i++) {
6688                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6689                    final int permsSize = perms.size();
6690                    for (int j = 0; j < permsSize; j++) {
6691                        final UriPermission perm = perms.valueAt(j);
6692                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6693                            result.add(perm.buildPersistedPublicApiObject());
6694                        }
6695                    }
6696                }
6697            }
6698        }
6699        return new ParceledListSlice<android.content.UriPermission>(result);
6700    }
6701
6702    @Override
6703    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6704        synchronized (this) {
6705            ProcessRecord app =
6706                who != null ? getRecordForAppLocked(who) : null;
6707            if (app == null) return;
6708
6709            Message msg = Message.obtain();
6710            msg.what = WAIT_FOR_DEBUGGER_MSG;
6711            msg.obj = app;
6712            msg.arg1 = waiting ? 1 : 0;
6713            mHandler.sendMessage(msg);
6714        }
6715    }
6716
6717    @Override
6718    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6719        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6720        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6721        outInfo.availMem = Process.getFreeMemory();
6722        outInfo.totalMem = Process.getTotalMemory();
6723        outInfo.threshold = homeAppMem;
6724        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6725        outInfo.hiddenAppThreshold = cachedAppMem;
6726        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6727                ProcessList.SERVICE_ADJ);
6728        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6729                ProcessList.VISIBLE_APP_ADJ);
6730        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6731                ProcessList.FOREGROUND_APP_ADJ);
6732    }
6733
6734    // =========================================================
6735    // TASK MANAGEMENT
6736    // =========================================================
6737
6738    @Override
6739    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6740                         IThumbnailReceiver receiver) {
6741        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6742
6743        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6744        ActivityRecord topRecord = null;
6745
6746        synchronized(this) {
6747            if (localLOGV) Slog.v(
6748                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6749                + ", receiver=" + receiver);
6750
6751            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6752                    != PackageManager.PERMISSION_GRANTED) {
6753                if (receiver != null) {
6754                    // If the caller wants to wait for pending thumbnails,
6755                    // it ain't gonna get them.
6756                    try {
6757                        receiver.finished();
6758                    } catch (RemoteException ex) {
6759                    }
6760                }
6761                String msg = "Permission Denial: getTasks() from pid="
6762                        + Binder.getCallingPid()
6763                        + ", uid=" + Binder.getCallingUid()
6764                        + " requires " + android.Manifest.permission.GET_TASKS;
6765                Slog.w(TAG, msg);
6766                throw new SecurityException(msg);
6767            }
6768
6769            // TODO: Improve with MRU list from all ActivityStacks.
6770            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6771
6772            if (!pending.pendingRecords.isEmpty()) {
6773                mPendingThumbnails.add(pending);
6774            }
6775        }
6776
6777        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6778
6779        if (topRecord != null) {
6780            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6781            try {
6782                IApplicationThread topThumbnail = topRecord.app.thread;
6783                topThumbnail.requestThumbnail(topRecord.appToken);
6784            } catch (Exception e) {
6785                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6786                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6787            }
6788        }
6789
6790        if (pending == null && receiver != null) {
6791            // In this case all thumbnails were available and the client
6792            // is being asked to be told when the remaining ones come in...
6793            // which is unusually, since the top-most currently running
6794            // activity should never have a canned thumbnail!  Oh well.
6795            try {
6796                receiver.finished();
6797            } catch (RemoteException ex) {
6798            }
6799        }
6800
6801        return list;
6802    }
6803
6804    TaskRecord getMostRecentTask() {
6805        return mRecentTasks.get(0);
6806    }
6807
6808    @Override
6809    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6810            int flags, int userId) {
6811        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6812                false, true, "getRecentTasks", null);
6813
6814        synchronized (this) {
6815            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6816                    "getRecentTasks()");
6817            final boolean detailed = checkCallingPermission(
6818                    android.Manifest.permission.GET_DETAILED_TASKS)
6819                    == PackageManager.PERMISSION_GRANTED;
6820
6821            IPackageManager pm = AppGlobals.getPackageManager();
6822
6823            final int N = mRecentTasks.size();
6824            ArrayList<ActivityManager.RecentTaskInfo> res
6825                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6826                            maxNum < N ? maxNum : N);
6827            for (int i=0; i<N && maxNum > 0; i++) {
6828                TaskRecord tr = mRecentTasks.get(i);
6829                // Only add calling user's recent tasks
6830                if (tr.userId != userId) continue;
6831                // Return the entry if desired by the caller.  We always return
6832                // the first entry, because callers always expect this to be the
6833                // foreground app.  We may filter others if the caller has
6834                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6835                // we should exclude the entry.
6836
6837                if (i == 0
6838                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6839                        || (tr.intent == null)
6840                        || ((tr.intent.getFlags()
6841                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6842                    ActivityManager.RecentTaskInfo rti
6843                            = new ActivityManager.RecentTaskInfo();
6844                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6845                    rti.persistentId = tr.taskId;
6846                    rti.baseIntent = new Intent(
6847                            tr.intent != null ? tr.intent : tr.affinityIntent);
6848                    if (!detailed) {
6849                        rti.baseIntent.replaceExtras((Bundle)null);
6850                    }
6851                    rti.origActivity = tr.origActivity;
6852                    rti.description = tr.lastDescription;
6853                    rti.stackId = tr.stack.mStackId;
6854
6855                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6856                        // Check whether this activity is currently available.
6857                        try {
6858                            if (rti.origActivity != null) {
6859                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6860                                        == null) {
6861                                    continue;
6862                                }
6863                            } else if (rti.baseIntent != null) {
6864                                if (pm.queryIntentActivities(rti.baseIntent,
6865                                        null, 0, userId) == null) {
6866                                    continue;
6867                                }
6868                            }
6869                        } catch (RemoteException e) {
6870                            // Will never happen.
6871                        }
6872                    }
6873
6874                    res.add(rti);
6875                    maxNum--;
6876                }
6877            }
6878            return res;
6879        }
6880    }
6881
6882    private TaskRecord recentTaskForIdLocked(int id) {
6883        final int N = mRecentTasks.size();
6884            for (int i=0; i<N; i++) {
6885                TaskRecord tr = mRecentTasks.get(i);
6886                if (tr.taskId == id) {
6887                    return tr;
6888                }
6889            }
6890            return null;
6891    }
6892
6893    @Override
6894    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6895        synchronized (this) {
6896            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6897                    "getTaskThumbnails()");
6898            TaskRecord tr = recentTaskForIdLocked(id);
6899            if (tr != null) {
6900                return tr.getTaskThumbnailsLocked();
6901            }
6902        }
6903        return null;
6904    }
6905
6906    @Override
6907    public Bitmap getTaskTopThumbnail(int id) {
6908        synchronized (this) {
6909            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6910                    "getTaskTopThumbnail()");
6911            TaskRecord tr = recentTaskForIdLocked(id);
6912            if (tr != null) {
6913                return tr.getTaskTopThumbnailLocked();
6914            }
6915        }
6916        return null;
6917    }
6918
6919    @Override
6920    public boolean removeSubTask(int taskId, int subTaskIndex) {
6921        synchronized (this) {
6922            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6923                    "removeSubTask()");
6924            long ident = Binder.clearCallingIdentity();
6925            try {
6926                TaskRecord tr = recentTaskForIdLocked(taskId);
6927                if (tr != null) {
6928                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6929                }
6930                return false;
6931            } finally {
6932                Binder.restoreCallingIdentity(ident);
6933            }
6934        }
6935    }
6936
6937    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6938        if (!pr.killedByAm) {
6939            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6940            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6941                    pr.processName, pr.setAdj, reason);
6942            pr.killedByAm = true;
6943            Process.killProcessQuiet(pr.pid);
6944        }
6945    }
6946
6947    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6948        tr.disposeThumbnail();
6949        mRecentTasks.remove(tr);
6950        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6951        Intent baseIntent = new Intent(
6952                tr.intent != null ? tr.intent : tr.affinityIntent);
6953        ComponentName component = baseIntent.getComponent();
6954        if (component == null) {
6955            Slog.w(TAG, "Now component for base intent of task: " + tr);
6956            return;
6957        }
6958
6959        // Find any running services associated with this app.
6960        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6961
6962        if (killProcesses) {
6963            // Find any running processes associated with this app.
6964            final String pkg = component.getPackageName();
6965            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6966            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6967            for (int i=0; i<pmap.size(); i++) {
6968                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6969                for (int j=0; j<uids.size(); j++) {
6970                    ProcessRecord proc = uids.valueAt(j);
6971                    if (proc.userId != tr.userId) {
6972                        continue;
6973                    }
6974                    if (!proc.pkgList.containsKey(pkg)) {
6975                        continue;
6976                    }
6977                    procs.add(proc);
6978                }
6979            }
6980
6981            // Kill the running processes.
6982            for (int i=0; i<procs.size(); i++) {
6983                ProcessRecord pr = procs.get(i);
6984                if (pr == mHomeProcess) {
6985                    // Don't kill the home process along with tasks from the same package.
6986                    continue;
6987                }
6988                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6989                    killUnneededProcessLocked(pr, "remove task");
6990                } else {
6991                    pr.waitingToKill = "remove task";
6992                }
6993            }
6994        }
6995    }
6996
6997    @Override
6998    public boolean removeTask(int taskId, int flags) {
6999        synchronized (this) {
7000            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7001                    "removeTask()");
7002            long ident = Binder.clearCallingIdentity();
7003            try {
7004                TaskRecord tr = recentTaskForIdLocked(taskId);
7005                if (tr != null) {
7006                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7007                    if (r != null) {
7008                        cleanUpRemovedTaskLocked(tr, flags);
7009                        return true;
7010                    }
7011                    if (tr.mActivities.size() == 0) {
7012                        // Caller is just removing a recent task that is
7013                        // not actively running.  That is easy!
7014                        cleanUpRemovedTaskLocked(tr, flags);
7015                        return true;
7016                    }
7017                    Slog.w(TAG, "removeTask: task " + taskId
7018                            + " does not have activities to remove, "
7019                            + " but numActivities=" + tr.numActivities
7020                            + ": " + tr);
7021                }
7022            } finally {
7023                Binder.restoreCallingIdentity(ident);
7024            }
7025        }
7026        return false;
7027    }
7028
7029    /**
7030     * TODO: Add mController hook
7031     */
7032    @Override
7033    public void moveTaskToFront(int task, int flags, Bundle options) {
7034        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7035                "moveTaskToFront()");
7036
7037        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
7038        synchronized(this) {
7039            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7040                    Binder.getCallingUid(), "Task to front")) {
7041                ActivityOptions.abort(options);
7042                return;
7043            }
7044            final long origId = Binder.clearCallingIdentity();
7045            try {
7046                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7047            } finally {
7048                Binder.restoreCallingIdentity(origId);
7049            }
7050            ActivityOptions.abort(options);
7051        }
7052    }
7053
7054    @Override
7055    public void moveTaskToBack(int taskId) {
7056        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7057                "moveTaskToBack()");
7058
7059        synchronized(this) {
7060            TaskRecord tr = recentTaskForIdLocked(taskId);
7061            if (tr != null) {
7062                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7063                ActivityStack stack = tr.stack;
7064                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7065                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7066                            Binder.getCallingUid(), "Task to back")) {
7067                        return;
7068                    }
7069                }
7070                final long origId = Binder.clearCallingIdentity();
7071                try {
7072                    stack.moveTaskToBackLocked(taskId, null);
7073                } finally {
7074                    Binder.restoreCallingIdentity(origId);
7075                }
7076            }
7077        }
7078    }
7079
7080    /**
7081     * Moves an activity, and all of the other activities within the same task, to the bottom
7082     * of the history stack.  The activity's order within the task is unchanged.
7083     *
7084     * @param token A reference to the activity we wish to move
7085     * @param nonRoot If false then this only works if the activity is the root
7086     *                of a task; if true it will work for any activity in a task.
7087     * @return Returns true if the move completed, false if not.
7088     */
7089    @Override
7090    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7091        enforceNotIsolatedCaller("moveActivityTaskToBack");
7092        synchronized(this) {
7093            final long origId = Binder.clearCallingIdentity();
7094            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7095            if (taskId >= 0) {
7096                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7097            }
7098            Binder.restoreCallingIdentity(origId);
7099        }
7100        return false;
7101    }
7102
7103    @Override
7104    public void moveTaskBackwards(int task) {
7105        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7106                "moveTaskBackwards()");
7107
7108        synchronized(this) {
7109            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7110                    Binder.getCallingUid(), "Task backwards")) {
7111                return;
7112            }
7113            final long origId = Binder.clearCallingIdentity();
7114            moveTaskBackwardsLocked(task);
7115            Binder.restoreCallingIdentity(origId);
7116        }
7117    }
7118
7119    private final void moveTaskBackwardsLocked(int task) {
7120        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7121    }
7122
7123    @Override
7124    public IBinder getHomeActivityToken() throws RemoteException {
7125        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7126                "getHomeActivityToken()");
7127        synchronized (this) {
7128            return mStackSupervisor.getHomeActivityToken();
7129        }
7130    }
7131
7132    @Override
7133    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7134            IActivityContainerCallback callback) throws RemoteException {
7135        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7136                "createActivityContainer()");
7137        synchronized (this) {
7138            if (parentActivityToken == null) {
7139                throw new IllegalArgumentException("parent token must not be null");
7140            }
7141            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7142            if (r == null) {
7143                return null;
7144            }
7145            return mStackSupervisor.createActivityContainer(r, callback);
7146        }
7147    }
7148
7149    @Override
7150    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7151        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7152                "deleteActivityContainer()");
7153        synchronized (this) {
7154            mStackSupervisor.deleteActivityContainer(container);
7155        }
7156    }
7157
7158    @Override
7159    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7160            throws RemoteException {
7161        synchronized (this) {
7162            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7163            if (stack != null) {
7164                return stack.mActivityContainer;
7165            }
7166            return null;
7167        }
7168    }
7169
7170    @Override
7171    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7172        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7173                "moveTaskToStack()");
7174        if (stackId == HOME_STACK_ID) {
7175            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7176                    new RuntimeException("here").fillInStackTrace());
7177        }
7178        synchronized (this) {
7179            long ident = Binder.clearCallingIdentity();
7180            try {
7181                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7182                        + stackId + " toTop=" + toTop);
7183                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7184            } finally {
7185                Binder.restoreCallingIdentity(ident);
7186            }
7187        }
7188    }
7189
7190    @Override
7191    public void resizeStack(int stackBoxId, Rect bounds) {
7192        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7193                "resizeStackBox()");
7194        long ident = Binder.clearCallingIdentity();
7195        try {
7196            mWindowManager.resizeStack(stackBoxId, bounds);
7197        } finally {
7198            Binder.restoreCallingIdentity(ident);
7199        }
7200    }
7201
7202    @Override
7203    public List<StackInfo> getAllStackInfos() {
7204        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7205                "getAllStackInfos()");
7206        long ident = Binder.clearCallingIdentity();
7207        try {
7208            synchronized (this) {
7209                return mStackSupervisor.getAllStackInfosLocked();
7210            }
7211        } finally {
7212            Binder.restoreCallingIdentity(ident);
7213        }
7214    }
7215
7216    @Override
7217    public StackInfo getStackInfo(int stackId) {
7218        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7219                "getStackInfo()");
7220        long ident = Binder.clearCallingIdentity();
7221        try {
7222            synchronized (this) {
7223                return mStackSupervisor.getStackInfoLocked(stackId);
7224            }
7225        } finally {
7226            Binder.restoreCallingIdentity(ident);
7227        }
7228    }
7229
7230    @Override
7231    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7232        synchronized(this) {
7233            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7234        }
7235    }
7236
7237    // =========================================================
7238    // THUMBNAILS
7239    // =========================================================
7240
7241    public void reportThumbnail(IBinder token,
7242            Bitmap thumbnail, CharSequence description) {
7243        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7244        final long origId = Binder.clearCallingIdentity();
7245        sendPendingThumbnail(null, token, thumbnail, description, true);
7246        Binder.restoreCallingIdentity(origId);
7247    }
7248
7249    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7250            Bitmap thumbnail, CharSequence description, boolean always) {
7251        TaskRecord task;
7252        ArrayList<PendingThumbnailsRecord> receivers = null;
7253
7254        //System.out.println("Send pending thumbnail: " + r);
7255
7256        synchronized(this) {
7257            if (r == null) {
7258                r = ActivityRecord.isInStackLocked(token);
7259                if (r == null) {
7260                    return;
7261                }
7262            }
7263            if (thumbnail == null && r.thumbHolder != null) {
7264                thumbnail = r.thumbHolder.lastThumbnail;
7265                description = r.thumbHolder.lastDescription;
7266            }
7267            if (thumbnail == null && !always) {
7268                // If there is no thumbnail, and this entry is not actually
7269                // going away, then abort for now and pick up the next
7270                // thumbnail we get.
7271                return;
7272            }
7273            task = r.task;
7274
7275            int N = mPendingThumbnails.size();
7276            int i=0;
7277            while (i<N) {
7278                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7279                //System.out.println("Looking in " + pr.pendingRecords);
7280                if (pr.pendingRecords.remove(r)) {
7281                    if (receivers == null) {
7282                        receivers = new ArrayList<PendingThumbnailsRecord>();
7283                    }
7284                    receivers.add(pr);
7285                    if (pr.pendingRecords.size() == 0) {
7286                        pr.finished = true;
7287                        mPendingThumbnails.remove(i);
7288                        N--;
7289                        continue;
7290                    }
7291                }
7292                i++;
7293            }
7294        }
7295
7296        if (receivers != null) {
7297            final int N = receivers.size();
7298            for (int i=0; i<N; i++) {
7299                try {
7300                    PendingThumbnailsRecord pr = receivers.get(i);
7301                    pr.receiver.newThumbnail(
7302                        task != null ? task.taskId : -1, thumbnail, description);
7303                    if (pr.finished) {
7304                        pr.receiver.finished();
7305                    }
7306                } catch (Exception e) {
7307                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7308                }
7309            }
7310        }
7311    }
7312
7313    // =========================================================
7314    // CONTENT PROVIDERS
7315    // =========================================================
7316
7317    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7318        List<ProviderInfo> providers = null;
7319        try {
7320            providers = AppGlobals.getPackageManager().
7321                queryContentProviders(app.processName, app.uid,
7322                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7323        } catch (RemoteException ex) {
7324        }
7325        if (DEBUG_MU)
7326            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7327        int userId = app.userId;
7328        if (providers != null) {
7329            int N = providers.size();
7330            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7331            for (int i=0; i<N; i++) {
7332                ProviderInfo cpi =
7333                    (ProviderInfo)providers.get(i);
7334                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7335                        cpi.name, cpi.flags);
7336                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7337                    // This is a singleton provider, but a user besides the
7338                    // default user is asking to initialize a process it runs
7339                    // in...  well, no, it doesn't actually run in this process,
7340                    // it runs in the process of the default user.  Get rid of it.
7341                    providers.remove(i);
7342                    N--;
7343                    i--;
7344                    continue;
7345                }
7346
7347                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7348                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7349                if (cpr == null) {
7350                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7351                    mProviderMap.putProviderByClass(comp, cpr);
7352                }
7353                if (DEBUG_MU)
7354                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7355                app.pubProviders.put(cpi.name, cpr);
7356                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7357                    // Don't add this if it is a platform component that is marked
7358                    // to run in multiple processes, because this is actually
7359                    // part of the framework so doesn't make sense to track as a
7360                    // separate apk in the process.
7361                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7362                }
7363                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7364            }
7365        }
7366        return providers;
7367    }
7368
7369    /**
7370     * Check if {@link ProcessRecord} has a possible chance at accessing the
7371     * given {@link ProviderInfo}. Final permission checking is always done
7372     * in {@link ContentProvider}.
7373     */
7374    private final String checkContentProviderPermissionLocked(
7375            ProviderInfo cpi, ProcessRecord r) {
7376        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7377        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7378        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7379                cpi.applicationInfo.uid, cpi.exported)
7380                == PackageManager.PERMISSION_GRANTED) {
7381            return null;
7382        }
7383        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7384                cpi.applicationInfo.uid, cpi.exported)
7385                == PackageManager.PERMISSION_GRANTED) {
7386            return null;
7387        }
7388
7389        PathPermission[] pps = cpi.pathPermissions;
7390        if (pps != null) {
7391            int i = pps.length;
7392            while (i > 0) {
7393                i--;
7394                PathPermission pp = pps[i];
7395                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7396                        cpi.applicationInfo.uid, cpi.exported)
7397                        == PackageManager.PERMISSION_GRANTED) {
7398                    return null;
7399                }
7400                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7401                        cpi.applicationInfo.uid, cpi.exported)
7402                        == PackageManager.PERMISSION_GRANTED) {
7403                    return null;
7404                }
7405            }
7406        }
7407
7408        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7409        if (perms != null) {
7410            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7411                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7412                    return null;
7413                }
7414            }
7415        }
7416
7417        String msg;
7418        if (!cpi.exported) {
7419            msg = "Permission Denial: opening provider " + cpi.name
7420                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7421                    + ", uid=" + callingUid + ") that is not exported from uid "
7422                    + cpi.applicationInfo.uid;
7423        } else {
7424            msg = "Permission Denial: opening provider " + cpi.name
7425                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7426                    + ", uid=" + callingUid + ") requires "
7427                    + cpi.readPermission + " or " + cpi.writePermission;
7428        }
7429        Slog.w(TAG, msg);
7430        return msg;
7431    }
7432
7433    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7434            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7435        if (r != null) {
7436            for (int i=0; i<r.conProviders.size(); i++) {
7437                ContentProviderConnection conn = r.conProviders.get(i);
7438                if (conn.provider == cpr) {
7439                    if (DEBUG_PROVIDER) Slog.v(TAG,
7440                            "Adding provider requested by "
7441                            + r.processName + " from process "
7442                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7443                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7444                    if (stable) {
7445                        conn.stableCount++;
7446                        conn.numStableIncs++;
7447                    } else {
7448                        conn.unstableCount++;
7449                        conn.numUnstableIncs++;
7450                    }
7451                    return conn;
7452                }
7453            }
7454            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7455            if (stable) {
7456                conn.stableCount = 1;
7457                conn.numStableIncs = 1;
7458            } else {
7459                conn.unstableCount = 1;
7460                conn.numUnstableIncs = 1;
7461            }
7462            cpr.connections.add(conn);
7463            r.conProviders.add(conn);
7464            return conn;
7465        }
7466        cpr.addExternalProcessHandleLocked(externalProcessToken);
7467        return null;
7468    }
7469
7470    boolean decProviderCountLocked(ContentProviderConnection conn,
7471            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7472        if (conn != null) {
7473            cpr = conn.provider;
7474            if (DEBUG_PROVIDER) Slog.v(TAG,
7475                    "Removing provider requested by "
7476                    + conn.client.processName + " from process "
7477                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7478                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7479            if (stable) {
7480                conn.stableCount--;
7481            } else {
7482                conn.unstableCount--;
7483            }
7484            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7485                cpr.connections.remove(conn);
7486                conn.client.conProviders.remove(conn);
7487                return true;
7488            }
7489            return false;
7490        }
7491        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7492        return false;
7493    }
7494
7495    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7496            String name, IBinder token, boolean stable, int userId) {
7497        ContentProviderRecord cpr;
7498        ContentProviderConnection conn = null;
7499        ProviderInfo cpi = null;
7500
7501        synchronized(this) {
7502            ProcessRecord r = null;
7503            if (caller != null) {
7504                r = getRecordForAppLocked(caller);
7505                if (r == null) {
7506                    throw new SecurityException(
7507                            "Unable to find app for caller " + caller
7508                          + " (pid=" + Binder.getCallingPid()
7509                          + ") when getting content provider " + name);
7510                }
7511            }
7512
7513            // First check if this content provider has been published...
7514            cpr = mProviderMap.getProviderByName(name, userId);
7515            boolean providerRunning = cpr != null;
7516            if (providerRunning) {
7517                cpi = cpr.info;
7518                String msg;
7519                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7520                    throw new SecurityException(msg);
7521                }
7522
7523                if (r != null && cpr.canRunHere(r)) {
7524                    // This provider has been published or is in the process
7525                    // of being published...  but it is also allowed to run
7526                    // in the caller's process, so don't make a connection
7527                    // and just let the caller instantiate its own instance.
7528                    ContentProviderHolder holder = cpr.newHolder(null);
7529                    // don't give caller the provider object, it needs
7530                    // to make its own.
7531                    holder.provider = null;
7532                    return holder;
7533                }
7534
7535                final long origId = Binder.clearCallingIdentity();
7536
7537                // In this case the provider instance already exists, so we can
7538                // return it right away.
7539                conn = incProviderCountLocked(r, cpr, token, stable);
7540                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7541                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7542                        // If this is a perceptible app accessing the provider,
7543                        // make sure to count it as being accessed and thus
7544                        // back up on the LRU list.  This is good because
7545                        // content providers are often expensive to start.
7546                        updateLruProcessLocked(cpr.proc, false, null);
7547                    }
7548                }
7549
7550                if (cpr.proc != null) {
7551                    if (false) {
7552                        if (cpr.name.flattenToShortString().equals(
7553                                "com.android.providers.calendar/.CalendarProvider2")) {
7554                            Slog.v(TAG, "****************** KILLING "
7555                                + cpr.name.flattenToShortString());
7556                            Process.killProcess(cpr.proc.pid);
7557                        }
7558                    }
7559                    boolean success = updateOomAdjLocked(cpr.proc);
7560                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7561                    // NOTE: there is still a race here where a signal could be
7562                    // pending on the process even though we managed to update its
7563                    // adj level.  Not sure what to do about this, but at least
7564                    // the race is now smaller.
7565                    if (!success) {
7566                        // Uh oh...  it looks like the provider's process
7567                        // has been killed on us.  We need to wait for a new
7568                        // process to be started, and make sure its death
7569                        // doesn't kill our process.
7570                        Slog.i(TAG,
7571                                "Existing provider " + cpr.name.flattenToShortString()
7572                                + " is crashing; detaching " + r);
7573                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7574                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7575                        if (!lastRef) {
7576                            // This wasn't the last ref our process had on
7577                            // the provider...  we have now been killed, bail.
7578                            return null;
7579                        }
7580                        providerRunning = false;
7581                        conn = null;
7582                    }
7583                }
7584
7585                Binder.restoreCallingIdentity(origId);
7586            }
7587
7588            boolean singleton;
7589            if (!providerRunning) {
7590                try {
7591                    cpi = AppGlobals.getPackageManager().
7592                        resolveContentProvider(name,
7593                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7594                } catch (RemoteException ex) {
7595                }
7596                if (cpi == null) {
7597                    return null;
7598                }
7599                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7600                        cpi.name, cpi.flags);
7601                if (singleton) {
7602                    userId = 0;
7603                }
7604                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7605
7606                String msg;
7607                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7608                    throw new SecurityException(msg);
7609                }
7610
7611                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7612                        && !cpi.processName.equals("system")) {
7613                    // If this content provider does not run in the system
7614                    // process, and the system is not yet ready to run other
7615                    // processes, then fail fast instead of hanging.
7616                    throw new IllegalArgumentException(
7617                            "Attempt to launch content provider before system ready");
7618                }
7619
7620                // Make sure that the user who owns this provider is started.  If not,
7621                // we don't want to allow it to run.
7622                if (mStartedUsers.get(userId) == null) {
7623                    Slog.w(TAG, "Unable to launch app "
7624                            + cpi.applicationInfo.packageName + "/"
7625                            + cpi.applicationInfo.uid + " for provider "
7626                            + name + ": user " + userId + " is stopped");
7627                    return null;
7628                }
7629
7630                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7631                cpr = mProviderMap.getProviderByClass(comp, userId);
7632                final boolean firstClass = cpr == null;
7633                if (firstClass) {
7634                    try {
7635                        ApplicationInfo ai =
7636                            AppGlobals.getPackageManager().
7637                                getApplicationInfo(
7638                                        cpi.applicationInfo.packageName,
7639                                        STOCK_PM_FLAGS, userId);
7640                        if (ai == null) {
7641                            Slog.w(TAG, "No package info for content provider "
7642                                    + cpi.name);
7643                            return null;
7644                        }
7645                        ai = getAppInfoForUser(ai, userId);
7646                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7647                    } catch (RemoteException ex) {
7648                        // pm is in same process, this will never happen.
7649                    }
7650                }
7651
7652                if (r != null && cpr.canRunHere(r)) {
7653                    // If this is a multiprocess provider, then just return its
7654                    // info and allow the caller to instantiate it.  Only do
7655                    // this if the provider is the same user as the caller's
7656                    // process, or can run as root (so can be in any process).
7657                    return cpr.newHolder(null);
7658                }
7659
7660                if (DEBUG_PROVIDER) {
7661                    RuntimeException e = new RuntimeException("here");
7662                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7663                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7664                }
7665
7666                // This is single process, and our app is now connecting to it.
7667                // See if we are already in the process of launching this
7668                // provider.
7669                final int N = mLaunchingProviders.size();
7670                int i;
7671                for (i=0; i<N; i++) {
7672                    if (mLaunchingProviders.get(i) == cpr) {
7673                        break;
7674                    }
7675                }
7676
7677                // If the provider is not already being launched, then get it
7678                // started.
7679                if (i >= N) {
7680                    final long origId = Binder.clearCallingIdentity();
7681
7682                    try {
7683                        // Content provider is now in use, its package can't be stopped.
7684                        try {
7685                            AppGlobals.getPackageManager().setPackageStoppedState(
7686                                    cpr.appInfo.packageName, false, userId);
7687                        } catch (RemoteException e) {
7688                        } catch (IllegalArgumentException e) {
7689                            Slog.w(TAG, "Failed trying to unstop package "
7690                                    + cpr.appInfo.packageName + ": " + e);
7691                        }
7692
7693                        // Use existing process if already started
7694                        ProcessRecord proc = getProcessRecordLocked(
7695                                cpi.processName, cpr.appInfo.uid, false);
7696                        if (proc != null && proc.thread != null) {
7697                            if (DEBUG_PROVIDER) {
7698                                Slog.d(TAG, "Installing in existing process " + proc);
7699                            }
7700                            proc.pubProviders.put(cpi.name, cpr);
7701                            try {
7702                                proc.thread.scheduleInstallProvider(cpi);
7703                            } catch (RemoteException e) {
7704                            }
7705                        } else {
7706                            proc = startProcessLocked(cpi.processName,
7707                                    cpr.appInfo, false, 0, "content provider",
7708                                    new ComponentName(cpi.applicationInfo.packageName,
7709                                            cpi.name), false, false, false);
7710                            if (proc == null) {
7711                                Slog.w(TAG, "Unable to launch app "
7712                                        + cpi.applicationInfo.packageName + "/"
7713                                        + cpi.applicationInfo.uid + " for provider "
7714                                        + name + ": process is bad");
7715                                return null;
7716                            }
7717                        }
7718                        cpr.launchingApp = proc;
7719                        mLaunchingProviders.add(cpr);
7720                    } finally {
7721                        Binder.restoreCallingIdentity(origId);
7722                    }
7723                }
7724
7725                // Make sure the provider is published (the same provider class
7726                // may be published under multiple names).
7727                if (firstClass) {
7728                    mProviderMap.putProviderByClass(comp, cpr);
7729                }
7730
7731                mProviderMap.putProviderByName(name, cpr);
7732                conn = incProviderCountLocked(r, cpr, token, stable);
7733                if (conn != null) {
7734                    conn.waiting = true;
7735                }
7736            }
7737        }
7738
7739        // Wait for the provider to be published...
7740        synchronized (cpr) {
7741            while (cpr.provider == null) {
7742                if (cpr.launchingApp == null) {
7743                    Slog.w(TAG, "Unable to launch app "
7744                            + cpi.applicationInfo.packageName + "/"
7745                            + cpi.applicationInfo.uid + " for provider "
7746                            + name + ": launching app became null");
7747                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7748                            UserHandle.getUserId(cpi.applicationInfo.uid),
7749                            cpi.applicationInfo.packageName,
7750                            cpi.applicationInfo.uid, name);
7751                    return null;
7752                }
7753                try {
7754                    if (DEBUG_MU) {
7755                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7756                                + cpr.launchingApp);
7757                    }
7758                    if (conn != null) {
7759                        conn.waiting = true;
7760                    }
7761                    cpr.wait();
7762                } catch (InterruptedException ex) {
7763                } finally {
7764                    if (conn != null) {
7765                        conn.waiting = false;
7766                    }
7767                }
7768            }
7769        }
7770        return cpr != null ? cpr.newHolder(conn) : null;
7771    }
7772
7773    public final ContentProviderHolder getContentProvider(
7774            IApplicationThread caller, String name, int userId, boolean stable) {
7775        enforceNotIsolatedCaller("getContentProvider");
7776        if (caller == null) {
7777            String msg = "null IApplicationThread when getting content provider "
7778                    + name;
7779            Slog.w(TAG, msg);
7780            throw new SecurityException(msg);
7781        }
7782
7783        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7784                false, true, "getContentProvider", null);
7785        return getContentProviderImpl(caller, name, null, stable, userId);
7786    }
7787
7788    public ContentProviderHolder getContentProviderExternal(
7789            String name, int userId, IBinder token) {
7790        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7791            "Do not have permission in call getContentProviderExternal()");
7792        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7793                false, true, "getContentProvider", null);
7794        return getContentProviderExternalUnchecked(name, token, userId);
7795    }
7796
7797    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7798            IBinder token, int userId) {
7799        return getContentProviderImpl(null, name, token, true, userId);
7800    }
7801
7802    /**
7803     * Drop a content provider from a ProcessRecord's bookkeeping
7804     */
7805    public void removeContentProvider(IBinder connection, boolean stable) {
7806        enforceNotIsolatedCaller("removeContentProvider");
7807        long ident = Binder.clearCallingIdentity();
7808        try {
7809            synchronized (this) {
7810                ContentProviderConnection conn;
7811                try {
7812                    conn = (ContentProviderConnection)connection;
7813                } catch (ClassCastException e) {
7814                    String msg ="removeContentProvider: " + connection
7815                            + " not a ContentProviderConnection";
7816                    Slog.w(TAG, msg);
7817                    throw new IllegalArgumentException(msg);
7818                }
7819                if (conn == null) {
7820                    throw new NullPointerException("connection is null");
7821                }
7822                if (decProviderCountLocked(conn, null, null, stable)) {
7823                    updateOomAdjLocked();
7824                }
7825            }
7826        } finally {
7827            Binder.restoreCallingIdentity(ident);
7828        }
7829    }
7830
7831    public void removeContentProviderExternal(String name, IBinder token) {
7832        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7833            "Do not have permission in call removeContentProviderExternal()");
7834        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7835    }
7836
7837    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7838        synchronized (this) {
7839            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7840            if(cpr == null) {
7841                //remove from mProvidersByClass
7842                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7843                return;
7844            }
7845
7846            //update content provider record entry info
7847            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7848            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7849            if (localCpr.hasExternalProcessHandles()) {
7850                if (localCpr.removeExternalProcessHandleLocked(token)) {
7851                    updateOomAdjLocked();
7852                } else {
7853                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7854                            + " with no external reference for token: "
7855                            + token + ".");
7856                }
7857            } else {
7858                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7859                        + " with no external references.");
7860            }
7861        }
7862    }
7863
7864    public final void publishContentProviders(IApplicationThread caller,
7865            List<ContentProviderHolder> providers) {
7866        if (providers == null) {
7867            return;
7868        }
7869
7870        enforceNotIsolatedCaller("publishContentProviders");
7871        synchronized (this) {
7872            final ProcessRecord r = getRecordForAppLocked(caller);
7873            if (DEBUG_MU)
7874                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7875            if (r == null) {
7876                throw new SecurityException(
7877                        "Unable to find app for caller " + caller
7878                      + " (pid=" + Binder.getCallingPid()
7879                      + ") when publishing content providers");
7880            }
7881
7882            final long origId = Binder.clearCallingIdentity();
7883
7884            final int N = providers.size();
7885            for (int i=0; i<N; i++) {
7886                ContentProviderHolder src = providers.get(i);
7887                if (src == null || src.info == null || src.provider == null) {
7888                    continue;
7889                }
7890                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7891                if (DEBUG_MU)
7892                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7893                if (dst != null) {
7894                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7895                    mProviderMap.putProviderByClass(comp, dst);
7896                    String names[] = dst.info.authority.split(";");
7897                    for (int j = 0; j < names.length; j++) {
7898                        mProviderMap.putProviderByName(names[j], dst);
7899                    }
7900
7901                    int NL = mLaunchingProviders.size();
7902                    int j;
7903                    for (j=0; j<NL; j++) {
7904                        if (mLaunchingProviders.get(j) == dst) {
7905                            mLaunchingProviders.remove(j);
7906                            j--;
7907                            NL--;
7908                        }
7909                    }
7910                    synchronized (dst) {
7911                        dst.provider = src.provider;
7912                        dst.proc = r;
7913                        dst.notifyAll();
7914                    }
7915                    updateOomAdjLocked(r);
7916                }
7917            }
7918
7919            Binder.restoreCallingIdentity(origId);
7920        }
7921    }
7922
7923    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7924        ContentProviderConnection conn;
7925        try {
7926            conn = (ContentProviderConnection)connection;
7927        } catch (ClassCastException e) {
7928            String msg ="refContentProvider: " + connection
7929                    + " not a ContentProviderConnection";
7930            Slog.w(TAG, msg);
7931            throw new IllegalArgumentException(msg);
7932        }
7933        if (conn == null) {
7934            throw new NullPointerException("connection is null");
7935        }
7936
7937        synchronized (this) {
7938            if (stable > 0) {
7939                conn.numStableIncs += stable;
7940            }
7941            stable = conn.stableCount + stable;
7942            if (stable < 0) {
7943                throw new IllegalStateException("stableCount < 0: " + stable);
7944            }
7945
7946            if (unstable > 0) {
7947                conn.numUnstableIncs += unstable;
7948            }
7949            unstable = conn.unstableCount + unstable;
7950            if (unstable < 0) {
7951                throw new IllegalStateException("unstableCount < 0: " + unstable);
7952            }
7953
7954            if ((stable+unstable) <= 0) {
7955                throw new IllegalStateException("ref counts can't go to zero here: stable="
7956                        + stable + " unstable=" + unstable);
7957            }
7958            conn.stableCount = stable;
7959            conn.unstableCount = unstable;
7960            return !conn.dead;
7961        }
7962    }
7963
7964    public void unstableProviderDied(IBinder connection) {
7965        ContentProviderConnection conn;
7966        try {
7967            conn = (ContentProviderConnection)connection;
7968        } catch (ClassCastException e) {
7969            String msg ="refContentProvider: " + connection
7970                    + " not a ContentProviderConnection";
7971            Slog.w(TAG, msg);
7972            throw new IllegalArgumentException(msg);
7973        }
7974        if (conn == null) {
7975            throw new NullPointerException("connection is null");
7976        }
7977
7978        // Safely retrieve the content provider associated with the connection.
7979        IContentProvider provider;
7980        synchronized (this) {
7981            provider = conn.provider.provider;
7982        }
7983
7984        if (provider == null) {
7985            // Um, yeah, we're way ahead of you.
7986            return;
7987        }
7988
7989        // Make sure the caller is being honest with us.
7990        if (provider.asBinder().pingBinder()) {
7991            // Er, no, still looks good to us.
7992            synchronized (this) {
7993                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7994                        + " says " + conn + " died, but we don't agree");
7995                return;
7996            }
7997        }
7998
7999        // Well look at that!  It's dead!
8000        synchronized (this) {
8001            if (conn.provider.provider != provider) {
8002                // But something changed...  good enough.
8003                return;
8004            }
8005
8006            ProcessRecord proc = conn.provider.proc;
8007            if (proc == null || proc.thread == null) {
8008                // Seems like the process is already cleaned up.
8009                return;
8010            }
8011
8012            // As far as we're concerned, this is just like receiving a
8013            // death notification...  just a bit prematurely.
8014            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8015                    + ") early provider death");
8016            final long ident = Binder.clearCallingIdentity();
8017            try {
8018                appDiedLocked(proc, proc.pid, proc.thread);
8019            } finally {
8020                Binder.restoreCallingIdentity(ident);
8021            }
8022        }
8023    }
8024
8025    @Override
8026    public void appNotRespondingViaProvider(IBinder connection) {
8027        enforceCallingPermission(
8028                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8029
8030        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8031        if (conn == null) {
8032            Slog.w(TAG, "ContentProviderConnection is null");
8033            return;
8034        }
8035
8036        final ProcessRecord host = conn.provider.proc;
8037        if (host == null) {
8038            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8039            return;
8040        }
8041
8042        final long token = Binder.clearCallingIdentity();
8043        try {
8044            appNotResponding(host, null, null, false, "ContentProvider not responding");
8045        } finally {
8046            Binder.restoreCallingIdentity(token);
8047        }
8048    }
8049
8050    public final void installSystemProviders() {
8051        List<ProviderInfo> providers;
8052        synchronized (this) {
8053            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8054            providers = generateApplicationProvidersLocked(app);
8055            if (providers != null) {
8056                for (int i=providers.size()-1; i>=0; i--) {
8057                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8058                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8059                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8060                                + ": not system .apk");
8061                        providers.remove(i);
8062                    }
8063                }
8064            }
8065        }
8066        if (providers != null) {
8067            mSystemThread.installSystemProviders(providers);
8068        }
8069
8070        mCoreSettingsObserver = new CoreSettingsObserver(this);
8071
8072        mUsageStatsService.monitorPackages();
8073    }
8074
8075    /**
8076     * Allows app to retrieve the MIME type of a URI without having permission
8077     * to access its content provider.
8078     *
8079     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8080     *
8081     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8082     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8083     */
8084    public String getProviderMimeType(Uri uri, int userId) {
8085        enforceNotIsolatedCaller("getProviderMimeType");
8086        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8087                userId, false, true, "getProviderMimeType", null);
8088        final String name = uri.getAuthority();
8089        final long ident = Binder.clearCallingIdentity();
8090        ContentProviderHolder holder = null;
8091
8092        try {
8093            holder = getContentProviderExternalUnchecked(name, null, userId);
8094            if (holder != null) {
8095                return holder.provider.getType(uri);
8096            }
8097        } catch (RemoteException e) {
8098            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8099            return null;
8100        } finally {
8101            if (holder != null) {
8102                removeContentProviderExternalUnchecked(name, null, userId);
8103            }
8104            Binder.restoreCallingIdentity(ident);
8105        }
8106
8107        return null;
8108    }
8109
8110    // =========================================================
8111    // GLOBAL MANAGEMENT
8112    // =========================================================
8113
8114    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8115            boolean isolated) {
8116        String proc = customProcess != null ? customProcess : info.processName;
8117        BatteryStatsImpl.Uid.Proc ps = null;
8118        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8119        int uid = info.uid;
8120        if (isolated) {
8121            int userId = UserHandle.getUserId(uid);
8122            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8123            while (true) {
8124                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8125                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8126                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8127                }
8128                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8129                mNextIsolatedProcessUid++;
8130                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8131                    // No process for this uid, use it.
8132                    break;
8133                }
8134                stepsLeft--;
8135                if (stepsLeft <= 0) {
8136                    return null;
8137                }
8138            }
8139        }
8140        return new ProcessRecord(stats, info, proc, uid);
8141    }
8142
8143    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8144        ProcessRecord app;
8145        if (!isolated) {
8146            app = getProcessRecordLocked(info.processName, info.uid, true);
8147        } else {
8148            app = null;
8149        }
8150
8151        if (app == null) {
8152            app = newProcessRecordLocked(info, null, isolated);
8153            mProcessNames.put(info.processName, app.uid, app);
8154            if (isolated) {
8155                mIsolatedProcesses.put(app.uid, app);
8156            }
8157            updateLruProcessLocked(app, false, null);
8158            updateOomAdjLocked();
8159        }
8160
8161        // This package really, really can not be stopped.
8162        try {
8163            AppGlobals.getPackageManager().setPackageStoppedState(
8164                    info.packageName, false, UserHandle.getUserId(app.uid));
8165        } catch (RemoteException e) {
8166        } catch (IllegalArgumentException e) {
8167            Slog.w(TAG, "Failed trying to unstop package "
8168                    + info.packageName + ": " + e);
8169        }
8170
8171        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8172                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8173            app.persistent = true;
8174            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8175        }
8176        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8177            mPersistentStartingProcesses.add(app);
8178            startProcessLocked(app, "added application", app.processName);
8179        }
8180
8181        return app;
8182    }
8183
8184    public void unhandledBack() {
8185        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8186                "unhandledBack()");
8187
8188        synchronized(this) {
8189            final long origId = Binder.clearCallingIdentity();
8190            try {
8191                getFocusedStack().unhandledBackLocked();
8192            } finally {
8193                Binder.restoreCallingIdentity(origId);
8194            }
8195        }
8196    }
8197
8198    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8199        enforceNotIsolatedCaller("openContentUri");
8200        final int userId = UserHandle.getCallingUserId();
8201        String name = uri.getAuthority();
8202        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8203        ParcelFileDescriptor pfd = null;
8204        if (cph != null) {
8205            // We record the binder invoker's uid in thread-local storage before
8206            // going to the content provider to open the file.  Later, in the code
8207            // that handles all permissions checks, we look for this uid and use
8208            // that rather than the Activity Manager's own uid.  The effect is that
8209            // we do the check against the caller's permissions even though it looks
8210            // to the content provider like the Activity Manager itself is making
8211            // the request.
8212            sCallerIdentity.set(new Identity(
8213                    Binder.getCallingPid(), Binder.getCallingUid()));
8214            try {
8215                pfd = cph.provider.openFile(null, uri, "r", null);
8216            } catch (FileNotFoundException e) {
8217                // do nothing; pfd will be returned null
8218            } finally {
8219                // Ensure that whatever happens, we clean up the identity state
8220                sCallerIdentity.remove();
8221            }
8222
8223            // We've got the fd now, so we're done with the provider.
8224            removeContentProviderExternalUnchecked(name, null, userId);
8225        } else {
8226            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8227        }
8228        return pfd;
8229    }
8230
8231    // Actually is sleeping or shutting down or whatever else in the future
8232    // is an inactive state.
8233    public boolean isSleepingOrShuttingDown() {
8234        return mSleeping || mShuttingDown;
8235    }
8236
8237    public void goingToSleep() {
8238        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8239                != PackageManager.PERMISSION_GRANTED) {
8240            throw new SecurityException("Requires permission "
8241                    + android.Manifest.permission.DEVICE_POWER);
8242        }
8243
8244        synchronized(this) {
8245            mWentToSleep = true;
8246            updateEventDispatchingLocked();
8247
8248            if (!mSleeping) {
8249                mSleeping = true;
8250                mStackSupervisor.goingToSleepLocked();
8251
8252                // Initialize the wake times of all processes.
8253                checkExcessivePowerUsageLocked(false);
8254                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8255                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8256                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8257            }
8258        }
8259    }
8260
8261    @Override
8262    public boolean shutdown(int timeout) {
8263        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8264                != PackageManager.PERMISSION_GRANTED) {
8265            throw new SecurityException("Requires permission "
8266                    + android.Manifest.permission.SHUTDOWN);
8267        }
8268
8269        boolean timedout = false;
8270
8271        synchronized(this) {
8272            mShuttingDown = true;
8273            updateEventDispatchingLocked();
8274            timedout = mStackSupervisor.shutdownLocked(timeout);
8275        }
8276
8277        mAppOpsService.shutdown();
8278        mUsageStatsService.shutdown();
8279        mBatteryStatsService.shutdown();
8280        synchronized (this) {
8281            mProcessStats.shutdownLocked();
8282        }
8283
8284        return timedout;
8285    }
8286
8287    public final void activitySlept(IBinder token) {
8288        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8289
8290        final long origId = Binder.clearCallingIdentity();
8291
8292        synchronized (this) {
8293            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8294            if (r != null) {
8295                mStackSupervisor.activitySleptLocked(r);
8296            }
8297        }
8298
8299        Binder.restoreCallingIdentity(origId);
8300    }
8301
8302    void logLockScreen(String msg) {
8303        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8304                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8305                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8306                mStackSupervisor.mDismissKeyguardOnNextActivity);
8307    }
8308
8309    private void comeOutOfSleepIfNeededLocked() {
8310        if (!mWentToSleep && !mLockScreenShown) {
8311            if (mSleeping) {
8312                mSleeping = false;
8313                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8314            }
8315        }
8316    }
8317
8318    public void wakingUp() {
8319        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8320                != PackageManager.PERMISSION_GRANTED) {
8321            throw new SecurityException("Requires permission "
8322                    + android.Manifest.permission.DEVICE_POWER);
8323        }
8324
8325        synchronized(this) {
8326            mWentToSleep = false;
8327            updateEventDispatchingLocked();
8328            comeOutOfSleepIfNeededLocked();
8329        }
8330    }
8331
8332    private void updateEventDispatchingLocked() {
8333        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8334    }
8335
8336    public void setLockScreenShown(boolean shown) {
8337        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8338                != PackageManager.PERMISSION_GRANTED) {
8339            throw new SecurityException("Requires permission "
8340                    + android.Manifest.permission.DEVICE_POWER);
8341        }
8342
8343        synchronized(this) {
8344            long ident = Binder.clearCallingIdentity();
8345            try {
8346                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8347                mLockScreenShown = shown;
8348                comeOutOfSleepIfNeededLocked();
8349            } finally {
8350                Binder.restoreCallingIdentity(ident);
8351            }
8352        }
8353    }
8354
8355    public void stopAppSwitches() {
8356        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8357                != PackageManager.PERMISSION_GRANTED) {
8358            throw new SecurityException("Requires permission "
8359                    + android.Manifest.permission.STOP_APP_SWITCHES);
8360        }
8361
8362        synchronized(this) {
8363            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8364                    + APP_SWITCH_DELAY_TIME;
8365            mDidAppSwitch = false;
8366            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8367            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8368            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8369        }
8370    }
8371
8372    public void resumeAppSwitches() {
8373        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8374                != PackageManager.PERMISSION_GRANTED) {
8375            throw new SecurityException("Requires permission "
8376                    + android.Manifest.permission.STOP_APP_SWITCHES);
8377        }
8378
8379        synchronized(this) {
8380            // Note that we don't execute any pending app switches... we will
8381            // let those wait until either the timeout, or the next start
8382            // activity request.
8383            mAppSwitchesAllowedTime = 0;
8384        }
8385    }
8386
8387    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8388            String name) {
8389        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8390            return true;
8391        }
8392
8393        final int perm = checkComponentPermission(
8394                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8395                callingUid, -1, true);
8396        if (perm == PackageManager.PERMISSION_GRANTED) {
8397            return true;
8398        }
8399
8400        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8401        return false;
8402    }
8403
8404    public void setDebugApp(String packageName, boolean waitForDebugger,
8405            boolean persistent) {
8406        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8407                "setDebugApp()");
8408
8409        long ident = Binder.clearCallingIdentity();
8410        try {
8411            // Note that this is not really thread safe if there are multiple
8412            // callers into it at the same time, but that's not a situation we
8413            // care about.
8414            if (persistent) {
8415                final ContentResolver resolver = mContext.getContentResolver();
8416                Settings.Global.putString(
8417                    resolver, Settings.Global.DEBUG_APP,
8418                    packageName);
8419                Settings.Global.putInt(
8420                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8421                    waitForDebugger ? 1 : 0);
8422            }
8423
8424            synchronized (this) {
8425                if (!persistent) {
8426                    mOrigDebugApp = mDebugApp;
8427                    mOrigWaitForDebugger = mWaitForDebugger;
8428                }
8429                mDebugApp = packageName;
8430                mWaitForDebugger = waitForDebugger;
8431                mDebugTransient = !persistent;
8432                if (packageName != null) {
8433                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8434                            false, UserHandle.USER_ALL, "set debug app");
8435                }
8436            }
8437        } finally {
8438            Binder.restoreCallingIdentity(ident);
8439        }
8440    }
8441
8442    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8443        synchronized (this) {
8444            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8445            if (!isDebuggable) {
8446                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8447                    throw new SecurityException("Process not debuggable: " + app.packageName);
8448                }
8449            }
8450
8451            mOpenGlTraceApp = processName;
8452        }
8453    }
8454
8455    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8456            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8457        synchronized (this) {
8458            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8459            if (!isDebuggable) {
8460                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8461                    throw new SecurityException("Process not debuggable: " + app.packageName);
8462                }
8463            }
8464            mProfileApp = processName;
8465            mProfileFile = profileFile;
8466            if (mProfileFd != null) {
8467                try {
8468                    mProfileFd.close();
8469                } catch (IOException e) {
8470                }
8471                mProfileFd = null;
8472            }
8473            mProfileFd = profileFd;
8474            mProfileType = 0;
8475            mAutoStopProfiler = autoStopProfiler;
8476        }
8477    }
8478
8479    @Override
8480    public void setAlwaysFinish(boolean enabled) {
8481        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8482                "setAlwaysFinish()");
8483
8484        Settings.Global.putInt(
8485                mContext.getContentResolver(),
8486                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8487
8488        synchronized (this) {
8489            mAlwaysFinishActivities = enabled;
8490        }
8491    }
8492
8493    @Override
8494    public void setActivityController(IActivityController controller) {
8495        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8496                "setActivityController()");
8497        synchronized (this) {
8498            mController = controller;
8499            Watchdog.getInstance().setActivityController(controller);
8500        }
8501    }
8502
8503    @Override
8504    public void setUserIsMonkey(boolean userIsMonkey) {
8505        synchronized (this) {
8506            synchronized (mPidsSelfLocked) {
8507                final int callingPid = Binder.getCallingPid();
8508                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8509                if (precessRecord == null) {
8510                    throw new SecurityException("Unknown process: " + callingPid);
8511                }
8512                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8513                    throw new SecurityException("Only an instrumentation process "
8514                            + "with a UiAutomation can call setUserIsMonkey");
8515                }
8516            }
8517            mUserIsMonkey = userIsMonkey;
8518        }
8519    }
8520
8521    @Override
8522    public boolean isUserAMonkey() {
8523        synchronized (this) {
8524            // If there is a controller also implies the user is a monkey.
8525            return (mUserIsMonkey || mController != null);
8526        }
8527    }
8528
8529    public void requestBugReport() {
8530        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8531        SystemProperties.set("ctl.start", "bugreport");
8532    }
8533
8534    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8535        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8536    }
8537
8538    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8539        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8540            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8541        }
8542        return KEY_DISPATCHING_TIMEOUT;
8543    }
8544
8545    @Override
8546    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8547        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8548                != PackageManager.PERMISSION_GRANTED) {
8549            throw new SecurityException("Requires permission "
8550                    + android.Manifest.permission.FILTER_EVENTS);
8551        }
8552        ProcessRecord proc;
8553        long timeout;
8554        synchronized (this) {
8555            synchronized (mPidsSelfLocked) {
8556                proc = mPidsSelfLocked.get(pid);
8557            }
8558            timeout = getInputDispatchingTimeoutLocked(proc);
8559        }
8560
8561        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8562            return -1;
8563        }
8564
8565        return timeout;
8566    }
8567
8568    /**
8569     * Handle input dispatching timeouts.
8570     * Returns whether input dispatching should be aborted or not.
8571     */
8572    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8573            final ActivityRecord activity, final ActivityRecord parent,
8574            final boolean aboveSystem, String reason) {
8575        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8576                != PackageManager.PERMISSION_GRANTED) {
8577            throw new SecurityException("Requires permission "
8578                    + android.Manifest.permission.FILTER_EVENTS);
8579        }
8580
8581        final String annotation;
8582        if (reason == null) {
8583            annotation = "Input dispatching timed out";
8584        } else {
8585            annotation = "Input dispatching timed out (" + reason + ")";
8586        }
8587
8588        if (proc != null) {
8589            synchronized (this) {
8590                if (proc.debugging) {
8591                    return false;
8592                }
8593
8594                if (mDidDexOpt) {
8595                    // Give more time since we were dexopting.
8596                    mDidDexOpt = false;
8597                    return false;
8598                }
8599
8600                if (proc.instrumentationClass != null) {
8601                    Bundle info = new Bundle();
8602                    info.putString("shortMsg", "keyDispatchingTimedOut");
8603                    info.putString("longMsg", annotation);
8604                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8605                    return true;
8606                }
8607            }
8608            mHandler.post(new Runnable() {
8609                @Override
8610                public void run() {
8611                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8612                }
8613            });
8614        }
8615
8616        return true;
8617    }
8618
8619    public Bundle getAssistContextExtras(int requestType) {
8620        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8621                "getAssistContextExtras()");
8622        PendingAssistExtras pae;
8623        Bundle extras = new Bundle();
8624        synchronized (this) {
8625            ActivityRecord activity = getFocusedStack().mResumedActivity;
8626            if (activity == null) {
8627                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8628                return null;
8629            }
8630            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8631            if (activity.app == null || activity.app.thread == null) {
8632                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8633                return extras;
8634            }
8635            if (activity.app.pid == Binder.getCallingPid()) {
8636                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8637                return extras;
8638            }
8639            pae = new PendingAssistExtras(activity);
8640            try {
8641                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8642                        requestType);
8643                mPendingAssistExtras.add(pae);
8644                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8645            } catch (RemoteException e) {
8646                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8647                return extras;
8648            }
8649        }
8650        synchronized (pae) {
8651            while (!pae.haveResult) {
8652                try {
8653                    pae.wait();
8654                } catch (InterruptedException e) {
8655                }
8656            }
8657            if (pae.result != null) {
8658                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8659            }
8660        }
8661        synchronized (this) {
8662            mPendingAssistExtras.remove(pae);
8663            mHandler.removeCallbacks(pae);
8664        }
8665        return extras;
8666    }
8667
8668    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8669        PendingAssistExtras pae = (PendingAssistExtras)token;
8670        synchronized (pae) {
8671            pae.result = extras;
8672            pae.haveResult = true;
8673            pae.notifyAll();
8674        }
8675    }
8676
8677    public void registerProcessObserver(IProcessObserver observer) {
8678        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8679                "registerProcessObserver()");
8680        synchronized (this) {
8681            mProcessObservers.register(observer);
8682        }
8683    }
8684
8685    @Override
8686    public void unregisterProcessObserver(IProcessObserver observer) {
8687        synchronized (this) {
8688            mProcessObservers.unregister(observer);
8689        }
8690    }
8691
8692    @Override
8693    public boolean convertFromTranslucent(IBinder token) {
8694        final long origId = Binder.clearCallingIdentity();
8695        try {
8696            synchronized (this) {
8697                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8698                if (r == null) {
8699                    return false;
8700                }
8701                if (r.changeWindowTranslucency(true)) {
8702                    mWindowManager.setAppFullscreen(token, true);
8703                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8704                    return true;
8705                }
8706                return false;
8707            }
8708        } finally {
8709            Binder.restoreCallingIdentity(origId);
8710        }
8711    }
8712
8713    @Override
8714    public boolean convertToTranslucent(IBinder token) {
8715        final long origId = Binder.clearCallingIdentity();
8716        try {
8717            synchronized (this) {
8718                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8719                if (r == null) {
8720                    return false;
8721                }
8722                if (r.changeWindowTranslucency(false)) {
8723                    r.task.stack.convertToTranslucent(r);
8724                    mWindowManager.setAppFullscreen(token, false);
8725                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8726                    return true;
8727                }
8728                return false;
8729            }
8730        } finally {
8731            Binder.restoreCallingIdentity(origId);
8732        }
8733    }
8734
8735    @Override
8736    public void setImmersive(IBinder token, boolean immersive) {
8737        synchronized(this) {
8738            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8739            if (r == null) {
8740                throw new IllegalArgumentException();
8741            }
8742            r.immersive = immersive;
8743
8744            // update associated state if we're frontmost
8745            if (r == mFocusedActivity) {
8746                if (DEBUG_IMMERSIVE) {
8747                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8748                }
8749                applyUpdateLockStateLocked(r);
8750            }
8751        }
8752    }
8753
8754    @Override
8755    public boolean isImmersive(IBinder token) {
8756        synchronized (this) {
8757            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8758            if (r == null) {
8759                throw new IllegalArgumentException();
8760            }
8761            return r.immersive;
8762        }
8763    }
8764
8765    public boolean isTopActivityImmersive() {
8766        enforceNotIsolatedCaller("startActivity");
8767        synchronized (this) {
8768            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8769            return (r != null) ? r.immersive : false;
8770        }
8771    }
8772
8773    public final void enterSafeMode() {
8774        synchronized(this) {
8775            // It only makes sense to do this before the system is ready
8776            // and started launching other packages.
8777            if (!mSystemReady) {
8778                try {
8779                    AppGlobals.getPackageManager().enterSafeMode();
8780                } catch (RemoteException e) {
8781                }
8782            }
8783        }
8784    }
8785
8786    public final void showSafeModeOverlay() {
8787        View v = LayoutInflater.from(mContext).inflate(
8788                com.android.internal.R.layout.safe_mode, null);
8789        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8790        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8791        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8792        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8793        lp.gravity = Gravity.BOTTOM | Gravity.START;
8794        lp.format = v.getBackground().getOpacity();
8795        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8796                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8797        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8798        ((WindowManager)mContext.getSystemService(
8799                Context.WINDOW_SERVICE)).addView(v, lp);
8800    }
8801
8802    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8803        if (!(sender instanceof PendingIntentRecord)) {
8804            return;
8805        }
8806        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8807        synchronized (stats) {
8808            if (mBatteryStatsService.isOnBattery()) {
8809                mBatteryStatsService.enforceCallingPermission();
8810                PendingIntentRecord rec = (PendingIntentRecord)sender;
8811                int MY_UID = Binder.getCallingUid();
8812                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8813                BatteryStatsImpl.Uid.Pkg pkg =
8814                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8815                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8816                pkg.incWakeupsLocked();
8817            }
8818        }
8819    }
8820
8821    public boolean killPids(int[] pids, String pReason, boolean secure) {
8822        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8823            throw new SecurityException("killPids only available to the system");
8824        }
8825        String reason = (pReason == null) ? "Unknown" : pReason;
8826        // XXX Note: don't acquire main activity lock here, because the window
8827        // manager calls in with its locks held.
8828
8829        boolean killed = false;
8830        synchronized (mPidsSelfLocked) {
8831            int[] types = new int[pids.length];
8832            int worstType = 0;
8833            for (int i=0; i<pids.length; i++) {
8834                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8835                if (proc != null) {
8836                    int type = proc.setAdj;
8837                    types[i] = type;
8838                    if (type > worstType) {
8839                        worstType = type;
8840                    }
8841                }
8842            }
8843
8844            // If the worst oom_adj is somewhere in the cached proc LRU range,
8845            // then constrain it so we will kill all cached procs.
8846            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8847                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8848                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8849            }
8850
8851            // If this is not a secure call, don't let it kill processes that
8852            // are important.
8853            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8854                worstType = ProcessList.SERVICE_ADJ;
8855            }
8856
8857            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8858            for (int i=0; i<pids.length; i++) {
8859                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8860                if (proc == null) {
8861                    continue;
8862                }
8863                int adj = proc.setAdj;
8864                if (adj >= worstType && !proc.killedByAm) {
8865                    killUnneededProcessLocked(proc, reason);
8866                    killed = true;
8867                }
8868            }
8869        }
8870        return killed;
8871    }
8872
8873    @Override
8874    public void killUid(int uid, String reason) {
8875        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8876            throw new SecurityException("killUid only available to the system");
8877        }
8878        synchronized (this) {
8879            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8880                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8881                    reason != null ? reason : "kill uid");
8882        }
8883    }
8884
8885    @Override
8886    public boolean killProcessesBelowForeground(String reason) {
8887        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8888            throw new SecurityException("killProcessesBelowForeground() only available to system");
8889        }
8890
8891        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8892    }
8893
8894    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8895        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8896            throw new SecurityException("killProcessesBelowAdj() only available to system");
8897        }
8898
8899        boolean killed = false;
8900        synchronized (mPidsSelfLocked) {
8901            final int size = mPidsSelfLocked.size();
8902            for (int i = 0; i < size; i++) {
8903                final int pid = mPidsSelfLocked.keyAt(i);
8904                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8905                if (proc == null) continue;
8906
8907                final int adj = proc.setAdj;
8908                if (adj > belowAdj && !proc.killedByAm) {
8909                    killUnneededProcessLocked(proc, reason);
8910                    killed = true;
8911                }
8912            }
8913        }
8914        return killed;
8915    }
8916
8917    @Override
8918    public void hang(final IBinder who, boolean allowRestart) {
8919        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8920                != PackageManager.PERMISSION_GRANTED) {
8921            throw new SecurityException("Requires permission "
8922                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8923        }
8924
8925        final IBinder.DeathRecipient death = new DeathRecipient() {
8926            @Override
8927            public void binderDied() {
8928                synchronized (this) {
8929                    notifyAll();
8930                }
8931            }
8932        };
8933
8934        try {
8935            who.linkToDeath(death, 0);
8936        } catch (RemoteException e) {
8937            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8938            return;
8939        }
8940
8941        synchronized (this) {
8942            Watchdog.getInstance().setAllowRestart(allowRestart);
8943            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8944            synchronized (death) {
8945                while (who.isBinderAlive()) {
8946                    try {
8947                        death.wait();
8948                    } catch (InterruptedException e) {
8949                    }
8950                }
8951            }
8952            Watchdog.getInstance().setAllowRestart(true);
8953        }
8954    }
8955
8956    @Override
8957    public void restart() {
8958        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8959                != PackageManager.PERMISSION_GRANTED) {
8960            throw new SecurityException("Requires permission "
8961                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8962        }
8963
8964        Log.i(TAG, "Sending shutdown broadcast...");
8965
8966        BroadcastReceiver br = new BroadcastReceiver() {
8967            @Override public void onReceive(Context context, Intent intent) {
8968                // Now the broadcast is done, finish up the low-level shutdown.
8969                Log.i(TAG, "Shutting down activity manager...");
8970                shutdown(10000);
8971                Log.i(TAG, "Shutdown complete, restarting!");
8972                Process.killProcess(Process.myPid());
8973                System.exit(10);
8974            }
8975        };
8976
8977        // First send the high-level shut down broadcast.
8978        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8979        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8980        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8981        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8982        mContext.sendOrderedBroadcastAsUser(intent,
8983                UserHandle.ALL, null, br, mHandler, 0, null, null);
8984        */
8985        br.onReceive(mContext, intent);
8986    }
8987
8988    private long getLowRamTimeSinceIdle(long now) {
8989        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8990    }
8991
8992    @Override
8993    public void performIdleMaintenance() {
8994        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8995                != PackageManager.PERMISSION_GRANTED) {
8996            throw new SecurityException("Requires permission "
8997                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8998        }
8999
9000        synchronized (this) {
9001            final long now = SystemClock.uptimeMillis();
9002            final long timeSinceLastIdle = now - mLastIdleTime;
9003            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9004            mLastIdleTime = now;
9005            mLowRamTimeSinceLastIdle = 0;
9006            if (mLowRamStartTime != 0) {
9007                mLowRamStartTime = now;
9008            }
9009
9010            StringBuilder sb = new StringBuilder(128);
9011            sb.append("Idle maintenance over ");
9012            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9013            sb.append(" low RAM for ");
9014            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9015            Slog.i(TAG, sb.toString());
9016
9017            // If at least 1/3 of our time since the last idle period has been spent
9018            // with RAM low, then we want to kill processes.
9019            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9020
9021            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9022                ProcessRecord proc = mLruProcesses.get(i);
9023                if (proc.notCachedSinceIdle) {
9024                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9025                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9026                        if (doKilling && proc.initialIdlePss != 0
9027                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9028                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9029                                    + " from " + proc.initialIdlePss + ")");
9030                        }
9031                    }
9032                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9033                    proc.notCachedSinceIdle = true;
9034                    proc.initialIdlePss = 0;
9035                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9036                            mSleeping, now);
9037                }
9038            }
9039
9040            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9041            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9042        }
9043    }
9044
9045    public final void startRunning(String pkg, String cls, String action,
9046            String data) {
9047        synchronized(this) {
9048            if (mStartRunning) {
9049                return;
9050            }
9051            mStartRunning = true;
9052            mTopComponent = pkg != null && cls != null
9053                    ? new ComponentName(pkg, cls) : null;
9054            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9055            mTopData = data;
9056            if (!mSystemReady) {
9057                return;
9058            }
9059        }
9060
9061        systemReady(null);
9062    }
9063
9064    private void retrieveSettings() {
9065        final ContentResolver resolver = mContext.getContentResolver();
9066        String debugApp = Settings.Global.getString(
9067            resolver, Settings.Global.DEBUG_APP);
9068        boolean waitForDebugger = Settings.Global.getInt(
9069            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9070        boolean alwaysFinishActivities = Settings.Global.getInt(
9071            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9072        boolean forceRtl = Settings.Global.getInt(
9073                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9074        // Transfer any global setting for forcing RTL layout, into a System Property
9075        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9076
9077        Configuration configuration = new Configuration();
9078        Settings.System.getConfiguration(resolver, configuration);
9079        if (forceRtl) {
9080            // This will take care of setting the correct layout direction flags
9081            configuration.setLayoutDirection(configuration.locale);
9082        }
9083
9084        synchronized (this) {
9085            mDebugApp = mOrigDebugApp = debugApp;
9086            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9087            mAlwaysFinishActivities = alwaysFinishActivities;
9088            // This happens before any activities are started, so we can
9089            // change mConfiguration in-place.
9090            updateConfigurationLocked(configuration, null, false, true);
9091            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9092        }
9093    }
9094
9095    public boolean testIsSystemReady() {
9096        // no need to synchronize(this) just to read & return the value
9097        return mSystemReady;
9098    }
9099
9100    private static File getCalledPreBootReceiversFile() {
9101        File dataDir = Environment.getDataDirectory();
9102        File systemDir = new File(dataDir, "system");
9103        File fname = new File(systemDir, "called_pre_boots.dat");
9104        return fname;
9105    }
9106
9107    static final int LAST_DONE_VERSION = 10000;
9108
9109    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9110        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9111        File file = getCalledPreBootReceiversFile();
9112        FileInputStream fis = null;
9113        try {
9114            fis = new FileInputStream(file);
9115            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9116            int fvers = dis.readInt();
9117            if (fvers == LAST_DONE_VERSION) {
9118                String vers = dis.readUTF();
9119                String codename = dis.readUTF();
9120                String build = dis.readUTF();
9121                if (android.os.Build.VERSION.RELEASE.equals(vers)
9122                        && android.os.Build.VERSION.CODENAME.equals(codename)
9123                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9124                    int num = dis.readInt();
9125                    while (num > 0) {
9126                        num--;
9127                        String pkg = dis.readUTF();
9128                        String cls = dis.readUTF();
9129                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9130                    }
9131                }
9132            }
9133        } catch (FileNotFoundException e) {
9134        } catch (IOException e) {
9135            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9136        } finally {
9137            if (fis != null) {
9138                try {
9139                    fis.close();
9140                } catch (IOException e) {
9141                }
9142            }
9143        }
9144        return lastDoneReceivers;
9145    }
9146
9147    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9148        File file = getCalledPreBootReceiversFile();
9149        FileOutputStream fos = null;
9150        DataOutputStream dos = null;
9151        try {
9152            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9153            fos = new FileOutputStream(file);
9154            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9155            dos.writeInt(LAST_DONE_VERSION);
9156            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9157            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9158            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9159            dos.writeInt(list.size());
9160            for (int i=0; i<list.size(); i++) {
9161                dos.writeUTF(list.get(i).getPackageName());
9162                dos.writeUTF(list.get(i).getClassName());
9163            }
9164        } catch (IOException e) {
9165            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9166            file.delete();
9167        } finally {
9168            FileUtils.sync(fos);
9169            if (dos != null) {
9170                try {
9171                    dos.close();
9172                } catch (IOException e) {
9173                    // TODO Auto-generated catch block
9174                    e.printStackTrace();
9175                }
9176            }
9177        }
9178    }
9179
9180    public void systemReady(final Runnable goingCallback) {
9181        synchronized(this) {
9182            if (mSystemReady) {
9183                if (goingCallback != null) goingCallback.run();
9184                return;
9185            }
9186
9187            // Check to see if there are any update receivers to run.
9188            if (!mDidUpdate) {
9189                if (mWaitingUpdate) {
9190                    return;
9191                }
9192                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9193                List<ResolveInfo> ris = null;
9194                try {
9195                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9196                            intent, null, 0, 0);
9197                } catch (RemoteException e) {
9198                }
9199                if (ris != null) {
9200                    for (int i=ris.size()-1; i>=0; i--) {
9201                        if ((ris.get(i).activityInfo.applicationInfo.flags
9202                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9203                            ris.remove(i);
9204                        }
9205                    }
9206                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9207
9208                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9209
9210                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9211                    for (int i=0; i<ris.size(); i++) {
9212                        ActivityInfo ai = ris.get(i).activityInfo;
9213                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9214                        if (lastDoneReceivers.contains(comp)) {
9215                            ris.remove(i);
9216                            i--;
9217                        }
9218                    }
9219
9220                    final int[] users = getUsersLocked();
9221                    for (int i=0; i<ris.size(); i++) {
9222                        ActivityInfo ai = ris.get(i).activityInfo;
9223                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9224                        doneReceivers.add(comp);
9225                        intent.setComponent(comp);
9226                        for (int j=0; j<users.length; j++) {
9227                            IIntentReceiver finisher = null;
9228                            if (i == ris.size()-1 && j == users.length-1) {
9229                                finisher = new IIntentReceiver.Stub() {
9230                                    public void performReceive(Intent intent, int resultCode,
9231                                            String data, Bundle extras, boolean ordered,
9232                                            boolean sticky, int sendingUser) {
9233                                        // The raw IIntentReceiver interface is called
9234                                        // with the AM lock held, so redispatch to
9235                                        // execute our code without the lock.
9236                                        mHandler.post(new Runnable() {
9237                                            public void run() {
9238                                                synchronized (ActivityManagerService.this) {
9239                                                    mDidUpdate = true;
9240                                                }
9241                                                writeLastDonePreBootReceivers(doneReceivers);
9242                                                showBootMessage(mContext.getText(
9243                                                        R.string.android_upgrading_complete),
9244                                                        false);
9245                                                systemReady(goingCallback);
9246                                            }
9247                                        });
9248                                    }
9249                                };
9250                            }
9251                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9252                                    + " for user " + users[j]);
9253                            broadcastIntentLocked(null, null, intent, null, finisher,
9254                                    0, null, null, null, AppOpsManager.OP_NONE,
9255                                    true, false, MY_PID, Process.SYSTEM_UID,
9256                                    users[j]);
9257                            if (finisher != null) {
9258                                mWaitingUpdate = true;
9259                            }
9260                        }
9261                    }
9262                }
9263                if (mWaitingUpdate) {
9264                    return;
9265                }
9266                mDidUpdate = true;
9267            }
9268
9269            mAppOpsService.systemReady();
9270            mSystemReady = true;
9271            if (!mStartRunning) {
9272                return;
9273            }
9274        }
9275
9276        ArrayList<ProcessRecord> procsToKill = null;
9277        synchronized(mPidsSelfLocked) {
9278            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9279                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9280                if (!isAllowedWhileBooting(proc.info)){
9281                    if (procsToKill == null) {
9282                        procsToKill = new ArrayList<ProcessRecord>();
9283                    }
9284                    procsToKill.add(proc);
9285                }
9286            }
9287        }
9288
9289        synchronized(this) {
9290            if (procsToKill != null) {
9291                for (int i=procsToKill.size()-1; i>=0; i--) {
9292                    ProcessRecord proc = procsToKill.get(i);
9293                    Slog.i(TAG, "Removing system update proc: " + proc);
9294                    removeProcessLocked(proc, true, false, "system update done");
9295                }
9296            }
9297
9298            // Now that we have cleaned up any update processes, we
9299            // are ready to start launching real processes and know that
9300            // we won't trample on them any more.
9301            mProcessesReady = true;
9302        }
9303
9304        Slog.i(TAG, "System now ready");
9305        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9306            SystemClock.uptimeMillis());
9307
9308        synchronized(this) {
9309            // Make sure we have no pre-ready processes sitting around.
9310
9311            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9312                ResolveInfo ri = mContext.getPackageManager()
9313                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9314                                STOCK_PM_FLAGS);
9315                CharSequence errorMsg = null;
9316                if (ri != null) {
9317                    ActivityInfo ai = ri.activityInfo;
9318                    ApplicationInfo app = ai.applicationInfo;
9319                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9320                        mTopAction = Intent.ACTION_FACTORY_TEST;
9321                        mTopData = null;
9322                        mTopComponent = new ComponentName(app.packageName,
9323                                ai.name);
9324                    } else {
9325                        errorMsg = mContext.getResources().getText(
9326                                com.android.internal.R.string.factorytest_not_system);
9327                    }
9328                } else {
9329                    errorMsg = mContext.getResources().getText(
9330                            com.android.internal.R.string.factorytest_no_action);
9331                }
9332                if (errorMsg != null) {
9333                    mTopAction = null;
9334                    mTopData = null;
9335                    mTopComponent = null;
9336                    Message msg = Message.obtain();
9337                    msg.what = SHOW_FACTORY_ERROR_MSG;
9338                    msg.getData().putCharSequence("msg", errorMsg);
9339                    mHandler.sendMessage(msg);
9340                }
9341            }
9342        }
9343
9344        retrieveSettings();
9345
9346        synchronized (this) {
9347            readGrantedUriPermissionsLocked();
9348        }
9349
9350        if (goingCallback != null) goingCallback.run();
9351
9352        synchronized (this) {
9353            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9354                try {
9355                    List apps = AppGlobals.getPackageManager().
9356                        getPersistentApplications(STOCK_PM_FLAGS);
9357                    if (apps != null) {
9358                        int N = apps.size();
9359                        int i;
9360                        for (i=0; i<N; i++) {
9361                            ApplicationInfo info
9362                                = (ApplicationInfo)apps.get(i);
9363                            if (info != null &&
9364                                    !info.packageName.equals("android")) {
9365                                addAppLocked(info, false);
9366                            }
9367                        }
9368                    }
9369                } catch (RemoteException ex) {
9370                    // pm is in same process, this will never happen.
9371                }
9372            }
9373
9374            // Start up initial activity.
9375            mBooting = true;
9376
9377            try {
9378                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9379                    Message msg = Message.obtain();
9380                    msg.what = SHOW_UID_ERROR_MSG;
9381                    mHandler.sendMessage(msg);
9382                }
9383            } catch (RemoteException e) {
9384            }
9385
9386            long ident = Binder.clearCallingIdentity();
9387            try {
9388                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9389                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9390                        | Intent.FLAG_RECEIVER_FOREGROUND);
9391                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9392                broadcastIntentLocked(null, null, intent,
9393                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9394                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9395                intent = new Intent(Intent.ACTION_USER_STARTING);
9396                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9397                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9398                broadcastIntentLocked(null, null, intent,
9399                        null, new IIntentReceiver.Stub() {
9400                            @Override
9401                            public void performReceive(Intent intent, int resultCode, String data,
9402                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9403                                    throws RemoteException {
9404                            }
9405                        }, 0, null, null,
9406                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9407                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9408            } finally {
9409                Binder.restoreCallingIdentity(ident);
9410            }
9411            mStackSupervisor.resumeTopActivitiesLocked();
9412            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9413        }
9414    }
9415
9416    private boolean makeAppCrashingLocked(ProcessRecord app,
9417            String shortMsg, String longMsg, String stackTrace) {
9418        app.crashing = true;
9419        app.crashingReport = generateProcessError(app,
9420                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9421        startAppProblemLocked(app);
9422        app.stopFreezingAllLocked();
9423        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9424    }
9425
9426    private void makeAppNotRespondingLocked(ProcessRecord app,
9427            String activity, String shortMsg, String longMsg) {
9428        app.notResponding = true;
9429        app.notRespondingReport = generateProcessError(app,
9430                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9431                activity, shortMsg, longMsg, null);
9432        startAppProblemLocked(app);
9433        app.stopFreezingAllLocked();
9434    }
9435
9436    /**
9437     * Generate a process error record, suitable for attachment to a ProcessRecord.
9438     *
9439     * @param app The ProcessRecord in which the error occurred.
9440     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9441     *                      ActivityManager.AppErrorStateInfo
9442     * @param activity The activity associated with the crash, if known.
9443     * @param shortMsg Short message describing the crash.
9444     * @param longMsg Long message describing the crash.
9445     * @param stackTrace Full crash stack trace, may be null.
9446     *
9447     * @return Returns a fully-formed AppErrorStateInfo record.
9448     */
9449    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9450            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9451        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9452
9453        report.condition = condition;
9454        report.processName = app.processName;
9455        report.pid = app.pid;
9456        report.uid = app.info.uid;
9457        report.tag = activity;
9458        report.shortMsg = shortMsg;
9459        report.longMsg = longMsg;
9460        report.stackTrace = stackTrace;
9461
9462        return report;
9463    }
9464
9465    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9466        synchronized (this) {
9467            app.crashing = false;
9468            app.crashingReport = null;
9469            app.notResponding = false;
9470            app.notRespondingReport = null;
9471            if (app.anrDialog == fromDialog) {
9472                app.anrDialog = null;
9473            }
9474            if (app.waitDialog == fromDialog) {
9475                app.waitDialog = null;
9476            }
9477            if (app.pid > 0 && app.pid != MY_PID) {
9478                handleAppCrashLocked(app, null, null, null);
9479                killUnneededProcessLocked(app, "user request after error");
9480            }
9481        }
9482    }
9483
9484    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9485            String stackTrace) {
9486        long now = SystemClock.uptimeMillis();
9487
9488        Long crashTime;
9489        if (!app.isolated) {
9490            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9491        } else {
9492            crashTime = null;
9493        }
9494        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9495            // This process loses!
9496            Slog.w(TAG, "Process " + app.info.processName
9497                    + " has crashed too many times: killing!");
9498            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9499                    app.userId, app.info.processName, app.uid);
9500            mStackSupervisor.handleAppCrashLocked(app);
9501            if (!app.persistent) {
9502                // We don't want to start this process again until the user
9503                // explicitly does so...  but for persistent process, we really
9504                // need to keep it running.  If a persistent process is actually
9505                // repeatedly crashing, then badness for everyone.
9506                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9507                        app.info.processName);
9508                if (!app.isolated) {
9509                    // XXX We don't have a way to mark isolated processes
9510                    // as bad, since they don't have a peristent identity.
9511                    mBadProcesses.put(app.info.processName, app.uid,
9512                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9513                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9514                }
9515                app.bad = true;
9516                app.removed = true;
9517                // Don't let services in this process be restarted and potentially
9518                // annoy the user repeatedly.  Unless it is persistent, since those
9519                // processes run critical code.
9520                removeProcessLocked(app, false, false, "crash");
9521                mStackSupervisor.resumeTopActivitiesLocked();
9522                return false;
9523            }
9524            mStackSupervisor.resumeTopActivitiesLocked();
9525        } else {
9526            mStackSupervisor.finishTopRunningActivityLocked(app);
9527        }
9528
9529        // Bump up the crash count of any services currently running in the proc.
9530        for (int i=app.services.size()-1; i>=0; i--) {
9531            // Any services running in the application need to be placed
9532            // back in the pending list.
9533            ServiceRecord sr = app.services.valueAt(i);
9534            sr.crashCount++;
9535        }
9536
9537        // If the crashing process is what we consider to be the "home process" and it has been
9538        // replaced by a third-party app, clear the package preferred activities from packages
9539        // with a home activity running in the process to prevent a repeatedly crashing app
9540        // from blocking the user to manually clear the list.
9541        final ArrayList<ActivityRecord> activities = app.activities;
9542        if (app == mHomeProcess && activities.size() > 0
9543                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9544            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9545                final ActivityRecord r = activities.get(activityNdx);
9546                if (r.isHomeActivity()) {
9547                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9548                    try {
9549                        ActivityThread.getPackageManager()
9550                                .clearPackagePreferredActivities(r.packageName);
9551                    } catch (RemoteException c) {
9552                        // pm is in same process, this will never happen.
9553                    }
9554                }
9555            }
9556        }
9557
9558        if (!app.isolated) {
9559            // XXX Can't keep track of crash times for isolated processes,
9560            // because they don't have a perisistent identity.
9561            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9562        }
9563
9564        return true;
9565    }
9566
9567    void startAppProblemLocked(ProcessRecord app) {
9568        if (app.userId == mCurrentUserId) {
9569            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9570                    mContext, app.info.packageName, app.info.flags);
9571        } else {
9572            // If this app is not running under the current user, then we
9573            // can't give it a report button because that would require
9574            // launching the report UI under a different user.
9575            app.errorReportReceiver = null;
9576        }
9577        skipCurrentReceiverLocked(app);
9578    }
9579
9580    void skipCurrentReceiverLocked(ProcessRecord app) {
9581        for (BroadcastQueue queue : mBroadcastQueues) {
9582            queue.skipCurrentReceiverLocked(app);
9583        }
9584    }
9585
9586    /**
9587     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9588     * The application process will exit immediately after this call returns.
9589     * @param app object of the crashing app, null for the system server
9590     * @param crashInfo describing the exception
9591     */
9592    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9593        ProcessRecord r = findAppProcess(app, "Crash");
9594        final String processName = app == null ? "system_server"
9595                : (r == null ? "unknown" : r.processName);
9596
9597        handleApplicationCrashInner("crash", r, processName, crashInfo);
9598    }
9599
9600    /* Native crash reporting uses this inner version because it needs to be somewhat
9601     * decoupled from the AM-managed cleanup lifecycle
9602     */
9603    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9604            ApplicationErrorReport.CrashInfo crashInfo) {
9605        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9606                UserHandle.getUserId(Binder.getCallingUid()), processName,
9607                r == null ? -1 : r.info.flags,
9608                crashInfo.exceptionClassName,
9609                crashInfo.exceptionMessage,
9610                crashInfo.throwFileName,
9611                crashInfo.throwLineNumber);
9612
9613        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9614
9615        crashApplication(r, crashInfo);
9616    }
9617
9618    public void handleApplicationStrictModeViolation(
9619            IBinder app,
9620            int violationMask,
9621            StrictMode.ViolationInfo info) {
9622        ProcessRecord r = findAppProcess(app, "StrictMode");
9623        if (r == null) {
9624            return;
9625        }
9626
9627        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9628            Integer stackFingerprint = info.hashCode();
9629            boolean logIt = true;
9630            synchronized (mAlreadyLoggedViolatedStacks) {
9631                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9632                    logIt = false;
9633                    // TODO: sub-sample into EventLog for these, with
9634                    // the info.durationMillis?  Then we'd get
9635                    // the relative pain numbers, without logging all
9636                    // the stack traces repeatedly.  We'd want to do
9637                    // likewise in the client code, which also does
9638                    // dup suppression, before the Binder call.
9639                } else {
9640                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9641                        mAlreadyLoggedViolatedStacks.clear();
9642                    }
9643                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9644                }
9645            }
9646            if (logIt) {
9647                logStrictModeViolationToDropBox(r, info);
9648            }
9649        }
9650
9651        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9652            AppErrorResult result = new AppErrorResult();
9653            synchronized (this) {
9654                final long origId = Binder.clearCallingIdentity();
9655
9656                Message msg = Message.obtain();
9657                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9658                HashMap<String, Object> data = new HashMap<String, Object>();
9659                data.put("result", result);
9660                data.put("app", r);
9661                data.put("violationMask", violationMask);
9662                data.put("info", info);
9663                msg.obj = data;
9664                mHandler.sendMessage(msg);
9665
9666                Binder.restoreCallingIdentity(origId);
9667            }
9668            int res = result.get();
9669            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9670        }
9671    }
9672
9673    // Depending on the policy in effect, there could be a bunch of
9674    // these in quick succession so we try to batch these together to
9675    // minimize disk writes, number of dropbox entries, and maximize
9676    // compression, by having more fewer, larger records.
9677    private void logStrictModeViolationToDropBox(
9678            ProcessRecord process,
9679            StrictMode.ViolationInfo info) {
9680        if (info == null) {
9681            return;
9682        }
9683        final boolean isSystemApp = process == null ||
9684                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9685                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9686        final String processName = process == null ? "unknown" : process.processName;
9687        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9688        final DropBoxManager dbox = (DropBoxManager)
9689                mContext.getSystemService(Context.DROPBOX_SERVICE);
9690
9691        // Exit early if the dropbox isn't configured to accept this report type.
9692        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9693
9694        boolean bufferWasEmpty;
9695        boolean needsFlush;
9696        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9697        synchronized (sb) {
9698            bufferWasEmpty = sb.length() == 0;
9699            appendDropBoxProcessHeaders(process, processName, sb);
9700            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9701            sb.append("System-App: ").append(isSystemApp).append("\n");
9702            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9703            if (info.violationNumThisLoop != 0) {
9704                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9705            }
9706            if (info.numAnimationsRunning != 0) {
9707                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9708            }
9709            if (info.broadcastIntentAction != null) {
9710                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9711            }
9712            if (info.durationMillis != -1) {
9713                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9714            }
9715            if (info.numInstances != -1) {
9716                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9717            }
9718            if (info.tags != null) {
9719                for (String tag : info.tags) {
9720                    sb.append("Span-Tag: ").append(tag).append("\n");
9721                }
9722            }
9723            sb.append("\n");
9724            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9725                sb.append(info.crashInfo.stackTrace);
9726            }
9727            sb.append("\n");
9728
9729            // Only buffer up to ~64k.  Various logging bits truncate
9730            // things at 128k.
9731            needsFlush = (sb.length() > 64 * 1024);
9732        }
9733
9734        // Flush immediately if the buffer's grown too large, or this
9735        // is a non-system app.  Non-system apps are isolated with a
9736        // different tag & policy and not batched.
9737        //
9738        // Batching is useful during internal testing with
9739        // StrictMode settings turned up high.  Without batching,
9740        // thousands of separate files could be created on boot.
9741        if (!isSystemApp || needsFlush) {
9742            new Thread("Error dump: " + dropboxTag) {
9743                @Override
9744                public void run() {
9745                    String report;
9746                    synchronized (sb) {
9747                        report = sb.toString();
9748                        sb.delete(0, sb.length());
9749                        sb.trimToSize();
9750                    }
9751                    if (report.length() != 0) {
9752                        dbox.addText(dropboxTag, report);
9753                    }
9754                }
9755            }.start();
9756            return;
9757        }
9758
9759        // System app batching:
9760        if (!bufferWasEmpty) {
9761            // An existing dropbox-writing thread is outstanding, so
9762            // we don't need to start it up.  The existing thread will
9763            // catch the buffer appends we just did.
9764            return;
9765        }
9766
9767        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9768        // (After this point, we shouldn't access AMS internal data structures.)
9769        new Thread("Error dump: " + dropboxTag) {
9770            @Override
9771            public void run() {
9772                // 5 second sleep to let stacks arrive and be batched together
9773                try {
9774                    Thread.sleep(5000);  // 5 seconds
9775                } catch (InterruptedException e) {}
9776
9777                String errorReport;
9778                synchronized (mStrictModeBuffer) {
9779                    errorReport = mStrictModeBuffer.toString();
9780                    if (errorReport.length() == 0) {
9781                        return;
9782                    }
9783                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9784                    mStrictModeBuffer.trimToSize();
9785                }
9786                dbox.addText(dropboxTag, errorReport);
9787            }
9788        }.start();
9789    }
9790
9791    /**
9792     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9793     * @param app object of the crashing app, null for the system server
9794     * @param tag reported by the caller
9795     * @param crashInfo describing the context of the error
9796     * @return true if the process should exit immediately (WTF is fatal)
9797     */
9798    public boolean handleApplicationWtf(IBinder app, String tag,
9799            ApplicationErrorReport.CrashInfo crashInfo) {
9800        ProcessRecord r = findAppProcess(app, "WTF");
9801        final String processName = app == null ? "system_server"
9802                : (r == null ? "unknown" : r.processName);
9803
9804        EventLog.writeEvent(EventLogTags.AM_WTF,
9805                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9806                processName,
9807                r == null ? -1 : r.info.flags,
9808                tag, crashInfo.exceptionMessage);
9809
9810        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9811
9812        if (r != null && r.pid != Process.myPid() &&
9813                Settings.Global.getInt(mContext.getContentResolver(),
9814                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9815            crashApplication(r, crashInfo);
9816            return true;
9817        } else {
9818            return false;
9819        }
9820    }
9821
9822    /**
9823     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9824     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9825     */
9826    private ProcessRecord findAppProcess(IBinder app, String reason) {
9827        if (app == null) {
9828            return null;
9829        }
9830
9831        synchronized (this) {
9832            final int NP = mProcessNames.getMap().size();
9833            for (int ip=0; ip<NP; ip++) {
9834                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9835                final int NA = apps.size();
9836                for (int ia=0; ia<NA; ia++) {
9837                    ProcessRecord p = apps.valueAt(ia);
9838                    if (p.thread != null && p.thread.asBinder() == app) {
9839                        return p;
9840                    }
9841                }
9842            }
9843
9844            Slog.w(TAG, "Can't find mystery application for " + reason
9845                    + " from pid=" + Binder.getCallingPid()
9846                    + " uid=" + Binder.getCallingUid() + ": " + app);
9847            return null;
9848        }
9849    }
9850
9851    /**
9852     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9853     * to append various headers to the dropbox log text.
9854     */
9855    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9856            StringBuilder sb) {
9857        // Watchdog thread ends up invoking this function (with
9858        // a null ProcessRecord) to add the stack file to dropbox.
9859        // Do not acquire a lock on this (am) in such cases, as it
9860        // could cause a potential deadlock, if and when watchdog
9861        // is invoked due to unavailability of lock on am and it
9862        // would prevent watchdog from killing system_server.
9863        if (process == null) {
9864            sb.append("Process: ").append(processName).append("\n");
9865            return;
9866        }
9867        // Note: ProcessRecord 'process' is guarded by the service
9868        // instance.  (notably process.pkgList, which could otherwise change
9869        // concurrently during execution of this method)
9870        synchronized (this) {
9871            sb.append("Process: ").append(processName).append("\n");
9872            int flags = process.info.flags;
9873            IPackageManager pm = AppGlobals.getPackageManager();
9874            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9875            for (int ip=0; ip<process.pkgList.size(); ip++) {
9876                String pkg = process.pkgList.keyAt(ip);
9877                sb.append("Package: ").append(pkg);
9878                try {
9879                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9880                    if (pi != null) {
9881                        sb.append(" v").append(pi.versionCode);
9882                        if (pi.versionName != null) {
9883                            sb.append(" (").append(pi.versionName).append(")");
9884                        }
9885                    }
9886                } catch (RemoteException e) {
9887                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9888                }
9889                sb.append("\n");
9890            }
9891        }
9892    }
9893
9894    private static String processClass(ProcessRecord process) {
9895        if (process == null || process.pid == MY_PID) {
9896            return "system_server";
9897        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9898            return "system_app";
9899        } else {
9900            return "data_app";
9901        }
9902    }
9903
9904    /**
9905     * Write a description of an error (crash, WTF, ANR) to the drop box.
9906     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9907     * @param process which caused the error, null means the system server
9908     * @param activity which triggered the error, null if unknown
9909     * @param parent activity related to the error, null if unknown
9910     * @param subject line related to the error, null if absent
9911     * @param report in long form describing the error, null if absent
9912     * @param logFile to include in the report, null if none
9913     * @param crashInfo giving an application stack trace, null if absent
9914     */
9915    public void addErrorToDropBox(String eventType,
9916            ProcessRecord process, String processName, ActivityRecord activity,
9917            ActivityRecord parent, String subject,
9918            final String report, final File logFile,
9919            final ApplicationErrorReport.CrashInfo crashInfo) {
9920        // NOTE -- this must never acquire the ActivityManagerService lock,
9921        // otherwise the watchdog may be prevented from resetting the system.
9922
9923        final String dropboxTag = processClass(process) + "_" + eventType;
9924        final DropBoxManager dbox = (DropBoxManager)
9925                mContext.getSystemService(Context.DROPBOX_SERVICE);
9926
9927        // Exit early if the dropbox isn't configured to accept this report type.
9928        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9929
9930        final StringBuilder sb = new StringBuilder(1024);
9931        appendDropBoxProcessHeaders(process, processName, sb);
9932        if (activity != null) {
9933            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9934        }
9935        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9936            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9937        }
9938        if (parent != null && parent != activity) {
9939            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9940        }
9941        if (subject != null) {
9942            sb.append("Subject: ").append(subject).append("\n");
9943        }
9944        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9945        if (Debug.isDebuggerConnected()) {
9946            sb.append("Debugger: Connected\n");
9947        }
9948        sb.append("\n");
9949
9950        // Do the rest in a worker thread to avoid blocking the caller on I/O
9951        // (After this point, we shouldn't access AMS internal data structures.)
9952        Thread worker = new Thread("Error dump: " + dropboxTag) {
9953            @Override
9954            public void run() {
9955                if (report != null) {
9956                    sb.append(report);
9957                }
9958                if (logFile != null) {
9959                    try {
9960                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9961                                    "\n\n[[TRUNCATED]]"));
9962                    } catch (IOException e) {
9963                        Slog.e(TAG, "Error reading " + logFile, e);
9964                    }
9965                }
9966                if (crashInfo != null && crashInfo.stackTrace != null) {
9967                    sb.append(crashInfo.stackTrace);
9968                }
9969
9970                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9971                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9972                if (lines > 0) {
9973                    sb.append("\n");
9974
9975                    // Merge several logcat streams, and take the last N lines
9976                    InputStreamReader input = null;
9977                    try {
9978                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9979                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9980                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9981
9982                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9983                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9984                        input = new InputStreamReader(logcat.getInputStream());
9985
9986                        int num;
9987                        char[] buf = new char[8192];
9988                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9989                    } catch (IOException e) {
9990                        Slog.e(TAG, "Error running logcat", e);
9991                    } finally {
9992                        if (input != null) try { input.close(); } catch (IOException e) {}
9993                    }
9994                }
9995
9996                dbox.addText(dropboxTag, sb.toString());
9997            }
9998        };
9999
10000        if (process == null) {
10001            // If process is null, we are being called from some internal code
10002            // and may be about to die -- run this synchronously.
10003            worker.run();
10004        } else {
10005            worker.start();
10006        }
10007    }
10008
10009    /**
10010     * Bring up the "unexpected error" dialog box for a crashing app.
10011     * Deal with edge cases (intercepts from instrumented applications,
10012     * ActivityController, error intent receivers, that sort of thing).
10013     * @param r the application crashing
10014     * @param crashInfo describing the failure
10015     */
10016    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10017        long timeMillis = System.currentTimeMillis();
10018        String shortMsg = crashInfo.exceptionClassName;
10019        String longMsg = crashInfo.exceptionMessage;
10020        String stackTrace = crashInfo.stackTrace;
10021        if (shortMsg != null && longMsg != null) {
10022            longMsg = shortMsg + ": " + longMsg;
10023        } else if (shortMsg != null) {
10024            longMsg = shortMsg;
10025        }
10026
10027        AppErrorResult result = new AppErrorResult();
10028        synchronized (this) {
10029            if (mController != null) {
10030                try {
10031                    String name = r != null ? r.processName : null;
10032                    int pid = r != null ? r.pid : Binder.getCallingPid();
10033                    if (!mController.appCrashed(name, pid,
10034                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10035                        Slog.w(TAG, "Force-killing crashed app " + name
10036                                + " at watcher's request");
10037                        Process.killProcess(pid);
10038                        return;
10039                    }
10040                } catch (RemoteException e) {
10041                    mController = null;
10042                    Watchdog.getInstance().setActivityController(null);
10043                }
10044            }
10045
10046            final long origId = Binder.clearCallingIdentity();
10047
10048            // If this process is running instrumentation, finish it.
10049            if (r != null && r.instrumentationClass != null) {
10050                Slog.w(TAG, "Error in app " + r.processName
10051                      + " running instrumentation " + r.instrumentationClass + ":");
10052                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10053                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10054                Bundle info = new Bundle();
10055                info.putString("shortMsg", shortMsg);
10056                info.putString("longMsg", longMsg);
10057                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10058                Binder.restoreCallingIdentity(origId);
10059                return;
10060            }
10061
10062            // If we can't identify the process or it's already exceeded its crash quota,
10063            // quit right away without showing a crash dialog.
10064            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10065                Binder.restoreCallingIdentity(origId);
10066                return;
10067            }
10068
10069            Message msg = Message.obtain();
10070            msg.what = SHOW_ERROR_MSG;
10071            HashMap data = new HashMap();
10072            data.put("result", result);
10073            data.put("app", r);
10074            msg.obj = data;
10075            mHandler.sendMessage(msg);
10076
10077            Binder.restoreCallingIdentity(origId);
10078        }
10079
10080        int res = result.get();
10081
10082        Intent appErrorIntent = null;
10083        synchronized (this) {
10084            if (r != null && !r.isolated) {
10085                // XXX Can't keep track of crash time for isolated processes,
10086                // since they don't have a persistent identity.
10087                mProcessCrashTimes.put(r.info.processName, r.uid,
10088                        SystemClock.uptimeMillis());
10089            }
10090            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10091                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10092            }
10093        }
10094
10095        if (appErrorIntent != null) {
10096            try {
10097                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10098            } catch (ActivityNotFoundException e) {
10099                Slog.w(TAG, "bug report receiver dissappeared", e);
10100            }
10101        }
10102    }
10103
10104    Intent createAppErrorIntentLocked(ProcessRecord r,
10105            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10106        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10107        if (report == null) {
10108            return null;
10109        }
10110        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10111        result.setComponent(r.errorReportReceiver);
10112        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10113        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10114        return result;
10115    }
10116
10117    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10118            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10119        if (r.errorReportReceiver == null) {
10120            return null;
10121        }
10122
10123        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10124            return null;
10125        }
10126
10127        ApplicationErrorReport report = new ApplicationErrorReport();
10128        report.packageName = r.info.packageName;
10129        report.installerPackageName = r.errorReportReceiver.getPackageName();
10130        report.processName = r.processName;
10131        report.time = timeMillis;
10132        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10133
10134        if (r.crashing || r.forceCrashReport) {
10135            report.type = ApplicationErrorReport.TYPE_CRASH;
10136            report.crashInfo = crashInfo;
10137        } else if (r.notResponding) {
10138            report.type = ApplicationErrorReport.TYPE_ANR;
10139            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10140
10141            report.anrInfo.activity = r.notRespondingReport.tag;
10142            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10143            report.anrInfo.info = r.notRespondingReport.longMsg;
10144        }
10145
10146        return report;
10147    }
10148
10149    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10150        enforceNotIsolatedCaller("getProcessesInErrorState");
10151        // assume our apps are happy - lazy create the list
10152        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10153
10154        final boolean allUsers = ActivityManager.checkUidPermission(
10155                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10156                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10157        int userId = UserHandle.getUserId(Binder.getCallingUid());
10158
10159        synchronized (this) {
10160
10161            // iterate across all processes
10162            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10163                ProcessRecord app = mLruProcesses.get(i);
10164                if (!allUsers && app.userId != userId) {
10165                    continue;
10166                }
10167                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10168                    // This one's in trouble, so we'll generate a report for it
10169                    // crashes are higher priority (in case there's a crash *and* an anr)
10170                    ActivityManager.ProcessErrorStateInfo report = null;
10171                    if (app.crashing) {
10172                        report = app.crashingReport;
10173                    } else if (app.notResponding) {
10174                        report = app.notRespondingReport;
10175                    }
10176
10177                    if (report != null) {
10178                        if (errList == null) {
10179                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10180                        }
10181                        errList.add(report);
10182                    } else {
10183                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10184                                " crashing = " + app.crashing +
10185                                " notResponding = " + app.notResponding);
10186                    }
10187                }
10188            }
10189        }
10190
10191        return errList;
10192    }
10193
10194    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10195        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10196            if (currApp != null) {
10197                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10198            }
10199            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10200        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10201            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10202        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10203            if (currApp != null) {
10204                currApp.lru = 0;
10205            }
10206            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10207        } else if (adj >= ProcessList.SERVICE_ADJ) {
10208            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10209        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10210            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10211        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10212            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10213        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10214            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10215        } else {
10216            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10217        }
10218    }
10219
10220    private void fillInProcMemInfo(ProcessRecord app,
10221            ActivityManager.RunningAppProcessInfo outInfo) {
10222        outInfo.pid = app.pid;
10223        outInfo.uid = app.info.uid;
10224        if (mHeavyWeightProcess == app) {
10225            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10226        }
10227        if (app.persistent) {
10228            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10229        }
10230        if (app.activities.size() > 0) {
10231            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10232        }
10233        outInfo.lastTrimLevel = app.trimMemoryLevel;
10234        int adj = app.curAdj;
10235        outInfo.importance = oomAdjToImportance(adj, outInfo);
10236        outInfo.importanceReasonCode = app.adjTypeCode;
10237    }
10238
10239    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10240        enforceNotIsolatedCaller("getRunningAppProcesses");
10241        // Lazy instantiation of list
10242        List<ActivityManager.RunningAppProcessInfo> runList = null;
10243        final boolean allUsers = ActivityManager.checkUidPermission(
10244                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10245                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10246        int userId = UserHandle.getUserId(Binder.getCallingUid());
10247        synchronized (this) {
10248            // Iterate across all processes
10249            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10250                ProcessRecord app = mLruProcesses.get(i);
10251                if (!allUsers && app.userId != userId) {
10252                    continue;
10253                }
10254                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10255                    // Generate process state info for running application
10256                    ActivityManager.RunningAppProcessInfo currApp =
10257                        new ActivityManager.RunningAppProcessInfo(app.processName,
10258                                app.pid, app.getPackageList());
10259                    fillInProcMemInfo(app, currApp);
10260                    if (app.adjSource instanceof ProcessRecord) {
10261                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10262                        currApp.importanceReasonImportance = oomAdjToImportance(
10263                                app.adjSourceOom, null);
10264                    } else if (app.adjSource instanceof ActivityRecord) {
10265                        ActivityRecord r = (ActivityRecord)app.adjSource;
10266                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10267                    }
10268                    if (app.adjTarget instanceof ComponentName) {
10269                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10270                    }
10271                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10272                    //        + " lru=" + currApp.lru);
10273                    if (runList == null) {
10274                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10275                    }
10276                    runList.add(currApp);
10277                }
10278            }
10279        }
10280        return runList;
10281    }
10282
10283    public List<ApplicationInfo> getRunningExternalApplications() {
10284        enforceNotIsolatedCaller("getRunningExternalApplications");
10285        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10286        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10287        if (runningApps != null && runningApps.size() > 0) {
10288            Set<String> extList = new HashSet<String>();
10289            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10290                if (app.pkgList != null) {
10291                    for (String pkg : app.pkgList) {
10292                        extList.add(pkg);
10293                    }
10294                }
10295            }
10296            IPackageManager pm = AppGlobals.getPackageManager();
10297            for (String pkg : extList) {
10298                try {
10299                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10300                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10301                        retList.add(info);
10302                    }
10303                } catch (RemoteException e) {
10304                }
10305            }
10306        }
10307        return retList;
10308    }
10309
10310    @Override
10311    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10312        enforceNotIsolatedCaller("getMyMemoryState");
10313        synchronized (this) {
10314            ProcessRecord proc;
10315            synchronized (mPidsSelfLocked) {
10316                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10317            }
10318            fillInProcMemInfo(proc, outInfo);
10319        }
10320    }
10321
10322    @Override
10323    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10324        if (checkCallingPermission(android.Manifest.permission.DUMP)
10325                != PackageManager.PERMISSION_GRANTED) {
10326            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10327                    + Binder.getCallingPid()
10328                    + ", uid=" + Binder.getCallingUid()
10329                    + " without permission "
10330                    + android.Manifest.permission.DUMP);
10331            return;
10332        }
10333
10334        boolean dumpAll = false;
10335        boolean dumpClient = false;
10336        String dumpPackage = null;
10337
10338        int opti = 0;
10339        while (opti < args.length) {
10340            String opt = args[opti];
10341            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10342                break;
10343            }
10344            opti++;
10345            if ("-a".equals(opt)) {
10346                dumpAll = true;
10347            } else if ("-c".equals(opt)) {
10348                dumpClient = true;
10349            } else if ("-h".equals(opt)) {
10350                pw.println("Activity manager dump options:");
10351                pw.println("  [-a] [-c] [-h] [cmd] ...");
10352                pw.println("  cmd may be one of:");
10353                pw.println("    a[ctivities]: activity stack state");
10354                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10355                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10356                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10357                pw.println("    o[om]: out of memory management");
10358                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10359                pw.println("    provider [COMP_SPEC]: provider client-side state");
10360                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10361                pw.println("    service [COMP_SPEC]: service client-side state");
10362                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10363                pw.println("    all: dump all activities");
10364                pw.println("    top: dump the top activity");
10365                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10366                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10367                pw.println("    a partial substring in a component name, a");
10368                pw.println("    hex object identifier.");
10369                pw.println("  -a: include all available server state.");
10370                pw.println("  -c: include client state.");
10371                return;
10372            } else {
10373                pw.println("Unknown argument: " + opt + "; use -h for help");
10374            }
10375        }
10376
10377        long origId = Binder.clearCallingIdentity();
10378        boolean more = false;
10379        // Is the caller requesting to dump a particular piece of data?
10380        if (opti < args.length) {
10381            String cmd = args[opti];
10382            opti++;
10383            if ("activities".equals(cmd) || "a".equals(cmd)) {
10384                synchronized (this) {
10385                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10386                }
10387            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10388                String[] newArgs;
10389                String name;
10390                if (opti >= args.length) {
10391                    name = null;
10392                    newArgs = EMPTY_STRING_ARRAY;
10393                } else {
10394                    name = args[opti];
10395                    opti++;
10396                    newArgs = new String[args.length - opti];
10397                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10398                            args.length - opti);
10399                }
10400                synchronized (this) {
10401                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10402                }
10403            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10404                String[] newArgs;
10405                String name;
10406                if (opti >= args.length) {
10407                    name = null;
10408                    newArgs = EMPTY_STRING_ARRAY;
10409                } else {
10410                    name = args[opti];
10411                    opti++;
10412                    newArgs = new String[args.length - opti];
10413                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10414                            args.length - opti);
10415                }
10416                synchronized (this) {
10417                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10418                }
10419            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10420                String[] newArgs;
10421                String name;
10422                if (opti >= args.length) {
10423                    name = null;
10424                    newArgs = EMPTY_STRING_ARRAY;
10425                } else {
10426                    name = args[opti];
10427                    opti++;
10428                    newArgs = new String[args.length - opti];
10429                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10430                            args.length - opti);
10431                }
10432                synchronized (this) {
10433                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10434                }
10435            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10436                synchronized (this) {
10437                    dumpOomLocked(fd, pw, args, opti, true);
10438                }
10439            } else if ("provider".equals(cmd)) {
10440                String[] newArgs;
10441                String name;
10442                if (opti >= args.length) {
10443                    name = null;
10444                    newArgs = EMPTY_STRING_ARRAY;
10445                } else {
10446                    name = args[opti];
10447                    opti++;
10448                    newArgs = new String[args.length - opti];
10449                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10450                }
10451                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10452                    pw.println("No providers match: " + name);
10453                    pw.println("Use -h for help.");
10454                }
10455            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10456                synchronized (this) {
10457                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10458                }
10459            } else if ("service".equals(cmd)) {
10460                String[] newArgs;
10461                String name;
10462                if (opti >= args.length) {
10463                    name = null;
10464                    newArgs = EMPTY_STRING_ARRAY;
10465                } else {
10466                    name = args[opti];
10467                    opti++;
10468                    newArgs = new String[args.length - opti];
10469                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10470                            args.length - opti);
10471                }
10472                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10473                    pw.println("No services match: " + name);
10474                    pw.println("Use -h for help.");
10475                }
10476            } else if ("package".equals(cmd)) {
10477                String[] newArgs;
10478                if (opti >= args.length) {
10479                    pw.println("package: no package name specified");
10480                    pw.println("Use -h for help.");
10481                } else {
10482                    dumpPackage = args[opti];
10483                    opti++;
10484                    newArgs = new String[args.length - opti];
10485                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10486                            args.length - opti);
10487                    args = newArgs;
10488                    opti = 0;
10489                    more = true;
10490                }
10491            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10492                synchronized (this) {
10493                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10494                }
10495            } else {
10496                // Dumping a single activity?
10497                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10498                    pw.println("Bad activity command, or no activities match: " + cmd);
10499                    pw.println("Use -h for help.");
10500                }
10501            }
10502            if (!more) {
10503                Binder.restoreCallingIdentity(origId);
10504                return;
10505            }
10506        }
10507
10508        // No piece of data specified, dump everything.
10509        synchronized (this) {
10510            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10511            pw.println();
10512            if (dumpAll) {
10513                pw.println("-------------------------------------------------------------------------------");
10514            }
10515            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10516            pw.println();
10517            if (dumpAll) {
10518                pw.println("-------------------------------------------------------------------------------");
10519            }
10520            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10521            pw.println();
10522            if (dumpAll) {
10523                pw.println("-------------------------------------------------------------------------------");
10524            }
10525            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10526            pw.println();
10527            if (dumpAll) {
10528                pw.println("-------------------------------------------------------------------------------");
10529            }
10530            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10531            pw.println();
10532            if (dumpAll) {
10533                pw.println("-------------------------------------------------------------------------------");
10534            }
10535            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10536        }
10537        Binder.restoreCallingIdentity(origId);
10538    }
10539
10540    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10541            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10542        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10543
10544        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10545                dumpPackage);
10546        boolean needSep = printedAnything;
10547
10548        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10549                dumpPackage, needSep, "  mFocusedActivity: ");
10550        if (printed) {
10551            printedAnything = true;
10552            needSep = false;
10553        }
10554
10555        if (dumpPackage == null) {
10556            if (needSep) {
10557                pw.println();
10558            }
10559            needSep = true;
10560            printedAnything = true;
10561            mStackSupervisor.dump(pw, "  ");
10562        }
10563
10564        if (mRecentTasks.size() > 0) {
10565            boolean printedHeader = false;
10566
10567            final int N = mRecentTasks.size();
10568            for (int i=0; i<N; i++) {
10569                TaskRecord tr = mRecentTasks.get(i);
10570                if (dumpPackage != null) {
10571                    if (tr.realActivity == null ||
10572                            !dumpPackage.equals(tr.realActivity)) {
10573                        continue;
10574                    }
10575                }
10576                if (!printedHeader) {
10577                    if (needSep) {
10578                        pw.println();
10579                    }
10580                    pw.println("  Recent tasks:");
10581                    printedHeader = true;
10582                    printedAnything = true;
10583                }
10584                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10585                        pw.println(tr);
10586                if (dumpAll) {
10587                    mRecentTasks.get(i).dump(pw, "    ");
10588                }
10589            }
10590        }
10591
10592        if (!printedAnything) {
10593            pw.println("  (nothing)");
10594        }
10595    }
10596
10597    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10598            int opti, boolean dumpAll, String dumpPackage) {
10599        boolean needSep = false;
10600        boolean printedAnything = false;
10601        int numPers = 0;
10602
10603        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10604
10605        if (dumpAll) {
10606            final int NP = mProcessNames.getMap().size();
10607            for (int ip=0; ip<NP; ip++) {
10608                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10609                final int NA = procs.size();
10610                for (int ia=0; ia<NA; ia++) {
10611                    ProcessRecord r = procs.valueAt(ia);
10612                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10613                        continue;
10614                    }
10615                    if (!needSep) {
10616                        pw.println("  All known processes:");
10617                        needSep = true;
10618                        printedAnything = true;
10619                    }
10620                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10621                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10622                        pw.print(" "); pw.println(r);
10623                    r.dump(pw, "    ");
10624                    if (r.persistent) {
10625                        numPers++;
10626                    }
10627                }
10628            }
10629        }
10630
10631        if (mIsolatedProcesses.size() > 0) {
10632            boolean printed = false;
10633            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10634                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10635                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10636                    continue;
10637                }
10638                if (!printed) {
10639                    if (needSep) {
10640                        pw.println();
10641                    }
10642                    pw.println("  Isolated process list (sorted by uid):");
10643                    printedAnything = true;
10644                    printed = true;
10645                    needSep = true;
10646                }
10647                pw.println(String.format("%sIsolated #%2d: %s",
10648                        "    ", i, r.toString()));
10649            }
10650        }
10651
10652        if (mLruProcesses.size() > 0) {
10653            if (needSep) {
10654                pw.println();
10655            }
10656            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10657                    pw.print(" total, non-act at ");
10658                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10659                    pw.print(", non-svc at ");
10660                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10661                    pw.println("):");
10662            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10663            needSep = true;
10664            printedAnything = true;
10665        }
10666
10667        if (dumpAll || dumpPackage != null) {
10668            synchronized (mPidsSelfLocked) {
10669                boolean printed = false;
10670                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10671                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10672                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10673                        continue;
10674                    }
10675                    if (!printed) {
10676                        if (needSep) pw.println();
10677                        needSep = true;
10678                        pw.println("  PID mappings:");
10679                        printed = true;
10680                        printedAnything = true;
10681                    }
10682                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10683                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10684                }
10685            }
10686        }
10687
10688        if (mForegroundProcesses.size() > 0) {
10689            synchronized (mPidsSelfLocked) {
10690                boolean printed = false;
10691                for (int i=0; i<mForegroundProcesses.size(); i++) {
10692                    ProcessRecord r = mPidsSelfLocked.get(
10693                            mForegroundProcesses.valueAt(i).pid);
10694                    if (dumpPackage != null && (r == null
10695                            || !r.pkgList.containsKey(dumpPackage))) {
10696                        continue;
10697                    }
10698                    if (!printed) {
10699                        if (needSep) pw.println();
10700                        needSep = true;
10701                        pw.println("  Foreground Processes:");
10702                        printed = true;
10703                        printedAnything = true;
10704                    }
10705                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10706                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10707                }
10708            }
10709        }
10710
10711        if (mPersistentStartingProcesses.size() > 0) {
10712            if (needSep) pw.println();
10713            needSep = true;
10714            printedAnything = true;
10715            pw.println("  Persisent processes that are starting:");
10716            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10717                    "Starting Norm", "Restarting PERS", dumpPackage);
10718        }
10719
10720        if (mRemovedProcesses.size() > 0) {
10721            if (needSep) pw.println();
10722            needSep = true;
10723            printedAnything = true;
10724            pw.println("  Processes that are being removed:");
10725            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10726                    "Removed Norm", "Removed PERS", dumpPackage);
10727        }
10728
10729        if (mProcessesOnHold.size() > 0) {
10730            if (needSep) pw.println();
10731            needSep = true;
10732            printedAnything = true;
10733            pw.println("  Processes that are on old until the system is ready:");
10734            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10735                    "OnHold Norm", "OnHold PERS", dumpPackage);
10736        }
10737
10738        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10739
10740        if (mProcessCrashTimes.getMap().size() > 0) {
10741            boolean printed = false;
10742            long now = SystemClock.uptimeMillis();
10743            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10744            final int NP = pmap.size();
10745            for (int ip=0; ip<NP; ip++) {
10746                String pname = pmap.keyAt(ip);
10747                SparseArray<Long> uids = pmap.valueAt(ip);
10748                final int N = uids.size();
10749                for (int i=0; i<N; i++) {
10750                    int puid = uids.keyAt(i);
10751                    ProcessRecord r = mProcessNames.get(pname, puid);
10752                    if (dumpPackage != null && (r == null
10753                            || !r.pkgList.containsKey(dumpPackage))) {
10754                        continue;
10755                    }
10756                    if (!printed) {
10757                        if (needSep) pw.println();
10758                        needSep = true;
10759                        pw.println("  Time since processes crashed:");
10760                        printed = true;
10761                        printedAnything = true;
10762                    }
10763                    pw.print("    Process "); pw.print(pname);
10764                            pw.print(" uid "); pw.print(puid);
10765                            pw.print(": last crashed ");
10766                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10767                            pw.println(" ago");
10768                }
10769            }
10770        }
10771
10772        if (mBadProcesses.getMap().size() > 0) {
10773            boolean printed = false;
10774            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10775            final int NP = pmap.size();
10776            for (int ip=0; ip<NP; ip++) {
10777                String pname = pmap.keyAt(ip);
10778                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10779                final int N = uids.size();
10780                for (int i=0; i<N; i++) {
10781                    int puid = uids.keyAt(i);
10782                    ProcessRecord r = mProcessNames.get(pname, puid);
10783                    if (dumpPackage != null && (r == null
10784                            || !r.pkgList.containsKey(dumpPackage))) {
10785                        continue;
10786                    }
10787                    if (!printed) {
10788                        if (needSep) pw.println();
10789                        needSep = true;
10790                        pw.println("  Bad processes:");
10791                        printedAnything = true;
10792                    }
10793                    BadProcessInfo info = uids.valueAt(i);
10794                    pw.print("    Bad process "); pw.print(pname);
10795                            pw.print(" uid "); pw.print(puid);
10796                            pw.print(": crashed at time "); pw.println(info.time);
10797                    if (info.shortMsg != null) {
10798                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10799                    }
10800                    if (info.longMsg != null) {
10801                        pw.print("      Long msg: "); pw.println(info.longMsg);
10802                    }
10803                    if (info.stack != null) {
10804                        pw.println("      Stack:");
10805                        int lastPos = 0;
10806                        for (int pos=0; pos<info.stack.length(); pos++) {
10807                            if (info.stack.charAt(pos) == '\n') {
10808                                pw.print("        ");
10809                                pw.write(info.stack, lastPos, pos-lastPos);
10810                                pw.println();
10811                                lastPos = pos+1;
10812                            }
10813                        }
10814                        if (lastPos < info.stack.length()) {
10815                            pw.print("        ");
10816                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10817                            pw.println();
10818                        }
10819                    }
10820                }
10821            }
10822        }
10823
10824        if (dumpPackage == null) {
10825            pw.println();
10826            needSep = false;
10827            pw.println("  mStartedUsers:");
10828            for (int i=0; i<mStartedUsers.size(); i++) {
10829                UserStartedState uss = mStartedUsers.valueAt(i);
10830                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10831                        pw.print(": "); uss.dump("", pw);
10832            }
10833            pw.print("  mStartedUserArray: [");
10834            for (int i=0; i<mStartedUserArray.length; i++) {
10835                if (i > 0) pw.print(", ");
10836                pw.print(mStartedUserArray[i]);
10837            }
10838            pw.println("]");
10839            pw.print("  mUserLru: [");
10840            for (int i=0; i<mUserLru.size(); i++) {
10841                if (i > 0) pw.print(", ");
10842                pw.print(mUserLru.get(i));
10843            }
10844            pw.println("]");
10845            if (dumpAll) {
10846                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10847            }
10848        }
10849        if (mHomeProcess != null && (dumpPackage == null
10850                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10851            if (needSep) {
10852                pw.println();
10853                needSep = false;
10854            }
10855            pw.println("  mHomeProcess: " + mHomeProcess);
10856        }
10857        if (mPreviousProcess != null && (dumpPackage == null
10858                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10859            if (needSep) {
10860                pw.println();
10861                needSep = false;
10862            }
10863            pw.println("  mPreviousProcess: " + mPreviousProcess);
10864        }
10865        if (dumpAll) {
10866            StringBuilder sb = new StringBuilder(128);
10867            sb.append("  mPreviousProcessVisibleTime: ");
10868            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10869            pw.println(sb);
10870        }
10871        if (mHeavyWeightProcess != null && (dumpPackage == null
10872                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10873            if (needSep) {
10874                pw.println();
10875                needSep = false;
10876            }
10877            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10878        }
10879        if (dumpPackage == null) {
10880            pw.println("  mConfiguration: " + mConfiguration);
10881        }
10882        if (dumpAll) {
10883            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10884            if (mCompatModePackages.getPackages().size() > 0) {
10885                boolean printed = false;
10886                for (Map.Entry<String, Integer> entry
10887                        : mCompatModePackages.getPackages().entrySet()) {
10888                    String pkg = entry.getKey();
10889                    int mode = entry.getValue();
10890                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10891                        continue;
10892                    }
10893                    if (!printed) {
10894                        pw.println("  mScreenCompatPackages:");
10895                        printed = true;
10896                    }
10897                    pw.print("    "); pw.print(pkg); pw.print(": ");
10898                            pw.print(mode); pw.println();
10899                }
10900            }
10901        }
10902        if (dumpPackage == null) {
10903            if (mSleeping || mWentToSleep || mLockScreenShown) {
10904                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10905                        + " mLockScreenShown " + mLockScreenShown);
10906            }
10907            if (mShuttingDown) {
10908                pw.println("  mShuttingDown=" + mShuttingDown);
10909            }
10910        }
10911        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10912                || mOrigWaitForDebugger) {
10913            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10914                    || dumpPackage.equals(mOrigDebugApp)) {
10915                if (needSep) {
10916                    pw.println();
10917                    needSep = false;
10918                }
10919                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10920                        + " mDebugTransient=" + mDebugTransient
10921                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10922            }
10923        }
10924        if (mOpenGlTraceApp != null) {
10925            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10926                if (needSep) {
10927                    pw.println();
10928                    needSep = false;
10929                }
10930                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10931            }
10932        }
10933        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10934                || mProfileFd != null) {
10935            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10936                if (needSep) {
10937                    pw.println();
10938                    needSep = false;
10939                }
10940                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10941                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10942                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10943                        + mAutoStopProfiler);
10944            }
10945        }
10946        if (dumpPackage == null) {
10947            if (mAlwaysFinishActivities || mController != null) {
10948                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10949                        + " mController=" + mController);
10950            }
10951            if (dumpAll) {
10952                pw.println("  Total persistent processes: " + numPers);
10953                pw.println("  mStartRunning=" + mStartRunning
10954                        + " mProcessesReady=" + mProcessesReady
10955                        + " mSystemReady=" + mSystemReady);
10956                pw.println("  mBooting=" + mBooting
10957                        + " mBooted=" + mBooted
10958                        + " mFactoryTest=" + mFactoryTest);
10959                pw.print("  mLastPowerCheckRealtime=");
10960                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10961                        pw.println("");
10962                pw.print("  mLastPowerCheckUptime=");
10963                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10964                        pw.println("");
10965                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10966                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10967                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10968                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10969                        + " (" + mLruProcesses.size() + " total)"
10970                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10971                        + " mNumServiceProcs=" + mNumServiceProcs
10972                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10973                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10974                        + " mLastMemoryLevel" + mLastMemoryLevel
10975                        + " mLastNumProcesses" + mLastNumProcesses);
10976                long now = SystemClock.uptimeMillis();
10977                pw.print("  mLastIdleTime=");
10978                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10979                        pw.print(" mLowRamSinceLastIdle=");
10980                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10981                        pw.println();
10982            }
10983        }
10984
10985        if (!printedAnything) {
10986            pw.println("  (nothing)");
10987        }
10988    }
10989
10990    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10991            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10992        if (mProcessesToGc.size() > 0) {
10993            boolean printed = false;
10994            long now = SystemClock.uptimeMillis();
10995            for (int i=0; i<mProcessesToGc.size(); i++) {
10996                ProcessRecord proc = mProcessesToGc.get(i);
10997                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10998                    continue;
10999                }
11000                if (!printed) {
11001                    if (needSep) pw.println();
11002                    needSep = true;
11003                    pw.println("  Processes that are waiting to GC:");
11004                    printed = true;
11005                }
11006                pw.print("    Process "); pw.println(proc);
11007                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11008                        pw.print(", last gced=");
11009                        pw.print(now-proc.lastRequestedGc);
11010                        pw.print(" ms ago, last lowMem=");
11011                        pw.print(now-proc.lastLowMemory);
11012                        pw.println(" ms ago");
11013
11014            }
11015        }
11016        return needSep;
11017    }
11018
11019    void printOomLevel(PrintWriter pw, String name, int adj) {
11020        pw.print("    ");
11021        if (adj >= 0) {
11022            pw.print(' ');
11023            if (adj < 10) pw.print(' ');
11024        } else {
11025            if (adj > -10) pw.print(' ');
11026        }
11027        pw.print(adj);
11028        pw.print(": ");
11029        pw.print(name);
11030        pw.print(" (");
11031        pw.print(mProcessList.getMemLevel(adj)/1024);
11032        pw.println(" kB)");
11033    }
11034
11035    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11036            int opti, boolean dumpAll) {
11037        boolean needSep = false;
11038
11039        if (mLruProcesses.size() > 0) {
11040            if (needSep) pw.println();
11041            needSep = true;
11042            pw.println("  OOM levels:");
11043            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11044            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11045            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11046            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11047            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11048            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11049            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11050            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11051            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11052            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11053            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11054            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11055            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11056
11057            if (needSep) pw.println();
11058            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11059                    pw.print(" total, non-act at ");
11060                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11061                    pw.print(", non-svc at ");
11062                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11063                    pw.println("):");
11064            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11065            needSep = true;
11066        }
11067
11068        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11069
11070        pw.println();
11071        pw.println("  mHomeProcess: " + mHomeProcess);
11072        pw.println("  mPreviousProcess: " + mPreviousProcess);
11073        if (mHeavyWeightProcess != null) {
11074            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11075        }
11076
11077        return true;
11078    }
11079
11080    /**
11081     * There are three ways to call this:
11082     *  - no provider specified: dump all the providers
11083     *  - a flattened component name that matched an existing provider was specified as the
11084     *    first arg: dump that one provider
11085     *  - the first arg isn't the flattened component name of an existing provider:
11086     *    dump all providers whose component contains the first arg as a substring
11087     */
11088    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11089            int opti, boolean dumpAll) {
11090        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11091    }
11092
11093    static class ItemMatcher {
11094        ArrayList<ComponentName> components;
11095        ArrayList<String> strings;
11096        ArrayList<Integer> objects;
11097        boolean all;
11098
11099        ItemMatcher() {
11100            all = true;
11101        }
11102
11103        void build(String name) {
11104            ComponentName componentName = ComponentName.unflattenFromString(name);
11105            if (componentName != null) {
11106                if (components == null) {
11107                    components = new ArrayList<ComponentName>();
11108                }
11109                components.add(componentName);
11110                all = false;
11111            } else {
11112                int objectId = 0;
11113                // Not a '/' separated full component name; maybe an object ID?
11114                try {
11115                    objectId = Integer.parseInt(name, 16);
11116                    if (objects == null) {
11117                        objects = new ArrayList<Integer>();
11118                    }
11119                    objects.add(objectId);
11120                    all = false;
11121                } catch (RuntimeException e) {
11122                    // Not an integer; just do string match.
11123                    if (strings == null) {
11124                        strings = new ArrayList<String>();
11125                    }
11126                    strings.add(name);
11127                    all = false;
11128                }
11129            }
11130        }
11131
11132        int build(String[] args, int opti) {
11133            for (; opti<args.length; opti++) {
11134                String name = args[opti];
11135                if ("--".equals(name)) {
11136                    return opti+1;
11137                }
11138                build(name);
11139            }
11140            return opti;
11141        }
11142
11143        boolean match(Object object, ComponentName comp) {
11144            if (all) {
11145                return true;
11146            }
11147            if (components != null) {
11148                for (int i=0; i<components.size(); i++) {
11149                    if (components.get(i).equals(comp)) {
11150                        return true;
11151                    }
11152                }
11153            }
11154            if (objects != null) {
11155                for (int i=0; i<objects.size(); i++) {
11156                    if (System.identityHashCode(object) == objects.get(i)) {
11157                        return true;
11158                    }
11159                }
11160            }
11161            if (strings != null) {
11162                String flat = comp.flattenToString();
11163                for (int i=0; i<strings.size(); i++) {
11164                    if (flat.contains(strings.get(i))) {
11165                        return true;
11166                    }
11167                }
11168            }
11169            return false;
11170        }
11171    }
11172
11173    /**
11174     * There are three things that cmd can be:
11175     *  - a flattened component name that matches an existing activity
11176     *  - the cmd arg isn't the flattened component name of an existing activity:
11177     *    dump all activity whose component contains the cmd as a substring
11178     *  - A hex number of the ActivityRecord object instance.
11179     */
11180    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11181            int opti, boolean dumpAll) {
11182        ArrayList<ActivityRecord> activities;
11183
11184        synchronized (this) {
11185            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11186        }
11187
11188        if (activities.size() <= 0) {
11189            return false;
11190        }
11191
11192        String[] newArgs = new String[args.length - opti];
11193        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11194
11195        TaskRecord lastTask = null;
11196        boolean needSep = false;
11197        for (int i=activities.size()-1; i>=0; i--) {
11198            ActivityRecord r = activities.get(i);
11199            if (needSep) {
11200                pw.println();
11201            }
11202            needSep = true;
11203            synchronized (this) {
11204                if (lastTask != r.task) {
11205                    lastTask = r.task;
11206                    pw.print("TASK "); pw.print(lastTask.affinity);
11207                            pw.print(" id="); pw.println(lastTask.taskId);
11208                    if (dumpAll) {
11209                        lastTask.dump(pw, "  ");
11210                    }
11211                }
11212            }
11213            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11214        }
11215        return true;
11216    }
11217
11218    /**
11219     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11220     * there is a thread associated with the activity.
11221     */
11222    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11223            final ActivityRecord r, String[] args, boolean dumpAll) {
11224        String innerPrefix = prefix + "  ";
11225        synchronized (this) {
11226            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11227                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11228                    pw.print(" pid=");
11229                    if (r.app != null) pw.println(r.app.pid);
11230                    else pw.println("(not running)");
11231            if (dumpAll) {
11232                r.dump(pw, innerPrefix);
11233            }
11234        }
11235        if (r.app != null && r.app.thread != null) {
11236            // flush anything that is already in the PrintWriter since the thread is going
11237            // to write to the file descriptor directly
11238            pw.flush();
11239            try {
11240                TransferPipe tp = new TransferPipe();
11241                try {
11242                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11243                            r.appToken, innerPrefix, args);
11244                    tp.go(fd);
11245                } finally {
11246                    tp.kill();
11247                }
11248            } catch (IOException e) {
11249                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11250            } catch (RemoteException e) {
11251                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11252            }
11253        }
11254    }
11255
11256    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11257            int opti, boolean dumpAll, String dumpPackage) {
11258        boolean needSep = false;
11259        boolean onlyHistory = false;
11260        boolean printedAnything = false;
11261
11262        if ("history".equals(dumpPackage)) {
11263            if (opti < args.length && "-s".equals(args[opti])) {
11264                dumpAll = false;
11265            }
11266            onlyHistory = true;
11267            dumpPackage = null;
11268        }
11269
11270        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11271        if (!onlyHistory && dumpAll) {
11272            if (mRegisteredReceivers.size() > 0) {
11273                boolean printed = false;
11274                Iterator it = mRegisteredReceivers.values().iterator();
11275                while (it.hasNext()) {
11276                    ReceiverList r = (ReceiverList)it.next();
11277                    if (dumpPackage != null && (r.app == null ||
11278                            !dumpPackage.equals(r.app.info.packageName))) {
11279                        continue;
11280                    }
11281                    if (!printed) {
11282                        pw.println("  Registered Receivers:");
11283                        needSep = true;
11284                        printed = true;
11285                        printedAnything = true;
11286                    }
11287                    pw.print("  * "); pw.println(r);
11288                    r.dump(pw, "    ");
11289                }
11290            }
11291
11292            if (mReceiverResolver.dump(pw, needSep ?
11293                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11294                    "    ", dumpPackage, false)) {
11295                needSep = true;
11296                printedAnything = true;
11297            }
11298        }
11299
11300        for (BroadcastQueue q : mBroadcastQueues) {
11301            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11302            printedAnything |= needSep;
11303        }
11304
11305        needSep = true;
11306
11307        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11308            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11309                if (needSep) {
11310                    pw.println();
11311                }
11312                needSep = true;
11313                printedAnything = true;
11314                pw.print("  Sticky broadcasts for user ");
11315                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11316                StringBuilder sb = new StringBuilder(128);
11317                for (Map.Entry<String, ArrayList<Intent>> ent
11318                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11319                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11320                    if (dumpAll) {
11321                        pw.println(":");
11322                        ArrayList<Intent> intents = ent.getValue();
11323                        final int N = intents.size();
11324                        for (int i=0; i<N; i++) {
11325                            sb.setLength(0);
11326                            sb.append("    Intent: ");
11327                            intents.get(i).toShortString(sb, false, true, false, false);
11328                            pw.println(sb.toString());
11329                            Bundle bundle = intents.get(i).getExtras();
11330                            if (bundle != null) {
11331                                pw.print("      ");
11332                                pw.println(bundle.toString());
11333                            }
11334                        }
11335                    } else {
11336                        pw.println("");
11337                    }
11338                }
11339            }
11340        }
11341
11342        if (!onlyHistory && dumpAll) {
11343            pw.println();
11344            for (BroadcastQueue queue : mBroadcastQueues) {
11345                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11346                        + queue.mBroadcastsScheduled);
11347            }
11348            pw.println("  mHandler:");
11349            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11350            needSep = true;
11351            printedAnything = true;
11352        }
11353
11354        if (!printedAnything) {
11355            pw.println("  (nothing)");
11356        }
11357    }
11358
11359    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11360            int opti, boolean dumpAll, String dumpPackage) {
11361        boolean needSep;
11362        boolean printedAnything = false;
11363
11364        ItemMatcher matcher = new ItemMatcher();
11365        matcher.build(args, opti);
11366
11367        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11368
11369        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11370        printedAnything |= needSep;
11371
11372        if (mLaunchingProviders.size() > 0) {
11373            boolean printed = false;
11374            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11375                ContentProviderRecord r = mLaunchingProviders.get(i);
11376                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11377                    continue;
11378                }
11379                if (!printed) {
11380                    if (needSep) pw.println();
11381                    needSep = true;
11382                    pw.println("  Launching content providers:");
11383                    printed = true;
11384                    printedAnything = true;
11385                }
11386                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11387                        pw.println(r);
11388            }
11389        }
11390
11391        if (mGrantedUriPermissions.size() > 0) {
11392            boolean printed = false;
11393            int dumpUid = -2;
11394            if (dumpPackage != null) {
11395                try {
11396                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11397                } catch (NameNotFoundException e) {
11398                    dumpUid = -1;
11399                }
11400            }
11401            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11402                int uid = mGrantedUriPermissions.keyAt(i);
11403                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11404                    continue;
11405                }
11406                ArrayMap<Uri, UriPermission> perms
11407                        = mGrantedUriPermissions.valueAt(i);
11408                if (!printed) {
11409                    if (needSep) pw.println();
11410                    needSep = true;
11411                    pw.println("  Granted Uri Permissions:");
11412                    printed = true;
11413                    printedAnything = true;
11414                }
11415                pw.print("  * UID "); pw.print(uid);
11416                        pw.println(" holds:");
11417                for (UriPermission perm : perms.values()) {
11418                    pw.print("    "); pw.println(perm);
11419                    if (dumpAll) {
11420                        perm.dump(pw, "      ");
11421                    }
11422                }
11423            }
11424        }
11425
11426        if (!printedAnything) {
11427            pw.println("  (nothing)");
11428        }
11429    }
11430
11431    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11432            int opti, boolean dumpAll, String dumpPackage) {
11433        boolean printed = false;
11434
11435        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11436
11437        if (mIntentSenderRecords.size() > 0) {
11438            Iterator<WeakReference<PendingIntentRecord>> it
11439                    = mIntentSenderRecords.values().iterator();
11440            while (it.hasNext()) {
11441                WeakReference<PendingIntentRecord> ref = it.next();
11442                PendingIntentRecord rec = ref != null ? ref.get(): null;
11443                if (dumpPackage != null && (rec == null
11444                        || !dumpPackage.equals(rec.key.packageName))) {
11445                    continue;
11446                }
11447                printed = true;
11448                if (rec != null) {
11449                    pw.print("  * "); pw.println(rec);
11450                    if (dumpAll) {
11451                        rec.dump(pw, "    ");
11452                    }
11453                } else {
11454                    pw.print("  * "); pw.println(ref);
11455                }
11456            }
11457        }
11458
11459        if (!printed) {
11460            pw.println("  (nothing)");
11461        }
11462    }
11463
11464    private static final int dumpProcessList(PrintWriter pw,
11465            ActivityManagerService service, List list,
11466            String prefix, String normalLabel, String persistentLabel,
11467            String dumpPackage) {
11468        int numPers = 0;
11469        final int N = list.size()-1;
11470        for (int i=N; i>=0; i--) {
11471            ProcessRecord r = (ProcessRecord)list.get(i);
11472            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11473                continue;
11474            }
11475            pw.println(String.format("%s%s #%2d: %s",
11476                    prefix, (r.persistent ? persistentLabel : normalLabel),
11477                    i, r.toString()));
11478            if (r.persistent) {
11479                numPers++;
11480            }
11481        }
11482        return numPers;
11483    }
11484
11485    private static final boolean dumpProcessOomList(PrintWriter pw,
11486            ActivityManagerService service, List<ProcessRecord> origList,
11487            String prefix, String normalLabel, String persistentLabel,
11488            boolean inclDetails, String dumpPackage) {
11489
11490        ArrayList<Pair<ProcessRecord, Integer>> list
11491                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11492        for (int i=0; i<origList.size(); i++) {
11493            ProcessRecord r = origList.get(i);
11494            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11495                continue;
11496            }
11497            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11498        }
11499
11500        if (list.size() <= 0) {
11501            return false;
11502        }
11503
11504        Comparator<Pair<ProcessRecord, Integer>> comparator
11505                = new Comparator<Pair<ProcessRecord, Integer>>() {
11506            @Override
11507            public int compare(Pair<ProcessRecord, Integer> object1,
11508                    Pair<ProcessRecord, Integer> object2) {
11509                if (object1.first.setAdj != object2.first.setAdj) {
11510                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11511                }
11512                if (object1.second.intValue() != object2.second.intValue()) {
11513                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11514                }
11515                return 0;
11516            }
11517        };
11518
11519        Collections.sort(list, comparator);
11520
11521        final long curRealtime = SystemClock.elapsedRealtime();
11522        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11523        final long curUptime = SystemClock.uptimeMillis();
11524        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11525
11526        for (int i=list.size()-1; i>=0; i--) {
11527            ProcessRecord r = list.get(i).first;
11528            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11529            char schedGroup;
11530            switch (r.setSchedGroup) {
11531                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11532                    schedGroup = 'B';
11533                    break;
11534                case Process.THREAD_GROUP_DEFAULT:
11535                    schedGroup = 'F';
11536                    break;
11537                default:
11538                    schedGroup = '?';
11539                    break;
11540            }
11541            char foreground;
11542            if (r.foregroundActivities) {
11543                foreground = 'A';
11544            } else if (r.foregroundServices) {
11545                foreground = 'S';
11546            } else {
11547                foreground = ' ';
11548            }
11549            String procState = ProcessList.makeProcStateString(r.curProcState);
11550            pw.print(prefix);
11551            pw.print(r.persistent ? persistentLabel : normalLabel);
11552            pw.print(" #");
11553            int num = (origList.size()-1)-list.get(i).second;
11554            if (num < 10) pw.print(' ');
11555            pw.print(num);
11556            pw.print(": ");
11557            pw.print(oomAdj);
11558            pw.print(' ');
11559            pw.print(schedGroup);
11560            pw.print('/');
11561            pw.print(foreground);
11562            pw.print('/');
11563            pw.print(procState);
11564            pw.print(" trm:");
11565            if (r.trimMemoryLevel < 10) pw.print(' ');
11566            pw.print(r.trimMemoryLevel);
11567            pw.print(' ');
11568            pw.print(r.toShortString());
11569            pw.print(" (");
11570            pw.print(r.adjType);
11571            pw.println(')');
11572            if (r.adjSource != null || r.adjTarget != null) {
11573                pw.print(prefix);
11574                pw.print("    ");
11575                if (r.adjTarget instanceof ComponentName) {
11576                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11577                } else if (r.adjTarget != null) {
11578                    pw.print(r.adjTarget.toString());
11579                } else {
11580                    pw.print("{null}");
11581                }
11582                pw.print("<=");
11583                if (r.adjSource instanceof ProcessRecord) {
11584                    pw.print("Proc{");
11585                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11586                    pw.println("}");
11587                } else if (r.adjSource != null) {
11588                    pw.println(r.adjSource.toString());
11589                } else {
11590                    pw.println("{null}");
11591                }
11592            }
11593            if (inclDetails) {
11594                pw.print(prefix);
11595                pw.print("    ");
11596                pw.print("oom: max="); pw.print(r.maxAdj);
11597                pw.print(" curRaw="); pw.print(r.curRawAdj);
11598                pw.print(" setRaw="); pw.print(r.setRawAdj);
11599                pw.print(" cur="); pw.print(r.curAdj);
11600                pw.print(" set="); pw.println(r.setAdj);
11601                pw.print(prefix);
11602                pw.print("    ");
11603                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11604                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11605                pw.print(" lastPss="); pw.print(r.lastPss);
11606                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11607                pw.print(prefix);
11608                pw.print("    ");
11609                pw.print("keeping="); pw.print(r.keeping);
11610                pw.print(" cached="); pw.print(r.cached);
11611                pw.print(" empty="); pw.print(r.empty);
11612                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11613
11614                if (!r.keeping) {
11615                    if (r.lastWakeTime != 0) {
11616                        long wtime;
11617                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11618                        synchronized (stats) {
11619                            wtime = stats.getProcessWakeTime(r.info.uid,
11620                                    r.pid, curRealtime);
11621                        }
11622                        long timeUsed = wtime - r.lastWakeTime;
11623                        pw.print(prefix);
11624                        pw.print("    ");
11625                        pw.print("keep awake over ");
11626                        TimeUtils.formatDuration(realtimeSince, pw);
11627                        pw.print(" used ");
11628                        TimeUtils.formatDuration(timeUsed, pw);
11629                        pw.print(" (");
11630                        pw.print((timeUsed*100)/realtimeSince);
11631                        pw.println("%)");
11632                    }
11633                    if (r.lastCpuTime != 0) {
11634                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11635                        pw.print(prefix);
11636                        pw.print("    ");
11637                        pw.print("run cpu over ");
11638                        TimeUtils.formatDuration(uptimeSince, pw);
11639                        pw.print(" used ");
11640                        TimeUtils.formatDuration(timeUsed, pw);
11641                        pw.print(" (");
11642                        pw.print((timeUsed*100)/uptimeSince);
11643                        pw.println("%)");
11644                    }
11645                }
11646            }
11647        }
11648        return true;
11649    }
11650
11651    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11652        ArrayList<ProcessRecord> procs;
11653        synchronized (this) {
11654            if (args != null && args.length > start
11655                    && args[start].charAt(0) != '-') {
11656                procs = new ArrayList<ProcessRecord>();
11657                int pid = -1;
11658                try {
11659                    pid = Integer.parseInt(args[start]);
11660                } catch (NumberFormatException e) {
11661                }
11662                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11663                    ProcessRecord proc = mLruProcesses.get(i);
11664                    if (proc.pid == pid) {
11665                        procs.add(proc);
11666                    } else if (proc.processName.equals(args[start])) {
11667                        procs.add(proc);
11668                    }
11669                }
11670                if (procs.size() <= 0) {
11671                    return null;
11672                }
11673            } else {
11674                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11675            }
11676        }
11677        return procs;
11678    }
11679
11680    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11681            PrintWriter pw, String[] args) {
11682        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11683        if (procs == null) {
11684            pw.println("No process found for: " + args[0]);
11685            return;
11686        }
11687
11688        long uptime = SystemClock.uptimeMillis();
11689        long realtime = SystemClock.elapsedRealtime();
11690        pw.println("Applications Graphics Acceleration Info:");
11691        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11692
11693        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11694            ProcessRecord r = procs.get(i);
11695            if (r.thread != null) {
11696                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11697                pw.flush();
11698                try {
11699                    TransferPipe tp = new TransferPipe();
11700                    try {
11701                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11702                        tp.go(fd);
11703                    } finally {
11704                        tp.kill();
11705                    }
11706                } catch (IOException e) {
11707                    pw.println("Failure while dumping the app: " + r);
11708                    pw.flush();
11709                } catch (RemoteException e) {
11710                    pw.println("Got a RemoteException while dumping the app " + r);
11711                    pw.flush();
11712                }
11713            }
11714        }
11715    }
11716
11717    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11718        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11719        if (procs == null) {
11720            pw.println("No process found for: " + args[0]);
11721            return;
11722        }
11723
11724        pw.println("Applications Database Info:");
11725
11726        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11727            ProcessRecord r = procs.get(i);
11728            if (r.thread != null) {
11729                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11730                pw.flush();
11731                try {
11732                    TransferPipe tp = new TransferPipe();
11733                    try {
11734                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11735                        tp.go(fd);
11736                    } finally {
11737                        tp.kill();
11738                    }
11739                } catch (IOException e) {
11740                    pw.println("Failure while dumping the app: " + r);
11741                    pw.flush();
11742                } catch (RemoteException e) {
11743                    pw.println("Got a RemoteException while dumping the app " + r);
11744                    pw.flush();
11745                }
11746            }
11747        }
11748    }
11749
11750    final static class MemItem {
11751        final boolean isProc;
11752        final String label;
11753        final String shortLabel;
11754        final long pss;
11755        final int id;
11756        final boolean hasActivities;
11757        ArrayList<MemItem> subitems;
11758
11759        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11760                boolean _hasActivities) {
11761            isProc = true;
11762            label = _label;
11763            shortLabel = _shortLabel;
11764            pss = _pss;
11765            id = _id;
11766            hasActivities = _hasActivities;
11767        }
11768
11769        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11770            isProc = false;
11771            label = _label;
11772            shortLabel = _shortLabel;
11773            pss = _pss;
11774            id = _id;
11775            hasActivities = false;
11776        }
11777    }
11778
11779    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11780            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11781        if (sort && !isCompact) {
11782            Collections.sort(items, new Comparator<MemItem>() {
11783                @Override
11784                public int compare(MemItem lhs, MemItem rhs) {
11785                    if (lhs.pss < rhs.pss) {
11786                        return 1;
11787                    } else if (lhs.pss > rhs.pss) {
11788                        return -1;
11789                    }
11790                    return 0;
11791                }
11792            });
11793        }
11794
11795        for (int i=0; i<items.size(); i++) {
11796            MemItem mi = items.get(i);
11797            if (!isCompact) {
11798                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11799            } else if (mi.isProc) {
11800                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11801                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11802                pw.println(mi.hasActivities ? ",a" : ",e");
11803            } else {
11804                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11805                pw.println(mi.pss);
11806            }
11807            if (mi.subitems != null) {
11808                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11809                        true, isCompact);
11810            }
11811        }
11812    }
11813
11814    // These are in KB.
11815    static final long[] DUMP_MEM_BUCKETS = new long[] {
11816        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11817        120*1024, 160*1024, 200*1024,
11818        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11819        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11820    };
11821
11822    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11823            boolean stackLike) {
11824        int start = label.lastIndexOf('.');
11825        if (start >= 0) start++;
11826        else start = 0;
11827        int end = label.length();
11828        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11829            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11830                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11831                out.append(bucket);
11832                out.append(stackLike ? "MB." : "MB ");
11833                out.append(label, start, end);
11834                return;
11835            }
11836        }
11837        out.append(memKB/1024);
11838        out.append(stackLike ? "MB." : "MB ");
11839        out.append(label, start, end);
11840    }
11841
11842    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11843            ProcessList.NATIVE_ADJ,
11844            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11845            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11846            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11847            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11848            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11849    };
11850    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11851            "Native",
11852            "System", "Persistent", "Foreground",
11853            "Visible", "Perceptible",
11854            "Heavy Weight", "Backup",
11855            "A Services", "Home",
11856            "Previous", "B Services", "Cached"
11857    };
11858    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11859            "native",
11860            "sys", "pers", "fore",
11861            "vis", "percept",
11862            "heavy", "backup",
11863            "servicea", "home",
11864            "prev", "serviceb", "cached"
11865    };
11866
11867    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11868            long realtime, boolean isCheckinRequest, boolean isCompact) {
11869        if (isCheckinRequest || isCompact) {
11870            // short checkin version
11871            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11872        } else {
11873            pw.println("Applications Memory Usage (kB):");
11874            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11875        }
11876    }
11877
11878    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11879            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11880        boolean dumpDetails = false;
11881        boolean dumpFullDetails = false;
11882        boolean dumpDalvik = false;
11883        boolean oomOnly = false;
11884        boolean isCompact = false;
11885        boolean localOnly = false;
11886
11887        int opti = 0;
11888        while (opti < args.length) {
11889            String opt = args[opti];
11890            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11891                break;
11892            }
11893            opti++;
11894            if ("-a".equals(opt)) {
11895                dumpDetails = true;
11896                dumpFullDetails = true;
11897                dumpDalvik = true;
11898            } else if ("-d".equals(opt)) {
11899                dumpDalvik = true;
11900            } else if ("-c".equals(opt)) {
11901                isCompact = true;
11902            } else if ("--oom".equals(opt)) {
11903                oomOnly = true;
11904            } else if ("--local".equals(opt)) {
11905                localOnly = true;
11906            } else if ("-h".equals(opt)) {
11907                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11908                pw.println("  -a: include all available information for each process.");
11909                pw.println("  -d: include dalvik details when dumping process details.");
11910                pw.println("  -c: dump in a compact machine-parseable representation.");
11911                pw.println("  --oom: only show processes organized by oom adj.");
11912                pw.println("  --local: only collect details locally, don't call process.");
11913                pw.println("If [process] is specified it can be the name or ");
11914                pw.println("pid of a specific process to dump.");
11915                return;
11916            } else {
11917                pw.println("Unknown argument: " + opt + "; use -h for help");
11918            }
11919        }
11920
11921        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11922        long uptime = SystemClock.uptimeMillis();
11923        long realtime = SystemClock.elapsedRealtime();
11924        final long[] tmpLong = new long[1];
11925
11926        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11927        if (procs == null) {
11928            // No Java processes.  Maybe they want to print a native process.
11929            if (args != null && args.length > opti
11930                    && args[opti].charAt(0) != '-') {
11931                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11932                        = new ArrayList<ProcessCpuTracker.Stats>();
11933                updateCpuStatsNow();
11934                int findPid = -1;
11935                try {
11936                    findPid = Integer.parseInt(args[opti]);
11937                } catch (NumberFormatException e) {
11938                }
11939                synchronized (mProcessCpuThread) {
11940                    final int N = mProcessCpuTracker.countStats();
11941                    for (int i=0; i<N; i++) {
11942                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11943                        if (st.pid == findPid || (st.baseName != null
11944                                && st.baseName.equals(args[opti]))) {
11945                            nativeProcs.add(st);
11946                        }
11947                    }
11948                }
11949                if (nativeProcs.size() > 0) {
11950                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11951                            isCompact);
11952                    Debug.MemoryInfo mi = null;
11953                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11954                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11955                        final int pid = r.pid;
11956                        if (!isCheckinRequest && dumpDetails) {
11957                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11958                        }
11959                        if (mi == null) {
11960                            mi = new Debug.MemoryInfo();
11961                        }
11962                        if (dumpDetails || (!brief && !oomOnly)) {
11963                            Debug.getMemoryInfo(pid, mi);
11964                        } else {
11965                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11966                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11967                        }
11968                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11969                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11970                        if (isCheckinRequest) {
11971                            pw.println();
11972                        }
11973                    }
11974                    return;
11975                }
11976            }
11977            pw.println("No process found for: " + args[opti]);
11978            return;
11979        }
11980
11981        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11982            dumpDetails = true;
11983        }
11984
11985        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11986
11987        String[] innerArgs = new String[args.length-opti];
11988        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11989
11990        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11991        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11992        long nativePss=0, dalvikPss=0, otherPss=0;
11993        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11994
11995        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11996        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11997                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11998
11999        long totalPss = 0;
12000        long cachedPss = 0;
12001
12002        Debug.MemoryInfo mi = null;
12003        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12004            final ProcessRecord r = procs.get(i);
12005            final IApplicationThread thread;
12006            final int pid;
12007            final int oomAdj;
12008            final boolean hasActivities;
12009            synchronized (this) {
12010                thread = r.thread;
12011                pid = r.pid;
12012                oomAdj = r.getSetAdjWithServices();
12013                hasActivities = r.activities.size() > 0;
12014            }
12015            if (thread != null) {
12016                if (!isCheckinRequest && dumpDetails) {
12017                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12018                }
12019                if (mi == null) {
12020                    mi = new Debug.MemoryInfo();
12021                }
12022                if (dumpDetails || (!brief && !oomOnly)) {
12023                    Debug.getMemoryInfo(pid, mi);
12024                } else {
12025                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12026                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12027                }
12028                if (dumpDetails) {
12029                    if (localOnly) {
12030                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12031                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12032                        if (isCheckinRequest) {
12033                            pw.println();
12034                        }
12035                    } else {
12036                        try {
12037                            pw.flush();
12038                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12039                                    dumpDalvik, innerArgs);
12040                        } catch (RemoteException e) {
12041                            if (!isCheckinRequest) {
12042                                pw.println("Got RemoteException!");
12043                                pw.flush();
12044                            }
12045                        }
12046                    }
12047                }
12048
12049                final long myTotalPss = mi.getTotalPss();
12050                final long myTotalUss = mi.getTotalUss();
12051
12052                synchronized (this) {
12053                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12054                        // Record this for posterity if the process has been stable.
12055                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12056                    }
12057                }
12058
12059                if (!isCheckinRequest && mi != null) {
12060                    totalPss += myTotalPss;
12061                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12062                            (hasActivities ? " / activities)" : ")"),
12063                            r.processName, myTotalPss, pid, hasActivities);
12064                    procMems.add(pssItem);
12065                    procMemsMap.put(pid, pssItem);
12066
12067                    nativePss += mi.nativePss;
12068                    dalvikPss += mi.dalvikPss;
12069                    otherPss += mi.otherPss;
12070                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12071                        long mem = mi.getOtherPss(j);
12072                        miscPss[j] += mem;
12073                        otherPss -= mem;
12074                    }
12075
12076                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12077                        cachedPss += myTotalPss;
12078                    }
12079
12080                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12081                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12082                                || oomIndex == (oomPss.length-1)) {
12083                            oomPss[oomIndex] += myTotalPss;
12084                            if (oomProcs[oomIndex] == null) {
12085                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12086                            }
12087                            oomProcs[oomIndex].add(pssItem);
12088                            break;
12089                        }
12090                    }
12091                }
12092            }
12093        }
12094
12095        if (!isCheckinRequest && procs.size() > 1) {
12096            // If we are showing aggregations, also look for native processes to
12097            // include so that our aggregations are more accurate.
12098            updateCpuStatsNow();
12099            synchronized (mProcessCpuThread) {
12100                final int N = mProcessCpuTracker.countStats();
12101                for (int i=0; i<N; i++) {
12102                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12103                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12104                        if (mi == null) {
12105                            mi = new Debug.MemoryInfo();
12106                        }
12107                        if (!brief && !oomOnly) {
12108                            Debug.getMemoryInfo(st.pid, mi);
12109                        } else {
12110                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12111                            mi.nativePrivateDirty = (int)tmpLong[0];
12112                        }
12113
12114                        final long myTotalPss = mi.getTotalPss();
12115                        totalPss += myTotalPss;
12116
12117                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12118                                st.name, myTotalPss, st.pid, false);
12119                        procMems.add(pssItem);
12120
12121                        nativePss += mi.nativePss;
12122                        dalvikPss += mi.dalvikPss;
12123                        otherPss += mi.otherPss;
12124                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12125                            long mem = mi.getOtherPss(j);
12126                            miscPss[j] += mem;
12127                            otherPss -= mem;
12128                        }
12129                        oomPss[0] += myTotalPss;
12130                        if (oomProcs[0] == null) {
12131                            oomProcs[0] = new ArrayList<MemItem>();
12132                        }
12133                        oomProcs[0].add(pssItem);
12134                    }
12135                }
12136            }
12137
12138            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12139
12140            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12141            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12142            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12143            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12144                String label = Debug.MemoryInfo.getOtherLabel(j);
12145                catMems.add(new MemItem(label, label, miscPss[j], j));
12146            }
12147
12148            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12149            for (int j=0; j<oomPss.length; j++) {
12150                if (oomPss[j] != 0) {
12151                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12152                            : DUMP_MEM_OOM_LABEL[j];
12153                    MemItem item = new MemItem(label, label, oomPss[j],
12154                            DUMP_MEM_OOM_ADJ[j]);
12155                    item.subitems = oomProcs[j];
12156                    oomMems.add(item);
12157                }
12158            }
12159
12160            if (!brief && !oomOnly && !isCompact) {
12161                pw.println();
12162                pw.println("Total PSS by process:");
12163                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12164                pw.println();
12165            }
12166            if (!isCompact) {
12167                pw.println("Total PSS by OOM adjustment:");
12168            }
12169            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12170            if (!brief && !oomOnly) {
12171                PrintWriter out = categoryPw != null ? categoryPw : pw;
12172                if (!isCompact) {
12173                    out.println();
12174                    out.println("Total PSS by category:");
12175                }
12176                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12177            }
12178            if (!isCompact) {
12179                pw.println();
12180            }
12181            MemInfoReader memInfo = new MemInfoReader();
12182            memInfo.readMemInfo();
12183            if (!brief) {
12184                if (!isCompact) {
12185                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12186                    pw.print(" kB (status ");
12187                    switch (mLastMemoryLevel) {
12188                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12189                            pw.println("normal)");
12190                            break;
12191                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12192                            pw.println("moderate)");
12193                            break;
12194                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12195                            pw.println("low)");
12196                            break;
12197                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12198                            pw.println("critical)");
12199                            break;
12200                        default:
12201                            pw.print(mLastMemoryLevel);
12202                            pw.println(")");
12203                            break;
12204                    }
12205                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12206                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12207                            pw.print(cachedPss); pw.print(" cached pss + ");
12208                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12209                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12210                } else {
12211                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12212                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12213                            + memInfo.getFreeSizeKb()); pw.print(",");
12214                    pw.println(totalPss - cachedPss);
12215                }
12216            }
12217            if (!isCompact) {
12218                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12219                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12220                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12221                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12222                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12223                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12224                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12225                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12226                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12227                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12228                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12229            }
12230            if (!brief) {
12231                if (memInfo.getZramTotalSizeKb() != 0) {
12232                    if (!isCompact) {
12233                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12234                                pw.print(" kB physical used for ");
12235                                pw.print(memInfo.getSwapTotalSizeKb()
12236                                        - memInfo.getSwapFreeSizeKb());
12237                                pw.print(" kB in swap (");
12238                                pw.print(memInfo.getSwapTotalSizeKb());
12239                                pw.println(" kB total swap)");
12240                    } else {
12241                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12242                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12243                                pw.println(memInfo.getSwapFreeSizeKb());
12244                    }
12245                }
12246                final int[] SINGLE_LONG_FORMAT = new int[] {
12247                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12248                };
12249                long[] longOut = new long[1];
12250                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12251                        SINGLE_LONG_FORMAT, null, longOut, null);
12252                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12253                longOut[0] = 0;
12254                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12255                        SINGLE_LONG_FORMAT, null, longOut, null);
12256                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12257                longOut[0] = 0;
12258                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12259                        SINGLE_LONG_FORMAT, null, longOut, null);
12260                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12261                longOut[0] = 0;
12262                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12263                        SINGLE_LONG_FORMAT, null, longOut, null);
12264                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12265                if (!isCompact) {
12266                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12267                        pw.print("      KSM: "); pw.print(sharing);
12268                                pw.print(" kB saved from shared ");
12269                                pw.print(shared); pw.println(" kB");
12270                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12271                                pw.print(voltile); pw.println(" kB volatile");
12272                    }
12273                    pw.print("   Tuning: ");
12274                    pw.print(ActivityManager.staticGetMemoryClass());
12275                    pw.print(" (large ");
12276                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12277                    pw.print("), oom ");
12278                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12279                    pw.print(" kB");
12280                    pw.print(", restore limit ");
12281                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12282                    pw.print(" kB");
12283                    if (ActivityManager.isLowRamDeviceStatic()) {
12284                        pw.print(" (low-ram)");
12285                    }
12286                    if (ActivityManager.isHighEndGfx()) {
12287                        pw.print(" (high-end-gfx)");
12288                    }
12289                    pw.println();
12290                } else {
12291                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12292                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12293                    pw.println(voltile);
12294                    pw.print("tuning,");
12295                    pw.print(ActivityManager.staticGetMemoryClass());
12296                    pw.print(',');
12297                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12298                    pw.print(',');
12299                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12300                    if (ActivityManager.isLowRamDeviceStatic()) {
12301                        pw.print(",low-ram");
12302                    }
12303                    if (ActivityManager.isHighEndGfx()) {
12304                        pw.print(",high-end-gfx");
12305                    }
12306                    pw.println();
12307                }
12308            }
12309        }
12310    }
12311
12312    /**
12313     * Searches array of arguments for the specified string
12314     * @param args array of argument strings
12315     * @param value value to search for
12316     * @return true if the value is contained in the array
12317     */
12318    private static boolean scanArgs(String[] args, String value) {
12319        if (args != null) {
12320            for (String arg : args) {
12321                if (value.equals(arg)) {
12322                    return true;
12323                }
12324            }
12325        }
12326        return false;
12327    }
12328
12329    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12330            ContentProviderRecord cpr, boolean always) {
12331        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12332
12333        if (!inLaunching || always) {
12334            synchronized (cpr) {
12335                cpr.launchingApp = null;
12336                cpr.notifyAll();
12337            }
12338            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12339            String names[] = cpr.info.authority.split(";");
12340            for (int j = 0; j < names.length; j++) {
12341                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12342            }
12343        }
12344
12345        for (int i=0; i<cpr.connections.size(); i++) {
12346            ContentProviderConnection conn = cpr.connections.get(i);
12347            if (conn.waiting) {
12348                // If this connection is waiting for the provider, then we don't
12349                // need to mess with its process unless we are always removing
12350                // or for some reason the provider is not currently launching.
12351                if (inLaunching && !always) {
12352                    continue;
12353                }
12354            }
12355            ProcessRecord capp = conn.client;
12356            conn.dead = true;
12357            if (conn.stableCount > 0) {
12358                if (!capp.persistent && capp.thread != null
12359                        && capp.pid != 0
12360                        && capp.pid != MY_PID) {
12361                    killUnneededProcessLocked(capp, "depends on provider "
12362                            + cpr.name.flattenToShortString()
12363                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12364                }
12365            } else if (capp.thread != null && conn.provider.provider != null) {
12366                try {
12367                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12368                } catch (RemoteException e) {
12369                }
12370                // In the protocol here, we don't expect the client to correctly
12371                // clean up this connection, we'll just remove it.
12372                cpr.connections.remove(i);
12373                conn.client.conProviders.remove(conn);
12374            }
12375        }
12376
12377        if (inLaunching && always) {
12378            mLaunchingProviders.remove(cpr);
12379        }
12380        return inLaunching;
12381    }
12382
12383    /**
12384     * Main code for cleaning up a process when it has gone away.  This is
12385     * called both as a result of the process dying, or directly when stopping
12386     * a process when running in single process mode.
12387     */
12388    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12389            boolean restarting, boolean allowRestart, int index) {
12390        if (index >= 0) {
12391            removeLruProcessLocked(app);
12392            ProcessList.remove(app.pid);
12393        }
12394
12395        mProcessesToGc.remove(app);
12396        mPendingPssProcesses.remove(app);
12397
12398        // Dismiss any open dialogs.
12399        if (app.crashDialog != null && !app.forceCrashReport) {
12400            app.crashDialog.dismiss();
12401            app.crashDialog = null;
12402        }
12403        if (app.anrDialog != null) {
12404            app.anrDialog.dismiss();
12405            app.anrDialog = null;
12406        }
12407        if (app.waitDialog != null) {
12408            app.waitDialog.dismiss();
12409            app.waitDialog = null;
12410        }
12411
12412        app.crashing = false;
12413        app.notResponding = false;
12414
12415        app.resetPackageList(mProcessStats);
12416        app.unlinkDeathRecipient();
12417        app.makeInactive(mProcessStats);
12418        app.forcingToForeground = null;
12419        updateProcessForegroundLocked(app, false, false);
12420        app.foregroundActivities = false;
12421        app.hasShownUi = false;
12422        app.hasAboveClient = false;
12423
12424        mServices.killServicesLocked(app, allowRestart);
12425
12426        boolean restart = false;
12427
12428        // Remove published content providers.
12429        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12430            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12431            final boolean always = app.bad || !allowRestart;
12432            if (removeDyingProviderLocked(app, cpr, always) || always) {
12433                // We left the provider in the launching list, need to
12434                // restart it.
12435                restart = true;
12436            }
12437
12438            cpr.provider = null;
12439            cpr.proc = null;
12440        }
12441        app.pubProviders.clear();
12442
12443        // Take care of any launching providers waiting for this process.
12444        if (checkAppInLaunchingProvidersLocked(app, false)) {
12445            restart = true;
12446        }
12447
12448        // Unregister from connected content providers.
12449        if (!app.conProviders.isEmpty()) {
12450            for (int i=0; i<app.conProviders.size(); i++) {
12451                ContentProviderConnection conn = app.conProviders.get(i);
12452                conn.provider.connections.remove(conn);
12453            }
12454            app.conProviders.clear();
12455        }
12456
12457        // At this point there may be remaining entries in mLaunchingProviders
12458        // where we were the only one waiting, so they are no longer of use.
12459        // Look for these and clean up if found.
12460        // XXX Commented out for now.  Trying to figure out a way to reproduce
12461        // the actual situation to identify what is actually going on.
12462        if (false) {
12463            for (int i=0; i<mLaunchingProviders.size(); i++) {
12464                ContentProviderRecord cpr = (ContentProviderRecord)
12465                        mLaunchingProviders.get(i);
12466                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12467                    synchronized (cpr) {
12468                        cpr.launchingApp = null;
12469                        cpr.notifyAll();
12470                    }
12471                }
12472            }
12473        }
12474
12475        skipCurrentReceiverLocked(app);
12476
12477        // Unregister any receivers.
12478        for (int i=app.receivers.size()-1; i>=0; i--) {
12479            removeReceiverLocked(app.receivers.valueAt(i));
12480        }
12481        app.receivers.clear();
12482
12483        // If the app is undergoing backup, tell the backup manager about it
12484        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12485            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12486                    + mBackupTarget.appInfo + " died during backup");
12487            try {
12488                IBackupManager bm = IBackupManager.Stub.asInterface(
12489                        ServiceManager.getService(Context.BACKUP_SERVICE));
12490                bm.agentDisconnected(app.info.packageName);
12491            } catch (RemoteException e) {
12492                // can't happen; backup manager is local
12493            }
12494        }
12495
12496        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12497            ProcessChangeItem item = mPendingProcessChanges.get(i);
12498            if (item.pid == app.pid) {
12499                mPendingProcessChanges.remove(i);
12500                mAvailProcessChanges.add(item);
12501            }
12502        }
12503        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12504
12505        // If the caller is restarting this app, then leave it in its
12506        // current lists and let the caller take care of it.
12507        if (restarting) {
12508            return;
12509        }
12510
12511        if (!app.persistent || app.isolated) {
12512            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12513                    "Removing non-persistent process during cleanup: " + app);
12514            mProcessNames.remove(app.processName, app.uid);
12515            mIsolatedProcesses.remove(app.uid);
12516            if (mHeavyWeightProcess == app) {
12517                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12518                        mHeavyWeightProcess.userId, 0));
12519                mHeavyWeightProcess = null;
12520            }
12521        } else if (!app.removed) {
12522            // This app is persistent, so we need to keep its record around.
12523            // If it is not already on the pending app list, add it there
12524            // and start a new process for it.
12525            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12526                mPersistentStartingProcesses.add(app);
12527                restart = true;
12528            }
12529        }
12530        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12531                "Clean-up removing on hold: " + app);
12532        mProcessesOnHold.remove(app);
12533
12534        if (app == mHomeProcess) {
12535            mHomeProcess = null;
12536        }
12537        if (app == mPreviousProcess) {
12538            mPreviousProcess = null;
12539        }
12540
12541        if (restart && !app.isolated) {
12542            // We have components that still need to be running in the
12543            // process, so re-launch it.
12544            mProcessNames.put(app.processName, app.uid, app);
12545            startProcessLocked(app, "restart", app.processName);
12546        } else if (app.pid > 0 && app.pid != MY_PID) {
12547            // Goodbye!
12548            boolean removed;
12549            synchronized (mPidsSelfLocked) {
12550                mPidsSelfLocked.remove(app.pid);
12551                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12552            }
12553            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12554                    app.processName, app.info.uid);
12555            if (app.isolated) {
12556                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12557            }
12558            app.setPid(0);
12559        }
12560    }
12561
12562    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12563        // Look through the content providers we are waiting to have launched,
12564        // and if any run in this process then either schedule a restart of
12565        // the process or kill the client waiting for it if this process has
12566        // gone bad.
12567        int NL = mLaunchingProviders.size();
12568        boolean restart = false;
12569        for (int i=0; i<NL; i++) {
12570            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12571            if (cpr.launchingApp == app) {
12572                if (!alwaysBad && !app.bad) {
12573                    restart = true;
12574                } else {
12575                    removeDyingProviderLocked(app, cpr, true);
12576                    // cpr should have been removed from mLaunchingProviders
12577                    NL = mLaunchingProviders.size();
12578                    i--;
12579                }
12580            }
12581        }
12582        return restart;
12583    }
12584
12585    // =========================================================
12586    // SERVICES
12587    // =========================================================
12588
12589    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12590            int flags) {
12591        enforceNotIsolatedCaller("getServices");
12592        synchronized (this) {
12593            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12594        }
12595    }
12596
12597    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12598        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12599        synchronized (this) {
12600            return mServices.getRunningServiceControlPanelLocked(name);
12601        }
12602    }
12603
12604    public ComponentName startService(IApplicationThread caller, Intent service,
12605            String resolvedType, int userId) {
12606        enforceNotIsolatedCaller("startService");
12607        // Refuse possible leaked file descriptors
12608        if (service != null && service.hasFileDescriptors() == true) {
12609            throw new IllegalArgumentException("File descriptors passed in Intent");
12610        }
12611
12612        if (DEBUG_SERVICE)
12613            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12614        synchronized(this) {
12615            final int callingPid = Binder.getCallingPid();
12616            final int callingUid = Binder.getCallingUid();
12617            final long origId = Binder.clearCallingIdentity();
12618            ComponentName res = mServices.startServiceLocked(caller, service,
12619                    resolvedType, callingPid, callingUid, userId);
12620            Binder.restoreCallingIdentity(origId);
12621            return res;
12622        }
12623    }
12624
12625    ComponentName startServiceInPackage(int uid,
12626            Intent service, String resolvedType, int userId) {
12627        synchronized(this) {
12628            if (DEBUG_SERVICE)
12629                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12630            final long origId = Binder.clearCallingIdentity();
12631            ComponentName res = mServices.startServiceLocked(null, service,
12632                    resolvedType, -1, uid, userId);
12633            Binder.restoreCallingIdentity(origId);
12634            return res;
12635        }
12636    }
12637
12638    public int stopService(IApplicationThread caller, Intent service,
12639            String resolvedType, int userId) {
12640        enforceNotIsolatedCaller("stopService");
12641        // Refuse possible leaked file descriptors
12642        if (service != null && service.hasFileDescriptors() == true) {
12643            throw new IllegalArgumentException("File descriptors passed in Intent");
12644        }
12645
12646        synchronized(this) {
12647            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12648        }
12649    }
12650
12651    public IBinder peekService(Intent service, String resolvedType) {
12652        enforceNotIsolatedCaller("peekService");
12653        // Refuse possible leaked file descriptors
12654        if (service != null && service.hasFileDescriptors() == true) {
12655            throw new IllegalArgumentException("File descriptors passed in Intent");
12656        }
12657        synchronized(this) {
12658            return mServices.peekServiceLocked(service, resolvedType);
12659        }
12660    }
12661
12662    public boolean stopServiceToken(ComponentName className, IBinder token,
12663            int startId) {
12664        synchronized(this) {
12665            return mServices.stopServiceTokenLocked(className, token, startId);
12666        }
12667    }
12668
12669    public void setServiceForeground(ComponentName className, IBinder token,
12670            int id, Notification notification, boolean removeNotification) {
12671        synchronized(this) {
12672            mServices.setServiceForegroundLocked(className, token, id, notification,
12673                    removeNotification);
12674        }
12675    }
12676
12677    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12678            boolean requireFull, String name, String callerPackage) {
12679        final int callingUserId = UserHandle.getUserId(callingUid);
12680        if (callingUserId != userId) {
12681            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12682                if ((requireFull || checkComponentPermission(
12683                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12684                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12685                        && checkComponentPermission(
12686                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12687                                callingPid, callingUid, -1, true)
12688                                != PackageManager.PERMISSION_GRANTED) {
12689                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12690                        // In this case, they would like to just execute as their
12691                        // owner user instead of failing.
12692                        userId = callingUserId;
12693                    } else {
12694                        StringBuilder builder = new StringBuilder(128);
12695                        builder.append("Permission Denial: ");
12696                        builder.append(name);
12697                        if (callerPackage != null) {
12698                            builder.append(" from ");
12699                            builder.append(callerPackage);
12700                        }
12701                        builder.append(" asks to run as user ");
12702                        builder.append(userId);
12703                        builder.append(" but is calling from user ");
12704                        builder.append(UserHandle.getUserId(callingUid));
12705                        builder.append("; this requires ");
12706                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12707                        if (!requireFull) {
12708                            builder.append(" or ");
12709                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12710                        }
12711                        String msg = builder.toString();
12712                        Slog.w(TAG, msg);
12713                        throw new SecurityException(msg);
12714                    }
12715                }
12716            }
12717            if (userId == UserHandle.USER_CURRENT
12718                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12719                // Note that we may be accessing this outside of a lock...
12720                // shouldn't be a big deal, if this is being called outside
12721                // of a locked context there is intrinsically a race with
12722                // the value the caller will receive and someone else changing it.
12723                userId = mCurrentUserId;
12724            }
12725            if (!allowAll && userId < 0) {
12726                throw new IllegalArgumentException(
12727                        "Call does not support special user #" + userId);
12728            }
12729        }
12730        return userId;
12731    }
12732
12733    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12734            String className, int flags) {
12735        boolean result = false;
12736        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12737            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12738                if (ActivityManager.checkUidPermission(
12739                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12740                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12741                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12742                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12743                            + " requests FLAG_SINGLE_USER, but app does not hold "
12744                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12745                    Slog.w(TAG, msg);
12746                    throw new SecurityException(msg);
12747                }
12748                result = true;
12749            }
12750        } else if (componentProcessName == aInfo.packageName) {
12751            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12752        } else if ("system".equals(componentProcessName)) {
12753            result = true;
12754        }
12755        if (DEBUG_MU) {
12756            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12757                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12758        }
12759        return result;
12760    }
12761
12762    public int bindService(IApplicationThread caller, IBinder token,
12763            Intent service, String resolvedType,
12764            IServiceConnection connection, int flags, int userId) {
12765        enforceNotIsolatedCaller("bindService");
12766        // Refuse possible leaked file descriptors
12767        if (service != null && service.hasFileDescriptors() == true) {
12768            throw new IllegalArgumentException("File descriptors passed in Intent");
12769        }
12770
12771        synchronized(this) {
12772            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12773                    connection, flags, userId);
12774        }
12775    }
12776
12777    public boolean unbindService(IServiceConnection connection) {
12778        synchronized (this) {
12779            return mServices.unbindServiceLocked(connection);
12780        }
12781    }
12782
12783    public void publishService(IBinder token, Intent intent, IBinder service) {
12784        // Refuse possible leaked file descriptors
12785        if (intent != null && intent.hasFileDescriptors() == true) {
12786            throw new IllegalArgumentException("File descriptors passed in Intent");
12787        }
12788
12789        synchronized(this) {
12790            if (!(token instanceof ServiceRecord)) {
12791                throw new IllegalArgumentException("Invalid service token");
12792            }
12793            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12794        }
12795    }
12796
12797    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12798        // Refuse possible leaked file descriptors
12799        if (intent != null && intent.hasFileDescriptors() == true) {
12800            throw new IllegalArgumentException("File descriptors passed in Intent");
12801        }
12802
12803        synchronized(this) {
12804            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12805        }
12806    }
12807
12808    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12809        synchronized(this) {
12810            if (!(token instanceof ServiceRecord)) {
12811                throw new IllegalArgumentException("Invalid service token");
12812            }
12813            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12814        }
12815    }
12816
12817    // =========================================================
12818    // BACKUP AND RESTORE
12819    // =========================================================
12820
12821    // Cause the target app to be launched if necessary and its backup agent
12822    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12823    // activity manager to announce its creation.
12824    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12825        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12826        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12827
12828        synchronized(this) {
12829            // !!! TODO: currently no check here that we're already bound
12830            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12831            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12832            synchronized (stats) {
12833                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12834            }
12835
12836            // Backup agent is now in use, its package can't be stopped.
12837            try {
12838                AppGlobals.getPackageManager().setPackageStoppedState(
12839                        app.packageName, false, UserHandle.getUserId(app.uid));
12840            } catch (RemoteException e) {
12841            } catch (IllegalArgumentException e) {
12842                Slog.w(TAG, "Failed trying to unstop package "
12843                        + app.packageName + ": " + e);
12844            }
12845
12846            BackupRecord r = new BackupRecord(ss, app, backupMode);
12847            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12848                    ? new ComponentName(app.packageName, app.backupAgentName)
12849                    : new ComponentName("android", "FullBackupAgent");
12850            // startProcessLocked() returns existing proc's record if it's already running
12851            ProcessRecord proc = startProcessLocked(app.processName, app,
12852                    false, 0, "backup", hostingName, false, false, false);
12853            if (proc == null) {
12854                Slog.e(TAG, "Unable to start backup agent process " + r);
12855                return false;
12856            }
12857
12858            r.app = proc;
12859            mBackupTarget = r;
12860            mBackupAppName = app.packageName;
12861
12862            // Try not to kill the process during backup
12863            updateOomAdjLocked(proc);
12864
12865            // If the process is already attached, schedule the creation of the backup agent now.
12866            // If it is not yet live, this will be done when it attaches to the framework.
12867            if (proc.thread != null) {
12868                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12869                try {
12870                    proc.thread.scheduleCreateBackupAgent(app,
12871                            compatibilityInfoForPackageLocked(app), backupMode);
12872                } catch (RemoteException e) {
12873                    // Will time out on the backup manager side
12874                }
12875            } else {
12876                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12877            }
12878            // Invariants: at this point, the target app process exists and the application
12879            // is either already running or in the process of coming up.  mBackupTarget and
12880            // mBackupAppName describe the app, so that when it binds back to the AM we
12881            // know that it's scheduled for a backup-agent operation.
12882        }
12883
12884        return true;
12885    }
12886
12887    @Override
12888    public void clearPendingBackup() {
12889        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12890        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12891
12892        synchronized (this) {
12893            mBackupTarget = null;
12894            mBackupAppName = null;
12895        }
12896    }
12897
12898    // A backup agent has just come up
12899    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12900        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12901                + " = " + agent);
12902
12903        synchronized(this) {
12904            if (!agentPackageName.equals(mBackupAppName)) {
12905                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12906                return;
12907            }
12908        }
12909
12910        long oldIdent = Binder.clearCallingIdentity();
12911        try {
12912            IBackupManager bm = IBackupManager.Stub.asInterface(
12913                    ServiceManager.getService(Context.BACKUP_SERVICE));
12914            bm.agentConnected(agentPackageName, agent);
12915        } catch (RemoteException e) {
12916            // can't happen; the backup manager service is local
12917        } catch (Exception e) {
12918            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12919            e.printStackTrace();
12920        } finally {
12921            Binder.restoreCallingIdentity(oldIdent);
12922        }
12923    }
12924
12925    // done with this agent
12926    public void unbindBackupAgent(ApplicationInfo appInfo) {
12927        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12928        if (appInfo == null) {
12929            Slog.w(TAG, "unbind backup agent for null app");
12930            return;
12931        }
12932
12933        synchronized(this) {
12934            try {
12935                if (mBackupAppName == null) {
12936                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12937                    return;
12938                }
12939
12940                if (!mBackupAppName.equals(appInfo.packageName)) {
12941                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12942                    return;
12943                }
12944
12945                // Not backing this app up any more; reset its OOM adjustment
12946                final ProcessRecord proc = mBackupTarget.app;
12947                updateOomAdjLocked(proc);
12948
12949                // If the app crashed during backup, 'thread' will be null here
12950                if (proc.thread != null) {
12951                    try {
12952                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12953                                compatibilityInfoForPackageLocked(appInfo));
12954                    } catch (Exception e) {
12955                        Slog.e(TAG, "Exception when unbinding backup agent:");
12956                        e.printStackTrace();
12957                    }
12958                }
12959            } finally {
12960                mBackupTarget = null;
12961                mBackupAppName = null;
12962            }
12963        }
12964    }
12965    // =========================================================
12966    // BROADCASTS
12967    // =========================================================
12968
12969    private final List getStickiesLocked(String action, IntentFilter filter,
12970            List cur, int userId) {
12971        final ContentResolver resolver = mContext.getContentResolver();
12972        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12973        if (stickies == null) {
12974            return cur;
12975        }
12976        final ArrayList<Intent> list = stickies.get(action);
12977        if (list == null) {
12978            return cur;
12979        }
12980        int N = list.size();
12981        for (int i=0; i<N; i++) {
12982            Intent intent = list.get(i);
12983            if (filter.match(resolver, intent, true, TAG) >= 0) {
12984                if (cur == null) {
12985                    cur = new ArrayList<Intent>();
12986                }
12987                cur.add(intent);
12988            }
12989        }
12990        return cur;
12991    }
12992
12993    boolean isPendingBroadcastProcessLocked(int pid) {
12994        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12995                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12996    }
12997
12998    void skipPendingBroadcastLocked(int pid) {
12999            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13000            for (BroadcastQueue queue : mBroadcastQueues) {
13001                queue.skipPendingBroadcastLocked(pid);
13002            }
13003    }
13004
13005    // The app just attached; send any pending broadcasts that it should receive
13006    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13007        boolean didSomething = false;
13008        for (BroadcastQueue queue : mBroadcastQueues) {
13009            didSomething |= queue.sendPendingBroadcastsLocked(app);
13010        }
13011        return didSomething;
13012    }
13013
13014    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13015            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13016        enforceNotIsolatedCaller("registerReceiver");
13017        int callingUid;
13018        int callingPid;
13019        synchronized(this) {
13020            ProcessRecord callerApp = null;
13021            if (caller != null) {
13022                callerApp = getRecordForAppLocked(caller);
13023                if (callerApp == null) {
13024                    throw new SecurityException(
13025                            "Unable to find app for caller " + caller
13026                            + " (pid=" + Binder.getCallingPid()
13027                            + ") when registering receiver " + receiver);
13028                }
13029                if (callerApp.info.uid != Process.SYSTEM_UID &&
13030                        !callerApp.pkgList.containsKey(callerPackage) &&
13031                        !"android".equals(callerPackage)) {
13032                    throw new SecurityException("Given caller package " + callerPackage
13033                            + " is not running in process " + callerApp);
13034                }
13035                callingUid = callerApp.info.uid;
13036                callingPid = callerApp.pid;
13037            } else {
13038                callerPackage = null;
13039                callingUid = Binder.getCallingUid();
13040                callingPid = Binder.getCallingPid();
13041            }
13042
13043            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13044                    true, true, "registerReceiver", callerPackage);
13045
13046            List allSticky = null;
13047
13048            // Look for any matching sticky broadcasts...
13049            Iterator actions = filter.actionsIterator();
13050            if (actions != null) {
13051                while (actions.hasNext()) {
13052                    String action = (String)actions.next();
13053                    allSticky = getStickiesLocked(action, filter, allSticky,
13054                            UserHandle.USER_ALL);
13055                    allSticky = getStickiesLocked(action, filter, allSticky,
13056                            UserHandle.getUserId(callingUid));
13057                }
13058            } else {
13059                allSticky = getStickiesLocked(null, filter, allSticky,
13060                        UserHandle.USER_ALL);
13061                allSticky = getStickiesLocked(null, filter, allSticky,
13062                        UserHandle.getUserId(callingUid));
13063            }
13064
13065            // The first sticky in the list is returned directly back to
13066            // the client.
13067            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13068
13069            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13070                    + ": " + sticky);
13071
13072            if (receiver == null) {
13073                return sticky;
13074            }
13075
13076            ReceiverList rl
13077                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13078            if (rl == null) {
13079                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13080                        userId, receiver);
13081                if (rl.app != null) {
13082                    rl.app.receivers.add(rl);
13083                } else {
13084                    try {
13085                        receiver.asBinder().linkToDeath(rl, 0);
13086                    } catch (RemoteException e) {
13087                        return sticky;
13088                    }
13089                    rl.linkedToDeath = true;
13090                }
13091                mRegisteredReceivers.put(receiver.asBinder(), rl);
13092            } else if (rl.uid != callingUid) {
13093                throw new IllegalArgumentException(
13094                        "Receiver requested to register for uid " + callingUid
13095                        + " was previously registered for uid " + rl.uid);
13096            } else if (rl.pid != callingPid) {
13097                throw new IllegalArgumentException(
13098                        "Receiver requested to register for pid " + callingPid
13099                        + " was previously registered for pid " + rl.pid);
13100            } else if (rl.userId != userId) {
13101                throw new IllegalArgumentException(
13102                        "Receiver requested to register for user " + userId
13103                        + " was previously registered for user " + rl.userId);
13104            }
13105            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13106                    permission, callingUid, userId);
13107            rl.add(bf);
13108            if (!bf.debugCheck()) {
13109                Slog.w(TAG, "==> For Dynamic broadast");
13110            }
13111            mReceiverResolver.addFilter(bf);
13112
13113            // Enqueue broadcasts for all existing stickies that match
13114            // this filter.
13115            if (allSticky != null) {
13116                ArrayList receivers = new ArrayList();
13117                receivers.add(bf);
13118
13119                int N = allSticky.size();
13120                for (int i=0; i<N; i++) {
13121                    Intent intent = (Intent)allSticky.get(i);
13122                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13123                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13124                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13125                            null, null, false, true, true, -1);
13126                    queue.enqueueParallelBroadcastLocked(r);
13127                    queue.scheduleBroadcastsLocked();
13128                }
13129            }
13130
13131            return sticky;
13132        }
13133    }
13134
13135    public void unregisterReceiver(IIntentReceiver receiver) {
13136        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13137
13138        final long origId = Binder.clearCallingIdentity();
13139        try {
13140            boolean doTrim = false;
13141
13142            synchronized(this) {
13143                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13144                if (rl != null) {
13145                    if (rl.curBroadcast != null) {
13146                        BroadcastRecord r = rl.curBroadcast;
13147                        final boolean doNext = finishReceiverLocked(
13148                                receiver.asBinder(), r.resultCode, r.resultData,
13149                                r.resultExtras, r.resultAbort);
13150                        if (doNext) {
13151                            doTrim = true;
13152                            r.queue.processNextBroadcast(false);
13153                        }
13154                    }
13155
13156                    if (rl.app != null) {
13157                        rl.app.receivers.remove(rl);
13158                    }
13159                    removeReceiverLocked(rl);
13160                    if (rl.linkedToDeath) {
13161                        rl.linkedToDeath = false;
13162                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13163                    }
13164                }
13165            }
13166
13167            // If we actually concluded any broadcasts, we might now be able
13168            // to trim the recipients' apps from our working set
13169            if (doTrim) {
13170                trimApplications();
13171                return;
13172            }
13173
13174        } finally {
13175            Binder.restoreCallingIdentity(origId);
13176        }
13177    }
13178
13179    void removeReceiverLocked(ReceiverList rl) {
13180        mRegisteredReceivers.remove(rl.receiver.asBinder());
13181        int N = rl.size();
13182        for (int i=0; i<N; i++) {
13183            mReceiverResolver.removeFilter(rl.get(i));
13184        }
13185    }
13186
13187    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13188        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13189            ProcessRecord r = mLruProcesses.get(i);
13190            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13191                try {
13192                    r.thread.dispatchPackageBroadcast(cmd, packages);
13193                } catch (RemoteException ex) {
13194                }
13195            }
13196        }
13197    }
13198
13199    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13200            int[] users) {
13201        List<ResolveInfo> receivers = null;
13202        try {
13203            HashSet<ComponentName> singleUserReceivers = null;
13204            boolean scannedFirstReceivers = false;
13205            for (int user : users) {
13206                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13207                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13208                if (user != 0 && newReceivers != null) {
13209                    // If this is not the primary user, we need to check for
13210                    // any receivers that should be filtered out.
13211                    for (int i=0; i<newReceivers.size(); i++) {
13212                        ResolveInfo ri = newReceivers.get(i);
13213                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13214                            newReceivers.remove(i);
13215                            i--;
13216                        }
13217                    }
13218                }
13219                if (newReceivers != null && newReceivers.size() == 0) {
13220                    newReceivers = null;
13221                }
13222                if (receivers == null) {
13223                    receivers = newReceivers;
13224                } else if (newReceivers != null) {
13225                    // We need to concatenate the additional receivers
13226                    // found with what we have do far.  This would be easy,
13227                    // but we also need to de-dup any receivers that are
13228                    // singleUser.
13229                    if (!scannedFirstReceivers) {
13230                        // Collect any single user receivers we had already retrieved.
13231                        scannedFirstReceivers = true;
13232                        for (int i=0; i<receivers.size(); i++) {
13233                            ResolveInfo ri = receivers.get(i);
13234                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13235                                ComponentName cn = new ComponentName(
13236                                        ri.activityInfo.packageName, ri.activityInfo.name);
13237                                if (singleUserReceivers == null) {
13238                                    singleUserReceivers = new HashSet<ComponentName>();
13239                                }
13240                                singleUserReceivers.add(cn);
13241                            }
13242                        }
13243                    }
13244                    // Add the new results to the existing results, tracking
13245                    // and de-dupping single user receivers.
13246                    for (int i=0; i<newReceivers.size(); i++) {
13247                        ResolveInfo ri = newReceivers.get(i);
13248                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13249                            ComponentName cn = new ComponentName(
13250                                    ri.activityInfo.packageName, ri.activityInfo.name);
13251                            if (singleUserReceivers == null) {
13252                                singleUserReceivers = new HashSet<ComponentName>();
13253                            }
13254                            if (!singleUserReceivers.contains(cn)) {
13255                                singleUserReceivers.add(cn);
13256                                receivers.add(ri);
13257                            }
13258                        } else {
13259                            receivers.add(ri);
13260                        }
13261                    }
13262                }
13263            }
13264        } catch (RemoteException ex) {
13265            // pm is in same process, this will never happen.
13266        }
13267        return receivers;
13268    }
13269
13270    private final int broadcastIntentLocked(ProcessRecord callerApp,
13271            String callerPackage, Intent intent, String resolvedType,
13272            IIntentReceiver resultTo, int resultCode, String resultData,
13273            Bundle map, String requiredPermission, int appOp,
13274            boolean ordered, boolean sticky, int callingPid, int callingUid,
13275            int userId) {
13276        intent = new Intent(intent);
13277
13278        // By default broadcasts do not go to stopped apps.
13279        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13280
13281        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13282            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13283            + " ordered=" + ordered + " userid=" + userId);
13284        if ((resultTo != null) && !ordered) {
13285            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13286        }
13287
13288        userId = handleIncomingUser(callingPid, callingUid, userId,
13289                true, false, "broadcast", callerPackage);
13290
13291        // Make sure that the user who is receiving this broadcast is started.
13292        // If not, we will just skip it.
13293        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13294            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13295                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13296                Slog.w(TAG, "Skipping broadcast of " + intent
13297                        + ": user " + userId + " is stopped");
13298                return ActivityManager.BROADCAST_SUCCESS;
13299            }
13300        }
13301
13302        /*
13303         * Prevent non-system code (defined here to be non-persistent
13304         * processes) from sending protected broadcasts.
13305         */
13306        int callingAppId = UserHandle.getAppId(callingUid);
13307        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13308            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13309            callingUid == 0) {
13310            // Always okay.
13311        } else if (callerApp == null || !callerApp.persistent) {
13312            try {
13313                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13314                        intent.getAction())) {
13315                    String msg = "Permission Denial: not allowed to send broadcast "
13316                            + intent.getAction() + " from pid="
13317                            + callingPid + ", uid=" + callingUid;
13318                    Slog.w(TAG, msg);
13319                    throw new SecurityException(msg);
13320                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13321                    // Special case for compatibility: we don't want apps to send this,
13322                    // but historically it has not been protected and apps may be using it
13323                    // to poke their own app widget.  So, instead of making it protected,
13324                    // just limit it to the caller.
13325                    if (callerApp == null) {
13326                        String msg = "Permission Denial: not allowed to send broadcast "
13327                                + intent.getAction() + " from unknown caller.";
13328                        Slog.w(TAG, msg);
13329                        throw new SecurityException(msg);
13330                    } else if (intent.getComponent() != null) {
13331                        // They are good enough to send to an explicit component...  verify
13332                        // it is being sent to the calling app.
13333                        if (!intent.getComponent().getPackageName().equals(
13334                                callerApp.info.packageName)) {
13335                            String msg = "Permission Denial: not allowed to send broadcast "
13336                                    + intent.getAction() + " to "
13337                                    + intent.getComponent().getPackageName() + " from "
13338                                    + callerApp.info.packageName;
13339                            Slog.w(TAG, msg);
13340                            throw new SecurityException(msg);
13341                        }
13342                    } else {
13343                        // Limit broadcast to their own package.
13344                        intent.setPackage(callerApp.info.packageName);
13345                    }
13346                }
13347            } catch (RemoteException e) {
13348                Slog.w(TAG, "Remote exception", e);
13349                return ActivityManager.BROADCAST_SUCCESS;
13350            }
13351        }
13352
13353        // Handle special intents: if this broadcast is from the package
13354        // manager about a package being removed, we need to remove all of
13355        // its activities from the history stack.
13356        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13357                intent.getAction());
13358        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13359                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13360                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13361                || uidRemoved) {
13362            if (checkComponentPermission(
13363                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13364                    callingPid, callingUid, -1, true)
13365                    == PackageManager.PERMISSION_GRANTED) {
13366                if (uidRemoved) {
13367                    final Bundle intentExtras = intent.getExtras();
13368                    final int uid = intentExtras != null
13369                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13370                    if (uid >= 0) {
13371                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13372                        synchronized (bs) {
13373                            bs.removeUidStatsLocked(uid);
13374                        }
13375                        mAppOpsService.uidRemoved(uid);
13376                    }
13377                } else {
13378                    // If resources are unavailable just force stop all
13379                    // those packages and flush the attribute cache as well.
13380                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13381                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13382                        if (list != null && (list.length > 0)) {
13383                            for (String pkg : list) {
13384                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13385                                        "storage unmount");
13386                            }
13387                            sendPackageBroadcastLocked(
13388                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13389                        }
13390                    } else {
13391                        Uri data = intent.getData();
13392                        String ssp;
13393                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13394                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13395                                    intent.getAction());
13396                            boolean fullUninstall = removed &&
13397                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13398                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13399                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13400                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13401                                        false, fullUninstall, userId,
13402                                        removed ? "pkg removed" : "pkg changed");
13403                            }
13404                            if (removed) {
13405                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13406                                        new String[] {ssp}, userId);
13407                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13408                                    mAppOpsService.packageRemoved(
13409                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13410
13411                                    // Remove all permissions granted from/to this package
13412                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13413                                }
13414                            }
13415                        }
13416                    }
13417                }
13418            } else {
13419                String msg = "Permission Denial: " + intent.getAction()
13420                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13421                        + ", uid=" + callingUid + ")"
13422                        + " requires "
13423                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13424                Slog.w(TAG, msg);
13425                throw new SecurityException(msg);
13426            }
13427
13428        // Special case for adding a package: by default turn on compatibility
13429        // mode.
13430        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13431            Uri data = intent.getData();
13432            String ssp;
13433            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13434                mCompatModePackages.handlePackageAddedLocked(ssp,
13435                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13436            }
13437        }
13438
13439        /*
13440         * If this is the time zone changed action, queue up a message that will reset the timezone
13441         * of all currently running processes. This message will get queued up before the broadcast
13442         * happens.
13443         */
13444        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13445            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13446        }
13447
13448        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13449            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13450        }
13451
13452        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13453            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13454            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13455        }
13456
13457        // Add to the sticky list if requested.
13458        if (sticky) {
13459            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13460                    callingPid, callingUid)
13461                    != PackageManager.PERMISSION_GRANTED) {
13462                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13463                        + callingPid + ", uid=" + callingUid
13464                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13465                Slog.w(TAG, msg);
13466                throw new SecurityException(msg);
13467            }
13468            if (requiredPermission != null) {
13469                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13470                        + " and enforce permission " + requiredPermission);
13471                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13472            }
13473            if (intent.getComponent() != null) {
13474                throw new SecurityException(
13475                        "Sticky broadcasts can't target a specific component");
13476            }
13477            // We use userId directly here, since the "all" target is maintained
13478            // as a separate set of sticky broadcasts.
13479            if (userId != UserHandle.USER_ALL) {
13480                // But first, if this is not a broadcast to all users, then
13481                // make sure it doesn't conflict with an existing broadcast to
13482                // all users.
13483                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13484                        UserHandle.USER_ALL);
13485                if (stickies != null) {
13486                    ArrayList<Intent> list = stickies.get(intent.getAction());
13487                    if (list != null) {
13488                        int N = list.size();
13489                        int i;
13490                        for (i=0; i<N; i++) {
13491                            if (intent.filterEquals(list.get(i))) {
13492                                throw new IllegalArgumentException(
13493                                        "Sticky broadcast " + intent + " for user "
13494                                        + userId + " conflicts with existing global broadcast");
13495                            }
13496                        }
13497                    }
13498                }
13499            }
13500            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13501            if (stickies == null) {
13502                stickies = new ArrayMap<String, ArrayList<Intent>>();
13503                mStickyBroadcasts.put(userId, stickies);
13504            }
13505            ArrayList<Intent> list = stickies.get(intent.getAction());
13506            if (list == null) {
13507                list = new ArrayList<Intent>();
13508                stickies.put(intent.getAction(), list);
13509            }
13510            int N = list.size();
13511            int i;
13512            for (i=0; i<N; i++) {
13513                if (intent.filterEquals(list.get(i))) {
13514                    // This sticky already exists, replace it.
13515                    list.set(i, new Intent(intent));
13516                    break;
13517                }
13518            }
13519            if (i >= N) {
13520                list.add(new Intent(intent));
13521            }
13522        }
13523
13524        int[] users;
13525        if (userId == UserHandle.USER_ALL) {
13526            // Caller wants broadcast to go to all started users.
13527            users = mStartedUserArray;
13528        } else {
13529            // Caller wants broadcast to go to one specific user.
13530            users = new int[] {userId};
13531        }
13532
13533        // Figure out who all will receive this broadcast.
13534        List receivers = null;
13535        List<BroadcastFilter> registeredReceivers = null;
13536        // Need to resolve the intent to interested receivers...
13537        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13538                 == 0) {
13539            receivers = collectReceiverComponents(intent, resolvedType, users);
13540        }
13541        if (intent.getComponent() == null) {
13542            registeredReceivers = mReceiverResolver.queryIntent(intent,
13543                    resolvedType, false, userId);
13544        }
13545
13546        final boolean replacePending =
13547                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13548
13549        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13550                + " replacePending=" + replacePending);
13551
13552        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13553        if (!ordered && NR > 0) {
13554            // If we are not serializing this broadcast, then send the
13555            // registered receivers separately so they don't wait for the
13556            // components to be launched.
13557            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13558            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13559                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13560                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13561                    ordered, sticky, false, userId);
13562            if (DEBUG_BROADCAST) Slog.v(
13563                    TAG, "Enqueueing parallel broadcast " + r);
13564            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13565            if (!replaced) {
13566                queue.enqueueParallelBroadcastLocked(r);
13567                queue.scheduleBroadcastsLocked();
13568            }
13569            registeredReceivers = null;
13570            NR = 0;
13571        }
13572
13573        // Merge into one list.
13574        int ir = 0;
13575        if (receivers != null) {
13576            // A special case for PACKAGE_ADDED: do not allow the package
13577            // being added to see this broadcast.  This prevents them from
13578            // using this as a back door to get run as soon as they are
13579            // installed.  Maybe in the future we want to have a special install
13580            // broadcast or such for apps, but we'd like to deliberately make
13581            // this decision.
13582            String skipPackages[] = null;
13583            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13584                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13585                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13586                Uri data = intent.getData();
13587                if (data != null) {
13588                    String pkgName = data.getSchemeSpecificPart();
13589                    if (pkgName != null) {
13590                        skipPackages = new String[] { pkgName };
13591                    }
13592                }
13593            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13594                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13595            }
13596            if (skipPackages != null && (skipPackages.length > 0)) {
13597                for (String skipPackage : skipPackages) {
13598                    if (skipPackage != null) {
13599                        int NT = receivers.size();
13600                        for (int it=0; it<NT; it++) {
13601                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13602                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13603                                receivers.remove(it);
13604                                it--;
13605                                NT--;
13606                            }
13607                        }
13608                    }
13609                }
13610            }
13611
13612            int NT = receivers != null ? receivers.size() : 0;
13613            int it = 0;
13614            ResolveInfo curt = null;
13615            BroadcastFilter curr = null;
13616            while (it < NT && ir < NR) {
13617                if (curt == null) {
13618                    curt = (ResolveInfo)receivers.get(it);
13619                }
13620                if (curr == null) {
13621                    curr = registeredReceivers.get(ir);
13622                }
13623                if (curr.getPriority() >= curt.priority) {
13624                    // Insert this broadcast record into the final list.
13625                    receivers.add(it, curr);
13626                    ir++;
13627                    curr = null;
13628                    it++;
13629                    NT++;
13630                } else {
13631                    // Skip to the next ResolveInfo in the final list.
13632                    it++;
13633                    curt = null;
13634                }
13635            }
13636        }
13637        while (ir < NR) {
13638            if (receivers == null) {
13639                receivers = new ArrayList();
13640            }
13641            receivers.add(registeredReceivers.get(ir));
13642            ir++;
13643        }
13644
13645        if ((receivers != null && receivers.size() > 0)
13646                || resultTo != null) {
13647            BroadcastQueue queue = broadcastQueueForIntent(intent);
13648            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13649                    callerPackage, callingPid, callingUid, resolvedType,
13650                    requiredPermission, appOp, receivers, resultTo, resultCode,
13651                    resultData, map, ordered, sticky, false, userId);
13652            if (DEBUG_BROADCAST) Slog.v(
13653                    TAG, "Enqueueing ordered broadcast " + r
13654                    + ": prev had " + queue.mOrderedBroadcasts.size());
13655            if (DEBUG_BROADCAST) {
13656                int seq = r.intent.getIntExtra("seq", -1);
13657                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13658            }
13659            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13660            if (!replaced) {
13661                queue.enqueueOrderedBroadcastLocked(r);
13662                queue.scheduleBroadcastsLocked();
13663            }
13664        }
13665
13666        return ActivityManager.BROADCAST_SUCCESS;
13667    }
13668
13669    final Intent verifyBroadcastLocked(Intent intent) {
13670        // Refuse possible leaked file descriptors
13671        if (intent != null && intent.hasFileDescriptors() == true) {
13672            throw new IllegalArgumentException("File descriptors passed in Intent");
13673        }
13674
13675        int flags = intent.getFlags();
13676
13677        if (!mProcessesReady) {
13678            // if the caller really truly claims to know what they're doing, go
13679            // ahead and allow the broadcast without launching any receivers
13680            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13681                intent = new Intent(intent);
13682                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13683            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13684                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13685                        + " before boot completion");
13686                throw new IllegalStateException("Cannot broadcast before boot completed");
13687            }
13688        }
13689
13690        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13691            throw new IllegalArgumentException(
13692                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13693        }
13694
13695        return intent;
13696    }
13697
13698    public final int broadcastIntent(IApplicationThread caller,
13699            Intent intent, String resolvedType, IIntentReceiver resultTo,
13700            int resultCode, String resultData, Bundle map,
13701            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13702        enforceNotIsolatedCaller("broadcastIntent");
13703        synchronized(this) {
13704            intent = verifyBroadcastLocked(intent);
13705
13706            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13707            final int callingPid = Binder.getCallingPid();
13708            final int callingUid = Binder.getCallingUid();
13709            final long origId = Binder.clearCallingIdentity();
13710            int res = broadcastIntentLocked(callerApp,
13711                    callerApp != null ? callerApp.info.packageName : null,
13712                    intent, resolvedType, resultTo,
13713                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13714                    callingPid, callingUid, userId);
13715            Binder.restoreCallingIdentity(origId);
13716            return res;
13717        }
13718    }
13719
13720    int broadcastIntentInPackage(String packageName, int uid,
13721            Intent intent, String resolvedType, IIntentReceiver resultTo,
13722            int resultCode, String resultData, Bundle map,
13723            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13724        synchronized(this) {
13725            intent = verifyBroadcastLocked(intent);
13726
13727            final long origId = Binder.clearCallingIdentity();
13728            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13729                    resultTo, resultCode, resultData, map, requiredPermission,
13730                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13731            Binder.restoreCallingIdentity(origId);
13732            return res;
13733        }
13734    }
13735
13736    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13737        // Refuse possible leaked file descriptors
13738        if (intent != null && intent.hasFileDescriptors() == true) {
13739            throw new IllegalArgumentException("File descriptors passed in Intent");
13740        }
13741
13742        userId = handleIncomingUser(Binder.getCallingPid(),
13743                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13744
13745        synchronized(this) {
13746            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13747                    != PackageManager.PERMISSION_GRANTED) {
13748                String msg = "Permission Denial: unbroadcastIntent() from pid="
13749                        + Binder.getCallingPid()
13750                        + ", uid=" + Binder.getCallingUid()
13751                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13752                Slog.w(TAG, msg);
13753                throw new SecurityException(msg);
13754            }
13755            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13756            if (stickies != null) {
13757                ArrayList<Intent> list = stickies.get(intent.getAction());
13758                if (list != null) {
13759                    int N = list.size();
13760                    int i;
13761                    for (i=0; i<N; i++) {
13762                        if (intent.filterEquals(list.get(i))) {
13763                            list.remove(i);
13764                            break;
13765                        }
13766                    }
13767                    if (list.size() <= 0) {
13768                        stickies.remove(intent.getAction());
13769                    }
13770                }
13771                if (stickies.size() <= 0) {
13772                    mStickyBroadcasts.remove(userId);
13773                }
13774            }
13775        }
13776    }
13777
13778    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13779            String resultData, Bundle resultExtras, boolean resultAbort) {
13780        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13781        if (r == null) {
13782            Slog.w(TAG, "finishReceiver called but not found on queue");
13783            return false;
13784        }
13785
13786        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13787    }
13788
13789    void backgroundServicesFinishedLocked(int userId) {
13790        for (BroadcastQueue queue : mBroadcastQueues) {
13791            queue.backgroundServicesFinishedLocked(userId);
13792        }
13793    }
13794
13795    public void finishReceiver(IBinder who, int resultCode, String resultData,
13796            Bundle resultExtras, boolean resultAbort) {
13797        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13798
13799        // Refuse possible leaked file descriptors
13800        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13801            throw new IllegalArgumentException("File descriptors passed in Bundle");
13802        }
13803
13804        final long origId = Binder.clearCallingIdentity();
13805        try {
13806            boolean doNext = false;
13807            BroadcastRecord r;
13808
13809            synchronized(this) {
13810                r = broadcastRecordForReceiverLocked(who);
13811                if (r != null) {
13812                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13813                        resultData, resultExtras, resultAbort, true);
13814                }
13815            }
13816
13817            if (doNext) {
13818                r.queue.processNextBroadcast(false);
13819            }
13820            trimApplications();
13821        } finally {
13822            Binder.restoreCallingIdentity(origId);
13823        }
13824    }
13825
13826    // =========================================================
13827    // INSTRUMENTATION
13828    // =========================================================
13829
13830    public boolean startInstrumentation(ComponentName className,
13831            String profileFile, int flags, Bundle arguments,
13832            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13833            int userId) {
13834        enforceNotIsolatedCaller("startInstrumentation");
13835        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13836                userId, false, true, "startInstrumentation", null);
13837        // Refuse possible leaked file descriptors
13838        if (arguments != null && arguments.hasFileDescriptors()) {
13839            throw new IllegalArgumentException("File descriptors passed in Bundle");
13840        }
13841
13842        synchronized(this) {
13843            InstrumentationInfo ii = null;
13844            ApplicationInfo ai = null;
13845            try {
13846                ii = mContext.getPackageManager().getInstrumentationInfo(
13847                    className, STOCK_PM_FLAGS);
13848                ai = AppGlobals.getPackageManager().getApplicationInfo(
13849                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13850            } catch (PackageManager.NameNotFoundException e) {
13851            } catch (RemoteException e) {
13852            }
13853            if (ii == null) {
13854                reportStartInstrumentationFailure(watcher, className,
13855                        "Unable to find instrumentation info for: " + className);
13856                return false;
13857            }
13858            if (ai == null) {
13859                reportStartInstrumentationFailure(watcher, className,
13860                        "Unable to find instrumentation target package: " + ii.targetPackage);
13861                return false;
13862            }
13863
13864            int match = mContext.getPackageManager().checkSignatures(
13865                    ii.targetPackage, ii.packageName);
13866            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13867                String msg = "Permission Denial: starting instrumentation "
13868                        + className + " from pid="
13869                        + Binder.getCallingPid()
13870                        + ", uid=" + Binder.getCallingPid()
13871                        + " not allowed because package " + ii.packageName
13872                        + " does not have a signature matching the target "
13873                        + ii.targetPackage;
13874                reportStartInstrumentationFailure(watcher, className, msg);
13875                throw new SecurityException(msg);
13876            }
13877
13878            final long origId = Binder.clearCallingIdentity();
13879            // Instrumentation can kill and relaunch even persistent processes
13880            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
13881                    "start instr");
13882            ProcessRecord app = addAppLocked(ai, false);
13883            app.instrumentationClass = className;
13884            app.instrumentationInfo = ai;
13885            app.instrumentationProfileFile = profileFile;
13886            app.instrumentationArguments = arguments;
13887            app.instrumentationWatcher = watcher;
13888            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13889            app.instrumentationResultClass = className;
13890            Binder.restoreCallingIdentity(origId);
13891        }
13892
13893        return true;
13894    }
13895
13896    /**
13897     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13898     * error to the logs, but if somebody is watching, send the report there too.  This enables
13899     * the "am" command to report errors with more information.
13900     *
13901     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13902     * @param cn The component name of the instrumentation.
13903     * @param report The error report.
13904     */
13905    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13906            ComponentName cn, String report) {
13907        Slog.w(TAG, report);
13908        try {
13909            if (watcher != null) {
13910                Bundle results = new Bundle();
13911                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13912                results.putString("Error", report);
13913                watcher.instrumentationStatus(cn, -1, results);
13914            }
13915        } catch (RemoteException e) {
13916            Slog.w(TAG, e);
13917        }
13918    }
13919
13920    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13921        if (app.instrumentationWatcher != null) {
13922            try {
13923                // NOTE:  IInstrumentationWatcher *must* be oneway here
13924                app.instrumentationWatcher.instrumentationFinished(
13925                    app.instrumentationClass,
13926                    resultCode,
13927                    results);
13928            } catch (RemoteException e) {
13929            }
13930        }
13931        if (app.instrumentationUiAutomationConnection != null) {
13932            try {
13933                app.instrumentationUiAutomationConnection.shutdown();
13934            } catch (RemoteException re) {
13935                /* ignore */
13936            }
13937            // Only a UiAutomation can set this flag and now that
13938            // it is finished we make sure it is reset to its default.
13939            mUserIsMonkey = false;
13940        }
13941        app.instrumentationWatcher = null;
13942        app.instrumentationUiAutomationConnection = null;
13943        app.instrumentationClass = null;
13944        app.instrumentationInfo = null;
13945        app.instrumentationProfileFile = null;
13946        app.instrumentationArguments = null;
13947
13948        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
13949                "finished inst");
13950    }
13951
13952    public void finishInstrumentation(IApplicationThread target,
13953            int resultCode, Bundle results) {
13954        int userId = UserHandle.getCallingUserId();
13955        // Refuse possible leaked file descriptors
13956        if (results != null && results.hasFileDescriptors()) {
13957            throw new IllegalArgumentException("File descriptors passed in Intent");
13958        }
13959
13960        synchronized(this) {
13961            ProcessRecord app = getRecordForAppLocked(target);
13962            if (app == null) {
13963                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13964                return;
13965            }
13966            final long origId = Binder.clearCallingIdentity();
13967            finishInstrumentationLocked(app, resultCode, results);
13968            Binder.restoreCallingIdentity(origId);
13969        }
13970    }
13971
13972    // =========================================================
13973    // CONFIGURATION
13974    // =========================================================
13975
13976    public ConfigurationInfo getDeviceConfigurationInfo() {
13977        ConfigurationInfo config = new ConfigurationInfo();
13978        synchronized (this) {
13979            config.reqTouchScreen = mConfiguration.touchscreen;
13980            config.reqKeyboardType = mConfiguration.keyboard;
13981            config.reqNavigation = mConfiguration.navigation;
13982            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13983                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13984                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13985            }
13986            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13987                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13988                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13989            }
13990            config.reqGlEsVersion = GL_ES_VERSION;
13991        }
13992        return config;
13993    }
13994
13995    ActivityStack getFocusedStack() {
13996        return mStackSupervisor.getFocusedStack();
13997    }
13998
13999    public Configuration getConfiguration() {
14000        Configuration ci;
14001        synchronized(this) {
14002            ci = new Configuration(mConfiguration);
14003        }
14004        return ci;
14005    }
14006
14007    public void updatePersistentConfiguration(Configuration values) {
14008        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14009                "updateConfiguration()");
14010        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14011                "updateConfiguration()");
14012        if (values == null) {
14013            throw new NullPointerException("Configuration must not be null");
14014        }
14015
14016        synchronized(this) {
14017            final long origId = Binder.clearCallingIdentity();
14018            updateConfigurationLocked(values, null, true, false);
14019            Binder.restoreCallingIdentity(origId);
14020        }
14021    }
14022
14023    public void updateConfiguration(Configuration values) {
14024        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14025                "updateConfiguration()");
14026
14027        synchronized(this) {
14028            if (values == null && mWindowManager != null) {
14029                // sentinel: fetch the current configuration from the window manager
14030                values = mWindowManager.computeNewConfiguration();
14031            }
14032
14033            if (mWindowManager != null) {
14034                mProcessList.applyDisplaySize(mWindowManager);
14035            }
14036
14037            final long origId = Binder.clearCallingIdentity();
14038            if (values != null) {
14039                Settings.System.clearConfiguration(values);
14040            }
14041            updateConfigurationLocked(values, null, false, false);
14042            Binder.restoreCallingIdentity(origId);
14043        }
14044    }
14045
14046    /**
14047     * Do either or both things: (1) change the current configuration, and (2)
14048     * make sure the given activity is running with the (now) current
14049     * configuration.  Returns true if the activity has been left running, or
14050     * false if <var>starting</var> is being destroyed to match the new
14051     * configuration.
14052     * @param persistent TODO
14053     */
14054    boolean updateConfigurationLocked(Configuration values,
14055            ActivityRecord starting, boolean persistent, boolean initLocale) {
14056        int changes = 0;
14057
14058        if (values != null) {
14059            Configuration newConfig = new Configuration(mConfiguration);
14060            changes = newConfig.updateFrom(values);
14061            if (changes != 0) {
14062                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14063                    Slog.i(TAG, "Updating configuration to: " + values);
14064                }
14065
14066                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14067
14068                if (values.locale != null && !initLocale) {
14069                    saveLocaleLocked(values.locale,
14070                                     !values.locale.equals(mConfiguration.locale),
14071                                     values.userSetLocale);
14072                }
14073
14074                mConfigurationSeq++;
14075                if (mConfigurationSeq <= 0) {
14076                    mConfigurationSeq = 1;
14077                }
14078                newConfig.seq = mConfigurationSeq;
14079                mConfiguration = newConfig;
14080                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14081
14082                final Configuration configCopy = new Configuration(mConfiguration);
14083
14084                // TODO: If our config changes, should we auto dismiss any currently
14085                // showing dialogs?
14086                mShowDialogs = shouldShowDialogs(newConfig);
14087
14088                AttributeCache ac = AttributeCache.instance();
14089                if (ac != null) {
14090                    ac.updateConfiguration(configCopy);
14091                }
14092
14093                // Make sure all resources in our process are updated
14094                // right now, so that anyone who is going to retrieve
14095                // resource values after we return will be sure to get
14096                // the new ones.  This is especially important during
14097                // boot, where the first config change needs to guarantee
14098                // all resources have that config before following boot
14099                // code is executed.
14100                mSystemThread.applyConfigurationToResources(configCopy);
14101
14102                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14103                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14104                    msg.obj = new Configuration(configCopy);
14105                    mHandler.sendMessage(msg);
14106                }
14107
14108                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14109                    ProcessRecord app = mLruProcesses.get(i);
14110                    try {
14111                        if (app.thread != null) {
14112                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14113                                    + app.processName + " new config " + mConfiguration);
14114                            app.thread.scheduleConfigurationChanged(configCopy);
14115                        }
14116                    } catch (Exception e) {
14117                    }
14118                }
14119                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14120                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14121                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14122                        | Intent.FLAG_RECEIVER_FOREGROUND);
14123                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14124                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14125                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14126                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14127                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14128                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14129                    broadcastIntentLocked(null, null, intent,
14130                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14131                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14132                }
14133            }
14134        }
14135
14136        boolean kept = true;
14137        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14138        // mainStack is null during startup.
14139        if (mainStack != null) {
14140            if (changes != 0 && starting == null) {
14141                // If the configuration changed, and the caller is not already
14142                // in the process of starting an activity, then find the top
14143                // activity to check if its configuration needs to change.
14144                starting = mainStack.topRunningActivityLocked(null);
14145            }
14146
14147            if (starting != null) {
14148                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14149                // And we need to make sure at this point that all other activities
14150                // are made visible with the correct configuration.
14151                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14152            }
14153        }
14154
14155        if (values != null && mWindowManager != null) {
14156            mWindowManager.setNewConfiguration(mConfiguration);
14157        }
14158
14159        return kept;
14160    }
14161
14162    /**
14163     * Decide based on the configuration whether we should shouw the ANR,
14164     * crash, etc dialogs.  The idea is that if there is no affordnace to
14165     * press the on-screen buttons, we shouldn't show the dialog.
14166     *
14167     * A thought: SystemUI might also want to get told about this, the Power
14168     * dialog / global actions also might want different behaviors.
14169     */
14170    private static final boolean shouldShowDialogs(Configuration config) {
14171        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14172                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14173    }
14174
14175    /**
14176     * Save the locale.  You must be inside a synchronized (this) block.
14177     */
14178    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14179        if(isDiff) {
14180            SystemProperties.set("user.language", l.getLanguage());
14181            SystemProperties.set("user.region", l.getCountry());
14182        }
14183
14184        if(isPersist) {
14185            SystemProperties.set("persist.sys.language", l.getLanguage());
14186            SystemProperties.set("persist.sys.country", l.getCountry());
14187            SystemProperties.set("persist.sys.localevar", l.getVariant());
14188        }
14189    }
14190
14191    @Override
14192    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14193        ActivityRecord srec = ActivityRecord.forToken(token);
14194        return srec != null && srec.task.affinity != null &&
14195                srec.task.affinity.equals(destAffinity);
14196    }
14197
14198    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14199            Intent resultData) {
14200
14201        synchronized (this) {
14202            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14203            if (stack != null) {
14204                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14205            }
14206            return false;
14207        }
14208    }
14209
14210    public int getLaunchedFromUid(IBinder activityToken) {
14211        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14212        if (srec == null) {
14213            return -1;
14214        }
14215        return srec.launchedFromUid;
14216    }
14217
14218    public String getLaunchedFromPackage(IBinder activityToken) {
14219        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14220        if (srec == null) {
14221            return null;
14222        }
14223        return srec.launchedFromPackage;
14224    }
14225
14226    // =========================================================
14227    // LIFETIME MANAGEMENT
14228    // =========================================================
14229
14230    // Returns which broadcast queue the app is the current [or imminent] receiver
14231    // on, or 'null' if the app is not an active broadcast recipient.
14232    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14233        BroadcastRecord r = app.curReceiver;
14234        if (r != null) {
14235            return r.queue;
14236        }
14237
14238        // It's not the current receiver, but it might be starting up to become one
14239        synchronized (this) {
14240            for (BroadcastQueue queue : mBroadcastQueues) {
14241                r = queue.mPendingBroadcast;
14242                if (r != null && r.curApp == app) {
14243                    // found it; report which queue it's in
14244                    return queue;
14245                }
14246            }
14247        }
14248
14249        return null;
14250    }
14251
14252    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14253            boolean doingAll, long now) {
14254        if (mAdjSeq == app.adjSeq) {
14255            // This adjustment has already been computed.
14256            return app.curRawAdj;
14257        }
14258
14259        if (app.thread == null) {
14260            app.adjSeq = mAdjSeq;
14261            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14262            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14263            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14264        }
14265
14266        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14267        app.adjSource = null;
14268        app.adjTarget = null;
14269        app.empty = false;
14270        app.cached = false;
14271
14272        final int activitiesSize = app.activities.size();
14273
14274        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14275            // The max adjustment doesn't allow this app to be anything
14276            // below foreground, so it is not worth doing work for it.
14277            app.adjType = "fixed";
14278            app.adjSeq = mAdjSeq;
14279            app.curRawAdj = app.maxAdj;
14280            app.foregroundActivities = false;
14281            app.keeping = true;
14282            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14283            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14284            // System process can do UI, and when they do we want to have
14285            // them trim their memory after the user leaves the UI.  To
14286            // facilitate this, here we need to determine whether or not it
14287            // is currently showing UI.
14288            app.systemNoUi = true;
14289            if (app == TOP_APP) {
14290                app.systemNoUi = false;
14291            } else if (activitiesSize > 0) {
14292                for (int j = 0; j < activitiesSize; j++) {
14293                    final ActivityRecord r = app.activities.get(j);
14294                    if (r.visible) {
14295                        app.systemNoUi = false;
14296                    }
14297                }
14298            }
14299            if (!app.systemNoUi) {
14300                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14301            }
14302            return (app.curAdj=app.maxAdj);
14303        }
14304
14305        app.keeping = false;
14306        app.systemNoUi = false;
14307
14308        // Determine the importance of the process, starting with most
14309        // important to least, and assign an appropriate OOM adjustment.
14310        int adj;
14311        int schedGroup;
14312        int procState;
14313        boolean foregroundActivities = false;
14314        boolean interesting = false;
14315        BroadcastQueue queue;
14316        if (app == TOP_APP) {
14317            // The last app on the list is the foreground app.
14318            adj = ProcessList.FOREGROUND_APP_ADJ;
14319            schedGroup = Process.THREAD_GROUP_DEFAULT;
14320            app.adjType = "top-activity";
14321            foregroundActivities = true;
14322            interesting = true;
14323            procState = ActivityManager.PROCESS_STATE_TOP;
14324        } else if (app.instrumentationClass != null) {
14325            // Don't want to kill running instrumentation.
14326            adj = ProcessList.FOREGROUND_APP_ADJ;
14327            schedGroup = Process.THREAD_GROUP_DEFAULT;
14328            app.adjType = "instrumentation";
14329            interesting = true;
14330            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14331        } else if ((queue = isReceivingBroadcast(app)) != null) {
14332            // An app that is currently receiving a broadcast also
14333            // counts as being in the foreground for OOM killer purposes.
14334            // It's placed in a sched group based on the nature of the
14335            // broadcast as reflected by which queue it's active in.
14336            adj = ProcessList.FOREGROUND_APP_ADJ;
14337            schedGroup = (queue == mFgBroadcastQueue)
14338                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14339            app.adjType = "broadcast";
14340            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14341        } else if (app.executingServices.size() > 0) {
14342            // An app that is currently executing a service callback also
14343            // counts as being in the foreground.
14344            adj = ProcessList.FOREGROUND_APP_ADJ;
14345            schedGroup = app.execServicesFg ?
14346                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14347            app.adjType = "exec-service";
14348            procState = ActivityManager.PROCESS_STATE_SERVICE;
14349            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14350        } else {
14351            // As far as we know the process is empty.  We may change our mind later.
14352            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14353            // At this point we don't actually know the adjustment.  Use the cached adj
14354            // value that the caller wants us to.
14355            adj = cachedAdj;
14356            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14357            app.cached = true;
14358            app.empty = true;
14359            app.adjType = "cch-empty";
14360        }
14361
14362        // Examine all activities if not already foreground.
14363        if (!foregroundActivities && activitiesSize > 0) {
14364            for (int j = 0; j < activitiesSize; j++) {
14365                final ActivityRecord r = app.activities.get(j);
14366                if (r.app != app) {
14367                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14368                            + app + "?!?");
14369                    continue;
14370                }
14371                if (r.visible) {
14372                    // App has a visible activity; only upgrade adjustment.
14373                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14374                        adj = ProcessList.VISIBLE_APP_ADJ;
14375                        app.adjType = "visible";
14376                    }
14377                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14378                        procState = ActivityManager.PROCESS_STATE_TOP;
14379                    }
14380                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14381                    app.cached = false;
14382                    app.empty = false;
14383                    foregroundActivities = true;
14384                    break;
14385                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14386                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14387                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14388                        app.adjType = "pausing";
14389                    }
14390                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14391                        procState = ActivityManager.PROCESS_STATE_TOP;
14392                    }
14393                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14394                    app.cached = false;
14395                    app.empty = false;
14396                    foregroundActivities = true;
14397                } else if (r.state == ActivityState.STOPPING) {
14398                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14399                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14400                        app.adjType = "stopping";
14401                    }
14402                    // For the process state, we will at this point consider the
14403                    // process to be cached.  It will be cached either as an activity
14404                    // or empty depending on whether the activity is finishing.  We do
14405                    // this so that we can treat the process as cached for purposes of
14406                    // memory trimming (determing current memory level, trim command to
14407                    // send to process) since there can be an arbitrary number of stopping
14408                    // processes and they should soon all go into the cached state.
14409                    if (!r.finishing) {
14410                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14411                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14412                        }
14413                    }
14414                    app.cached = false;
14415                    app.empty = false;
14416                    foregroundActivities = true;
14417                } else {
14418                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14419                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14420                        app.adjType = "cch-act";
14421                    }
14422                }
14423            }
14424        }
14425
14426        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14427            if (app.foregroundServices) {
14428                // The user is aware of this app, so make it visible.
14429                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14430                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14431                app.cached = false;
14432                app.adjType = "fg-service";
14433                schedGroup = Process.THREAD_GROUP_DEFAULT;
14434            } else if (app.forcingToForeground != null) {
14435                // The user is aware of this app, so make it visible.
14436                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14437                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14438                app.cached = false;
14439                app.adjType = "force-fg";
14440                app.adjSource = app.forcingToForeground;
14441                schedGroup = Process.THREAD_GROUP_DEFAULT;
14442            }
14443        }
14444
14445        if (app.foregroundServices) {
14446            interesting = true;
14447        }
14448
14449        if (app == mHeavyWeightProcess) {
14450            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14451                // We don't want to kill the current heavy-weight process.
14452                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14453                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14454                app.cached = false;
14455                app.adjType = "heavy";
14456            }
14457            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14458                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14459            }
14460        }
14461
14462        if (app == mHomeProcess) {
14463            if (adj > ProcessList.HOME_APP_ADJ) {
14464                // This process is hosting what we currently consider to be the
14465                // home app, so we don't want to let it go into the background.
14466                adj = ProcessList.HOME_APP_ADJ;
14467                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14468                app.cached = false;
14469                app.adjType = "home";
14470            }
14471            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14472                procState = ActivityManager.PROCESS_STATE_HOME;
14473            }
14474        }
14475
14476        if (app == mPreviousProcess && app.activities.size() > 0) {
14477            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14478                // This was the previous process that showed UI to the user.
14479                // We want to try to keep it around more aggressively, to give
14480                // a good experience around switching between two apps.
14481                adj = ProcessList.PREVIOUS_APP_ADJ;
14482                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14483                app.cached = false;
14484                app.adjType = "previous";
14485            }
14486            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14487                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14488            }
14489        }
14490
14491        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14492                + " reason=" + app.adjType);
14493
14494        // By default, we use the computed adjustment.  It may be changed if
14495        // there are applications dependent on our services or providers, but
14496        // this gives us a baseline and makes sure we don't get into an
14497        // infinite recursion.
14498        app.adjSeq = mAdjSeq;
14499        app.curRawAdj = adj;
14500        app.hasStartedServices = false;
14501
14502        if (mBackupTarget != null && app == mBackupTarget.app) {
14503            // If possible we want to avoid killing apps while they're being backed up
14504            if (adj > ProcessList.BACKUP_APP_ADJ) {
14505                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14506                adj = ProcessList.BACKUP_APP_ADJ;
14507                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14508                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14509                }
14510                app.adjType = "backup";
14511                app.cached = false;
14512            }
14513            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14514                procState = ActivityManager.PROCESS_STATE_BACKUP;
14515            }
14516        }
14517
14518        boolean mayBeTop = false;
14519
14520        for (int is = app.services.size()-1;
14521                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14522                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14523                        || procState > ActivityManager.PROCESS_STATE_TOP);
14524                is--) {
14525            ServiceRecord s = app.services.valueAt(is);
14526            if (s.startRequested) {
14527                app.hasStartedServices = true;
14528                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14529                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14530                }
14531                if (app.hasShownUi && app != mHomeProcess) {
14532                    // If this process has shown some UI, let it immediately
14533                    // go to the LRU list because it may be pretty heavy with
14534                    // UI stuff.  We'll tag it with a label just to help
14535                    // debug and understand what is going on.
14536                    if (adj > ProcessList.SERVICE_ADJ) {
14537                        app.adjType = "cch-started-ui-services";
14538                    }
14539                } else {
14540                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14541                        // This service has seen some activity within
14542                        // recent memory, so we will keep its process ahead
14543                        // of the background processes.
14544                        if (adj > ProcessList.SERVICE_ADJ) {
14545                            adj = ProcessList.SERVICE_ADJ;
14546                            app.adjType = "started-services";
14547                            app.cached = false;
14548                        }
14549                    }
14550                    // If we have let the service slide into the background
14551                    // state, still have some text describing what it is doing
14552                    // even though the service no longer has an impact.
14553                    if (adj > ProcessList.SERVICE_ADJ) {
14554                        app.adjType = "cch-started-services";
14555                    }
14556                }
14557                // Don't kill this process because it is doing work; it
14558                // has said it is doing work.
14559                app.keeping = true;
14560            }
14561            for (int conni = s.connections.size()-1;
14562                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14563                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14564                            || procState > ActivityManager.PROCESS_STATE_TOP);
14565                    conni--) {
14566                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14567                for (int i = 0;
14568                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14569                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14570                                || procState > ActivityManager.PROCESS_STATE_TOP);
14571                        i++) {
14572                    // XXX should compute this based on the max of
14573                    // all connected clients.
14574                    ConnectionRecord cr = clist.get(i);
14575                    if (cr.binding.client == app) {
14576                        // Binding to ourself is not interesting.
14577                        continue;
14578                    }
14579                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14580                        ProcessRecord client = cr.binding.client;
14581                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14582                                TOP_APP, doingAll, now);
14583                        int clientProcState = client.curProcState;
14584                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14585                            // If the other app is cached for any reason, for purposes here
14586                            // we are going to consider it empty.  The specific cached state
14587                            // doesn't propagate except under certain conditions.
14588                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14589                        }
14590                        String adjType = null;
14591                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14592                            // Not doing bind OOM management, so treat
14593                            // this guy more like a started service.
14594                            if (app.hasShownUi && app != mHomeProcess) {
14595                                // If this process has shown some UI, let it immediately
14596                                // go to the LRU list because it may be pretty heavy with
14597                                // UI stuff.  We'll tag it with a label just to help
14598                                // debug and understand what is going on.
14599                                if (adj > clientAdj) {
14600                                    adjType = "cch-bound-ui-services";
14601                                }
14602                                app.cached = false;
14603                                clientAdj = adj;
14604                                clientProcState = procState;
14605                            } else {
14606                                if (now >= (s.lastActivity
14607                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14608                                    // This service has not seen activity within
14609                                    // recent memory, so allow it to drop to the
14610                                    // LRU list if there is no other reason to keep
14611                                    // it around.  We'll also tag it with a label just
14612                                    // to help debug and undertand what is going on.
14613                                    if (adj > clientAdj) {
14614                                        adjType = "cch-bound-services";
14615                                    }
14616                                    clientAdj = adj;
14617                                }
14618                            }
14619                        }
14620                        if (adj > clientAdj) {
14621                            // If this process has recently shown UI, and
14622                            // the process that is binding to it is less
14623                            // important than being visible, then we don't
14624                            // care about the binding as much as we care
14625                            // about letting this process get into the LRU
14626                            // list to be killed and restarted if needed for
14627                            // memory.
14628                            if (app.hasShownUi && app != mHomeProcess
14629                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14630                                adjType = "cch-bound-ui-services";
14631                            } else {
14632                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14633                                        |Context.BIND_IMPORTANT)) != 0) {
14634                                    adj = clientAdj;
14635                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14636                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14637                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14638                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14639                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14640                                    adj = clientAdj;
14641                                } else {
14642                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14643                                        adj = ProcessList.VISIBLE_APP_ADJ;
14644                                    }
14645                                }
14646                                if (!client.cached) {
14647                                    app.cached = false;
14648                                }
14649                                if (client.keeping) {
14650                                    app.keeping = true;
14651                                }
14652                                adjType = "service";
14653                            }
14654                        }
14655                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14656                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14657                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14658                            }
14659                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14660                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14661                                    // Special handling of clients who are in the top state.
14662                                    // We *may* want to consider this process to be in the
14663                                    // top state as well, but only if there is not another
14664                                    // reason for it to be running.  Being on the top is a
14665                                    // special state, meaning you are specifically running
14666                                    // for the current top app.  If the process is already
14667                                    // running in the background for some other reason, it
14668                                    // is more important to continue considering it to be
14669                                    // in the background state.
14670                                    mayBeTop = true;
14671                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14672                                } else {
14673                                    // Special handling for above-top states (persistent
14674                                    // processes).  These should not bring the current process
14675                                    // into the top state, since they are not on top.  Instead
14676                                    // give them the best state after that.
14677                                    clientProcState =
14678                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14679                                }
14680                            }
14681                        } else {
14682                            if (clientProcState <
14683                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14684                                clientProcState =
14685                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14686                            }
14687                        }
14688                        if (procState > clientProcState) {
14689                            procState = clientProcState;
14690                        }
14691                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14692                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14693                            app.pendingUiClean = true;
14694                        }
14695                        if (adjType != null) {
14696                            app.adjType = adjType;
14697                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14698                                    .REASON_SERVICE_IN_USE;
14699                            app.adjSource = cr.binding.client;
14700                            app.adjSourceOom = clientAdj;
14701                            app.adjTarget = s.name;
14702                        }
14703                    }
14704                    final ActivityRecord a = cr.activity;
14705                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14706                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14707                                (a.visible || a.state == ActivityState.RESUMED
14708                                 || a.state == ActivityState.PAUSING)) {
14709                            adj = ProcessList.FOREGROUND_APP_ADJ;
14710                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14711                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14712                            }
14713                            app.cached = false;
14714                            app.adjType = "service";
14715                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14716                                    .REASON_SERVICE_IN_USE;
14717                            app.adjSource = a;
14718                            app.adjSourceOom = adj;
14719                            app.adjTarget = s.name;
14720                        }
14721                    }
14722                }
14723            }
14724        }
14725
14726        for (int provi = app.pubProviders.size()-1;
14727                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14728                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14729                        || procState > ActivityManager.PROCESS_STATE_TOP);
14730                provi--) {
14731            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14732            for (int i = cpr.connections.size()-1;
14733                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14734                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14735                            || procState > ActivityManager.PROCESS_STATE_TOP);
14736                    i--) {
14737                ContentProviderConnection conn = cpr.connections.get(i);
14738                ProcessRecord client = conn.client;
14739                if (client == app) {
14740                    // Being our own client is not interesting.
14741                    continue;
14742                }
14743                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14744                int clientProcState = client.curProcState;
14745                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14746                    // If the other app is cached for any reason, for purposes here
14747                    // we are going to consider it empty.
14748                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14749                }
14750                if (adj > clientAdj) {
14751                    if (app.hasShownUi && app != mHomeProcess
14752                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14753                        app.adjType = "cch-ui-provider";
14754                    } else {
14755                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14756                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14757                        app.adjType = "provider";
14758                    }
14759                    app.cached &= client.cached;
14760                    app.keeping |= client.keeping;
14761                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14762                            .REASON_PROVIDER_IN_USE;
14763                    app.adjSource = client;
14764                    app.adjSourceOom = clientAdj;
14765                    app.adjTarget = cpr.name;
14766                }
14767                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14768                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14769                        // Special handling of clients who are in the top state.
14770                        // We *may* want to consider this process to be in the
14771                        // top state as well, but only if there is not another
14772                        // reason for it to be running.  Being on the top is a
14773                        // special state, meaning you are specifically running
14774                        // for the current top app.  If the process is already
14775                        // running in the background for some other reason, it
14776                        // is more important to continue considering it to be
14777                        // in the background state.
14778                        mayBeTop = true;
14779                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14780                    } else {
14781                        // Special handling for above-top states (persistent
14782                        // processes).  These should not bring the current process
14783                        // into the top state, since they are not on top.  Instead
14784                        // give them the best state after that.
14785                        clientProcState =
14786                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14787                    }
14788                }
14789                if (procState > clientProcState) {
14790                    procState = clientProcState;
14791                }
14792                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14793                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14794                }
14795            }
14796            // If the provider has external (non-framework) process
14797            // dependencies, ensure that its adjustment is at least
14798            // FOREGROUND_APP_ADJ.
14799            if (cpr.hasExternalProcessHandles()) {
14800                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14801                    adj = ProcessList.FOREGROUND_APP_ADJ;
14802                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14803                    app.cached = false;
14804                    app.keeping = true;
14805                    app.adjType = "provider";
14806                    app.adjTarget = cpr.name;
14807                }
14808                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14809                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14810                }
14811            }
14812        }
14813
14814        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14815            // A client of one of our services or providers is in the top state.  We
14816            // *may* want to be in the top state, but not if we are already running in
14817            // the background for some other reason.  For the decision here, we are going
14818            // to pick out a few specific states that we want to remain in when a client
14819            // is top (states that tend to be longer-term) and otherwise allow it to go
14820            // to the top state.
14821            switch (procState) {
14822                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14823                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14824                case ActivityManager.PROCESS_STATE_SERVICE:
14825                    // These all are longer-term states, so pull them up to the top
14826                    // of the background states, but not all the way to the top state.
14827                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14828                    break;
14829                default:
14830                    // Otherwise, top is a better choice, so take it.
14831                    procState = ActivityManager.PROCESS_STATE_TOP;
14832                    break;
14833            }
14834        }
14835
14836        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14837            // This is a cached process, but with client activities.  Mark it so.
14838            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14839            app.adjType = "cch-client-act";
14840        }
14841
14842        if (adj == ProcessList.SERVICE_ADJ) {
14843            if (doingAll) {
14844                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14845                mNewNumServiceProcs++;
14846                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14847                if (!app.serviceb) {
14848                    // This service isn't far enough down on the LRU list to
14849                    // normally be a B service, but if we are low on RAM and it
14850                    // is large we want to force it down since we would prefer to
14851                    // keep launcher over it.
14852                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14853                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14854                        app.serviceHighRam = true;
14855                        app.serviceb = true;
14856                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14857                    } else {
14858                        mNewNumAServiceProcs++;
14859                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14860                    }
14861                } else {
14862                    app.serviceHighRam = false;
14863                }
14864            }
14865            if (app.serviceb) {
14866                adj = ProcessList.SERVICE_B_ADJ;
14867            }
14868        }
14869
14870        app.curRawAdj = adj;
14871
14872        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14873        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14874        if (adj > app.maxAdj) {
14875            adj = app.maxAdj;
14876            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14877                schedGroup = Process.THREAD_GROUP_DEFAULT;
14878            }
14879        }
14880        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14881            app.keeping = true;
14882        }
14883
14884        // Do final modification to adj.  Everything we do between here and applying
14885        // the final setAdj must be done in this function, because we will also use
14886        // it when computing the final cached adj later.  Note that we don't need to
14887        // worry about this for max adj above, since max adj will always be used to
14888        // keep it out of the cached vaues.
14889        adj = app.modifyRawOomAdj(adj);
14890
14891        app.curProcState = procState;
14892
14893        int importance = app.memImportance;
14894        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14895            app.curAdj = adj;
14896            app.curSchedGroup = schedGroup;
14897            if (!interesting) {
14898                // For this reporting, if there is not something explicitly
14899                // interesting in this process then we will push it to the
14900                // background importance.
14901                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14902            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14903                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14904            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14905                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14906            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14907                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14908            } else if (adj >= ProcessList.SERVICE_ADJ) {
14909                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14910            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14911                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14912            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14913                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14914            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14915                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14916            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14917                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14918            } else {
14919                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14920            }
14921        }
14922
14923        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14924        if (foregroundActivities != app.foregroundActivities) {
14925            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14926        }
14927        if (changes != 0) {
14928            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14929            app.memImportance = importance;
14930            app.foregroundActivities = foregroundActivities;
14931            int i = mPendingProcessChanges.size()-1;
14932            ProcessChangeItem item = null;
14933            while (i >= 0) {
14934                item = mPendingProcessChanges.get(i);
14935                if (item.pid == app.pid) {
14936                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14937                    break;
14938                }
14939                i--;
14940            }
14941            if (i < 0) {
14942                // No existing item in pending changes; need a new one.
14943                final int NA = mAvailProcessChanges.size();
14944                if (NA > 0) {
14945                    item = mAvailProcessChanges.remove(NA-1);
14946                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14947                } else {
14948                    item = new ProcessChangeItem();
14949                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14950                }
14951                item.changes = 0;
14952                item.pid = app.pid;
14953                item.uid = app.info.uid;
14954                if (mPendingProcessChanges.size() == 0) {
14955                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14956                            "*** Enqueueing dispatch processes changed!");
14957                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14958                }
14959                mPendingProcessChanges.add(item);
14960            }
14961            item.changes |= changes;
14962            item.importance = importance;
14963            item.foregroundActivities = foregroundActivities;
14964            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14965                    + Integer.toHexString(System.identityHashCode(item))
14966                    + " " + app.toShortString() + ": changes=" + item.changes
14967                    + " importance=" + item.importance
14968                    + " foreground=" + item.foregroundActivities
14969                    + " type=" + app.adjType + " source=" + app.adjSource
14970                    + " target=" + app.adjTarget);
14971        }
14972
14973        return app.curRawAdj;
14974    }
14975
14976    /**
14977     * Schedule PSS collection of a process.
14978     */
14979    void requestPssLocked(ProcessRecord proc, int procState) {
14980        if (mPendingPssProcesses.contains(proc)) {
14981            return;
14982        }
14983        if (mPendingPssProcesses.size() == 0) {
14984            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14985        }
14986        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14987        proc.pssProcState = procState;
14988        mPendingPssProcesses.add(proc);
14989    }
14990
14991    /**
14992     * Schedule PSS collection of all processes.
14993     */
14994    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14995        if (!always) {
14996            if (now < (mLastFullPssTime +
14997                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14998                return;
14999            }
15000        }
15001        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15002        mLastFullPssTime = now;
15003        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15004        mPendingPssProcesses.clear();
15005        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15006            ProcessRecord app = mLruProcesses.get(i);
15007            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15008                app.pssProcState = app.setProcState;
15009                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15010                        mSleeping, now);
15011                mPendingPssProcesses.add(app);
15012            }
15013        }
15014        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15015    }
15016
15017    /**
15018     * Ask a given process to GC right now.
15019     */
15020    final void performAppGcLocked(ProcessRecord app) {
15021        try {
15022            app.lastRequestedGc = SystemClock.uptimeMillis();
15023            if (app.thread != null) {
15024                if (app.reportLowMemory) {
15025                    app.reportLowMemory = false;
15026                    app.thread.scheduleLowMemory();
15027                } else {
15028                    app.thread.processInBackground();
15029                }
15030            }
15031        } catch (Exception e) {
15032            // whatever.
15033        }
15034    }
15035
15036    /**
15037     * Returns true if things are idle enough to perform GCs.
15038     */
15039    private final boolean canGcNowLocked() {
15040        boolean processingBroadcasts = false;
15041        for (BroadcastQueue q : mBroadcastQueues) {
15042            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15043                processingBroadcasts = true;
15044            }
15045        }
15046        return !processingBroadcasts
15047                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15048    }
15049
15050    /**
15051     * Perform GCs on all processes that are waiting for it, but only
15052     * if things are idle.
15053     */
15054    final void performAppGcsLocked() {
15055        final int N = mProcessesToGc.size();
15056        if (N <= 0) {
15057            return;
15058        }
15059        if (canGcNowLocked()) {
15060            while (mProcessesToGc.size() > 0) {
15061                ProcessRecord proc = mProcessesToGc.remove(0);
15062                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15063                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15064                            <= SystemClock.uptimeMillis()) {
15065                        // To avoid spamming the system, we will GC processes one
15066                        // at a time, waiting a few seconds between each.
15067                        performAppGcLocked(proc);
15068                        scheduleAppGcsLocked();
15069                        return;
15070                    } else {
15071                        // It hasn't been long enough since we last GCed this
15072                        // process...  put it in the list to wait for its time.
15073                        addProcessToGcListLocked(proc);
15074                        break;
15075                    }
15076                }
15077            }
15078
15079            scheduleAppGcsLocked();
15080        }
15081    }
15082
15083    /**
15084     * If all looks good, perform GCs on all processes waiting for them.
15085     */
15086    final void performAppGcsIfAppropriateLocked() {
15087        if (canGcNowLocked()) {
15088            performAppGcsLocked();
15089            return;
15090        }
15091        // Still not idle, wait some more.
15092        scheduleAppGcsLocked();
15093    }
15094
15095    /**
15096     * Schedule the execution of all pending app GCs.
15097     */
15098    final void scheduleAppGcsLocked() {
15099        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15100
15101        if (mProcessesToGc.size() > 0) {
15102            // Schedule a GC for the time to the next process.
15103            ProcessRecord proc = mProcessesToGc.get(0);
15104            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15105
15106            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15107            long now = SystemClock.uptimeMillis();
15108            if (when < (now+GC_TIMEOUT)) {
15109                when = now + GC_TIMEOUT;
15110            }
15111            mHandler.sendMessageAtTime(msg, when);
15112        }
15113    }
15114
15115    /**
15116     * Add a process to the array of processes waiting to be GCed.  Keeps the
15117     * list in sorted order by the last GC time.  The process can't already be
15118     * on the list.
15119     */
15120    final void addProcessToGcListLocked(ProcessRecord proc) {
15121        boolean added = false;
15122        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15123            if (mProcessesToGc.get(i).lastRequestedGc <
15124                    proc.lastRequestedGc) {
15125                added = true;
15126                mProcessesToGc.add(i+1, proc);
15127                break;
15128            }
15129        }
15130        if (!added) {
15131            mProcessesToGc.add(0, proc);
15132        }
15133    }
15134
15135    /**
15136     * Set up to ask a process to GC itself.  This will either do it
15137     * immediately, or put it on the list of processes to gc the next
15138     * time things are idle.
15139     */
15140    final void scheduleAppGcLocked(ProcessRecord app) {
15141        long now = SystemClock.uptimeMillis();
15142        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15143            return;
15144        }
15145        if (!mProcessesToGc.contains(app)) {
15146            addProcessToGcListLocked(app);
15147            scheduleAppGcsLocked();
15148        }
15149    }
15150
15151    final void checkExcessivePowerUsageLocked(boolean doKills) {
15152        updateCpuStatsNow();
15153
15154        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15155        boolean doWakeKills = doKills;
15156        boolean doCpuKills = doKills;
15157        if (mLastPowerCheckRealtime == 0) {
15158            doWakeKills = false;
15159        }
15160        if (mLastPowerCheckUptime == 0) {
15161            doCpuKills = false;
15162        }
15163        if (stats.isScreenOn()) {
15164            doWakeKills = false;
15165        }
15166        final long curRealtime = SystemClock.elapsedRealtime();
15167        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15168        final long curUptime = SystemClock.uptimeMillis();
15169        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15170        mLastPowerCheckRealtime = curRealtime;
15171        mLastPowerCheckUptime = curUptime;
15172        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15173            doWakeKills = false;
15174        }
15175        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15176            doCpuKills = false;
15177        }
15178        int i = mLruProcesses.size();
15179        while (i > 0) {
15180            i--;
15181            ProcessRecord app = mLruProcesses.get(i);
15182            if (!app.keeping) {
15183                long wtime;
15184                synchronized (stats) {
15185                    wtime = stats.getProcessWakeTime(app.info.uid,
15186                            app.pid, curRealtime);
15187                }
15188                long wtimeUsed = wtime - app.lastWakeTime;
15189                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15190                if (DEBUG_POWER) {
15191                    StringBuilder sb = new StringBuilder(128);
15192                    sb.append("Wake for ");
15193                    app.toShortString(sb);
15194                    sb.append(": over ");
15195                    TimeUtils.formatDuration(realtimeSince, sb);
15196                    sb.append(" used ");
15197                    TimeUtils.formatDuration(wtimeUsed, sb);
15198                    sb.append(" (");
15199                    sb.append((wtimeUsed*100)/realtimeSince);
15200                    sb.append("%)");
15201                    Slog.i(TAG, sb.toString());
15202                    sb.setLength(0);
15203                    sb.append("CPU for ");
15204                    app.toShortString(sb);
15205                    sb.append(": over ");
15206                    TimeUtils.formatDuration(uptimeSince, sb);
15207                    sb.append(" used ");
15208                    TimeUtils.formatDuration(cputimeUsed, sb);
15209                    sb.append(" (");
15210                    sb.append((cputimeUsed*100)/uptimeSince);
15211                    sb.append("%)");
15212                    Slog.i(TAG, sb.toString());
15213                }
15214                // If a process has held a wake lock for more
15215                // than 50% of the time during this period,
15216                // that sounds bad.  Kill!
15217                if (doWakeKills && realtimeSince > 0
15218                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15219                    synchronized (stats) {
15220                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15221                                realtimeSince, wtimeUsed);
15222                    }
15223                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15224                            + " during " + realtimeSince);
15225                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15226                } else if (doCpuKills && uptimeSince > 0
15227                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15228                    synchronized (stats) {
15229                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15230                                uptimeSince, cputimeUsed);
15231                    }
15232                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15233                            + " during " + uptimeSince);
15234                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15235                } else {
15236                    app.lastWakeTime = wtime;
15237                    app.lastCpuTime = app.curCpuTime;
15238                }
15239            }
15240        }
15241    }
15242
15243    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15244            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15245        boolean success = true;
15246
15247        if (app.curRawAdj != app.setRawAdj) {
15248            if (wasKeeping && !app.keeping) {
15249                // This app is no longer something we want to keep.  Note
15250                // its current wake lock time to later know to kill it if
15251                // it is not behaving well.
15252                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15253                synchronized (stats) {
15254                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15255                            app.pid, SystemClock.elapsedRealtime());
15256                }
15257                app.lastCpuTime = app.curCpuTime;
15258            }
15259
15260            app.setRawAdj = app.curRawAdj;
15261        }
15262
15263        if (app.curAdj != app.setAdj) {
15264            ProcessList.setOomAdj(app.pid, app.curAdj);
15265            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15266                TAG, "Set " + app.pid + " " + app.processName +
15267                " adj " + app.curAdj + ": " + app.adjType);
15268            app.setAdj = app.curAdj;
15269        }
15270
15271        if (app.setSchedGroup != app.curSchedGroup) {
15272            app.setSchedGroup = app.curSchedGroup;
15273            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15274                    "Setting process group of " + app.processName
15275                    + " to " + app.curSchedGroup);
15276            if (app.waitingToKill != null &&
15277                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15278                killUnneededProcessLocked(app, app.waitingToKill);
15279                success = false;
15280            } else {
15281                if (true) {
15282                    long oldId = Binder.clearCallingIdentity();
15283                    try {
15284                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15285                    } catch (Exception e) {
15286                        Slog.w(TAG, "Failed setting process group of " + app.pid
15287                                + " to " + app.curSchedGroup);
15288                        e.printStackTrace();
15289                    } finally {
15290                        Binder.restoreCallingIdentity(oldId);
15291                    }
15292                } else {
15293                    if (app.thread != null) {
15294                        try {
15295                            app.thread.setSchedulingGroup(app.curSchedGroup);
15296                        } catch (RemoteException e) {
15297                        }
15298                    }
15299                }
15300                Process.setSwappiness(app.pid,
15301                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15302            }
15303        }
15304        if (app.repProcState != app.curProcState) {
15305            app.repProcState = app.curProcState;
15306            if (!reportingProcessState && app.thread != null) {
15307                try {
15308                    if (false) {
15309                        //RuntimeException h = new RuntimeException("here");
15310                        Slog.i(TAG, "Sending new process state " + app.repProcState
15311                                + " to " + app /*, h*/);
15312                    }
15313                    app.thread.setProcessState(app.repProcState);
15314                } catch (RemoteException e) {
15315                }
15316            }
15317        }
15318        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15319                app.setProcState)) {
15320            app.lastStateTime = now;
15321            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15322                    mSleeping, now);
15323            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15324                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15325                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15326                    + (app.nextPssTime-now) + ": " + app);
15327        } else {
15328            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15329                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15330                requestPssLocked(app, app.setProcState);
15331                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15332                        mSleeping, now);
15333            } else if (false && DEBUG_PSS) {
15334                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15335            }
15336        }
15337        if (app.setProcState != app.curProcState) {
15338            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15339                    "Proc state change of " + app.processName
15340                    + " to " + app.curProcState);
15341            app.setProcState = app.curProcState;
15342            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15343                app.notCachedSinceIdle = false;
15344            }
15345            if (!doingAll) {
15346                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15347            } else {
15348                app.procStateChanged = true;
15349            }
15350        }
15351        return success;
15352    }
15353
15354    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15355        if (proc.thread != null && proc.baseProcessTracker != null) {
15356            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15357        }
15358    }
15359
15360    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15361            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15362        if (app.thread == null) {
15363            return false;
15364        }
15365
15366        final boolean wasKeeping = app.keeping;
15367
15368        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15369
15370        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15371                reportingProcessState, now);
15372    }
15373
15374    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15375            boolean oomAdj) {
15376        if (isForeground != proc.foregroundServices) {
15377            proc.foregroundServices = isForeground;
15378            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15379                    proc.info.uid);
15380            if (isForeground) {
15381                if (curProcs == null) {
15382                    curProcs = new ArrayList<ProcessRecord>();
15383                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15384                }
15385                if (!curProcs.contains(proc)) {
15386                    curProcs.add(proc);
15387                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15388                            proc.info.packageName, proc.info.uid);
15389                }
15390            } else {
15391                if (curProcs != null) {
15392                    if (curProcs.remove(proc)) {
15393                        mBatteryStatsService.noteEvent(
15394                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15395                                proc.info.packageName, proc.info.uid);
15396                        if (curProcs.size() <= 0) {
15397                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15398                        }
15399                    }
15400                }
15401            }
15402            if (oomAdj) {
15403                updateOomAdjLocked();
15404            }
15405        }
15406    }
15407
15408    private final ActivityRecord resumedAppLocked() {
15409        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15410        String pkg;
15411        int uid;
15412        if (act != null) {
15413            pkg = act.packageName;
15414            uid = act.info.applicationInfo.uid;
15415        } else {
15416            pkg = null;
15417            uid = -1;
15418        }
15419        // Has the UID or resumed package name changed?
15420        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15421                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15422            if (mCurResumedPackage != null) {
15423                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15424                        mCurResumedPackage, mCurResumedUid);
15425            }
15426            mCurResumedPackage = pkg;
15427            mCurResumedUid = uid;
15428            if (mCurResumedPackage != null) {
15429                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15430                        mCurResumedPackage, mCurResumedUid);
15431            }
15432        }
15433        return act;
15434    }
15435
15436    final boolean updateOomAdjLocked(ProcessRecord app) {
15437        return updateOomAdjLocked(app, false);
15438    }
15439
15440    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15441        final ActivityRecord TOP_ACT = resumedAppLocked();
15442        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15443        final boolean wasCached = app.cached;
15444
15445        mAdjSeq++;
15446
15447        // This is the desired cached adjusment we want to tell it to use.
15448        // If our app is currently cached, we know it, and that is it.  Otherwise,
15449        // we don't know it yet, and it needs to now be cached we will then
15450        // need to do a complete oom adj.
15451        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15452                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15453        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15454                SystemClock.uptimeMillis());
15455        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15456            // Changed to/from cached state, so apps after it in the LRU
15457            // list may also be changed.
15458            updateOomAdjLocked();
15459        }
15460        return success;
15461    }
15462
15463    final void updateOomAdjLocked() {
15464        final ActivityRecord TOP_ACT = resumedAppLocked();
15465        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15466        final long now = SystemClock.uptimeMillis();
15467        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15468        final int N = mLruProcesses.size();
15469
15470        if (false) {
15471            RuntimeException e = new RuntimeException();
15472            e.fillInStackTrace();
15473            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15474        }
15475
15476        mAdjSeq++;
15477        mNewNumServiceProcs = 0;
15478        mNewNumAServiceProcs = 0;
15479
15480        final int emptyProcessLimit;
15481        final int cachedProcessLimit;
15482        if (mProcessLimit <= 0) {
15483            emptyProcessLimit = cachedProcessLimit = 0;
15484        } else if (mProcessLimit == 1) {
15485            emptyProcessLimit = 1;
15486            cachedProcessLimit = 0;
15487        } else {
15488            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15489            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15490        }
15491
15492        // Let's determine how many processes we have running vs.
15493        // how many slots we have for background processes; we may want
15494        // to put multiple processes in a slot of there are enough of
15495        // them.
15496        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15497                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15498        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15499        if (numEmptyProcs > cachedProcessLimit) {
15500            // If there are more empty processes than our limit on cached
15501            // processes, then use the cached process limit for the factor.
15502            // This ensures that the really old empty processes get pushed
15503            // down to the bottom, so if we are running low on memory we will
15504            // have a better chance at keeping around more cached processes
15505            // instead of a gazillion empty processes.
15506            numEmptyProcs = cachedProcessLimit;
15507        }
15508        int emptyFactor = numEmptyProcs/numSlots;
15509        if (emptyFactor < 1) emptyFactor = 1;
15510        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15511        if (cachedFactor < 1) cachedFactor = 1;
15512        int stepCached = 0;
15513        int stepEmpty = 0;
15514        int numCached = 0;
15515        int numEmpty = 0;
15516        int numTrimming = 0;
15517
15518        mNumNonCachedProcs = 0;
15519        mNumCachedHiddenProcs = 0;
15520
15521        // First update the OOM adjustment for each of the
15522        // application processes based on their current state.
15523        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15524        int nextCachedAdj = curCachedAdj+1;
15525        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15526        int nextEmptyAdj = curEmptyAdj+2;
15527        for (int i=N-1; i>=0; i--) {
15528            ProcessRecord app = mLruProcesses.get(i);
15529            if (!app.killedByAm && app.thread != null) {
15530                app.procStateChanged = false;
15531                final boolean wasKeeping = app.keeping;
15532                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15533
15534                // If we haven't yet assigned the final cached adj
15535                // to the process, do that now.
15536                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15537                    switch (app.curProcState) {
15538                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15539                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15540                            // This process is a cached process holding activities...
15541                            // assign it the next cached value for that type, and then
15542                            // step that cached level.
15543                            app.curRawAdj = curCachedAdj;
15544                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15545                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15546                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15547                                    + ")");
15548                            if (curCachedAdj != nextCachedAdj) {
15549                                stepCached++;
15550                                if (stepCached >= cachedFactor) {
15551                                    stepCached = 0;
15552                                    curCachedAdj = nextCachedAdj;
15553                                    nextCachedAdj += 2;
15554                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15555                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15556                                    }
15557                                }
15558                            }
15559                            break;
15560                        default:
15561                            // For everything else, assign next empty cached process
15562                            // level and bump that up.  Note that this means that
15563                            // long-running services that have dropped down to the
15564                            // cached level will be treated as empty (since their process
15565                            // state is still as a service), which is what we want.
15566                            app.curRawAdj = curEmptyAdj;
15567                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15568                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15569                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15570                                    + ")");
15571                            if (curEmptyAdj != nextEmptyAdj) {
15572                                stepEmpty++;
15573                                if (stepEmpty >= emptyFactor) {
15574                                    stepEmpty = 0;
15575                                    curEmptyAdj = nextEmptyAdj;
15576                                    nextEmptyAdj += 2;
15577                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15578                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15579                                    }
15580                                }
15581                            }
15582                            break;
15583                    }
15584                }
15585
15586                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15587
15588                // Count the number of process types.
15589                switch (app.curProcState) {
15590                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15591                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15592                        mNumCachedHiddenProcs++;
15593                        numCached++;
15594                        if (numCached > cachedProcessLimit) {
15595                            killUnneededProcessLocked(app, "cached #" + numCached);
15596                        }
15597                        break;
15598                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15599                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15600                                && app.lastActivityTime < oldTime) {
15601                            killUnneededProcessLocked(app, "empty for "
15602                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15603                                    / 1000) + "s");
15604                        } else {
15605                            numEmpty++;
15606                            if (numEmpty > emptyProcessLimit) {
15607                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15608                            }
15609                        }
15610                        break;
15611                    default:
15612                        mNumNonCachedProcs++;
15613                        break;
15614                }
15615
15616                if (app.isolated && app.services.size() <= 0) {
15617                    // If this is an isolated process, and there are no
15618                    // services running in it, then the process is no longer
15619                    // needed.  We agressively kill these because we can by
15620                    // definition not re-use the same process again, and it is
15621                    // good to avoid having whatever code was running in them
15622                    // left sitting around after no longer needed.
15623                    killUnneededProcessLocked(app, "isolated not needed");
15624                }
15625
15626                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15627                        && !app.killedByAm) {
15628                    numTrimming++;
15629                }
15630            }
15631        }
15632
15633        mNumServiceProcs = mNewNumServiceProcs;
15634
15635        // Now determine the memory trimming level of background processes.
15636        // Unfortunately we need to start at the back of the list to do this
15637        // properly.  We only do this if the number of background apps we
15638        // are managing to keep around is less than half the maximum we desire;
15639        // if we are keeping a good number around, we'll let them use whatever
15640        // memory they want.
15641        final int numCachedAndEmpty = numCached + numEmpty;
15642        int memFactor;
15643        if (numCached <= ProcessList.TRIM_CACHED_APPS
15644                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15645            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15646                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15647            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15648                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15649            } else {
15650                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15651            }
15652        } else {
15653            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15654        }
15655        // We always allow the memory level to go up (better).  We only allow it to go
15656        // down if we are in a state where that is allowed, *and* the total number of processes
15657        // has gone down since last time.
15658        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15659                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15660                + " last=" + mLastNumProcesses);
15661        if (memFactor > mLastMemoryLevel) {
15662            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15663                memFactor = mLastMemoryLevel;
15664                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15665            }
15666        }
15667        mLastMemoryLevel = memFactor;
15668        mLastNumProcesses = mLruProcesses.size();
15669        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15670        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15671        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15672            if (mLowRamStartTime == 0) {
15673                mLowRamStartTime = now;
15674            }
15675            int step = 0;
15676            int fgTrimLevel;
15677            switch (memFactor) {
15678                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15679                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15680                    break;
15681                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15682                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15683                    break;
15684                default:
15685                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15686                    break;
15687            }
15688            int factor = numTrimming/3;
15689            int minFactor = 2;
15690            if (mHomeProcess != null) minFactor++;
15691            if (mPreviousProcess != null) minFactor++;
15692            if (factor < minFactor) factor = minFactor;
15693            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15694            for (int i=N-1; i>=0; i--) {
15695                ProcessRecord app = mLruProcesses.get(i);
15696                if (allChanged || app.procStateChanged) {
15697                    setProcessTrackerState(app, trackerMemFactor, now);
15698                    app.procStateChanged = false;
15699                }
15700                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15701                        && !app.killedByAm) {
15702                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15703                        try {
15704                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15705                                    "Trimming memory of " + app.processName
15706                                    + " to " + curLevel);
15707                            app.thread.scheduleTrimMemory(curLevel);
15708                        } catch (RemoteException e) {
15709                        }
15710                        if (false) {
15711                            // For now we won't do this; our memory trimming seems
15712                            // to be good enough at this point that destroying
15713                            // activities causes more harm than good.
15714                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15715                                    && app != mHomeProcess && app != mPreviousProcess) {
15716                                // Need to do this on its own message because the stack may not
15717                                // be in a consistent state at this point.
15718                                // For these apps we will also finish their activities
15719                                // to help them free memory.
15720                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15721                            }
15722                        }
15723                    }
15724                    app.trimMemoryLevel = curLevel;
15725                    step++;
15726                    if (step >= factor) {
15727                        step = 0;
15728                        switch (curLevel) {
15729                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15730                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15731                                break;
15732                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15733                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15734                                break;
15735                        }
15736                    }
15737                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15738                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15739                            && app.thread != null) {
15740                        try {
15741                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15742                                    "Trimming memory of heavy-weight " + app.processName
15743                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15744                            app.thread.scheduleTrimMemory(
15745                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15746                        } catch (RemoteException e) {
15747                        }
15748                    }
15749                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15750                } else {
15751                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15752                            || app.systemNoUi) && app.pendingUiClean) {
15753                        // If this application is now in the background and it
15754                        // had done UI, then give it the special trim level to
15755                        // have it free UI resources.
15756                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15757                        if (app.trimMemoryLevel < level && app.thread != null) {
15758                            try {
15759                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15760                                        "Trimming memory of bg-ui " + app.processName
15761                                        + " to " + level);
15762                                app.thread.scheduleTrimMemory(level);
15763                            } catch (RemoteException e) {
15764                            }
15765                        }
15766                        app.pendingUiClean = false;
15767                    }
15768                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15769                        try {
15770                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15771                                    "Trimming memory of fg " + app.processName
15772                                    + " to " + fgTrimLevel);
15773                            app.thread.scheduleTrimMemory(fgTrimLevel);
15774                        } catch (RemoteException e) {
15775                        }
15776                    }
15777                    app.trimMemoryLevel = fgTrimLevel;
15778                }
15779            }
15780        } else {
15781            if (mLowRamStartTime != 0) {
15782                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15783                mLowRamStartTime = 0;
15784            }
15785            for (int i=N-1; i>=0; i--) {
15786                ProcessRecord app = mLruProcesses.get(i);
15787                if (allChanged || app.procStateChanged) {
15788                    setProcessTrackerState(app, trackerMemFactor, now);
15789                    app.procStateChanged = false;
15790                }
15791                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15792                        || app.systemNoUi) && app.pendingUiClean) {
15793                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15794                            && app.thread != null) {
15795                        try {
15796                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15797                                    "Trimming memory of ui hidden " + app.processName
15798                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15799                            app.thread.scheduleTrimMemory(
15800                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15801                        } catch (RemoteException e) {
15802                        }
15803                    }
15804                    app.pendingUiClean = false;
15805                }
15806                app.trimMemoryLevel = 0;
15807            }
15808        }
15809
15810        if (mAlwaysFinishActivities) {
15811            // Need to do this on its own message because the stack may not
15812            // be in a consistent state at this point.
15813            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15814        }
15815
15816        if (allChanged) {
15817            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15818        }
15819
15820        if (mProcessStats.shouldWriteNowLocked(now)) {
15821            mHandler.post(new Runnable() {
15822                @Override public void run() {
15823                    synchronized (ActivityManagerService.this) {
15824                        mProcessStats.writeStateAsyncLocked();
15825                    }
15826                }
15827            });
15828        }
15829
15830        if (DEBUG_OOM_ADJ) {
15831            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15832        }
15833    }
15834
15835    final void trimApplications() {
15836        synchronized (this) {
15837            int i;
15838
15839            // First remove any unused application processes whose package
15840            // has been removed.
15841            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15842                final ProcessRecord app = mRemovedProcesses.get(i);
15843                if (app.activities.size() == 0
15844                        && app.curReceiver == null && app.services.size() == 0) {
15845                    Slog.i(
15846                        TAG, "Exiting empty application process "
15847                        + app.processName + " ("
15848                        + (app.thread != null ? app.thread.asBinder() : null)
15849                        + ")\n");
15850                    if (app.pid > 0 && app.pid != MY_PID) {
15851                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15852                                app.processName, app.setAdj, "empty");
15853                        app.killedByAm = true;
15854                        Process.killProcessQuiet(app.pid);
15855                    } else {
15856                        try {
15857                            app.thread.scheduleExit();
15858                        } catch (Exception e) {
15859                            // Ignore exceptions.
15860                        }
15861                    }
15862                    cleanUpApplicationRecordLocked(app, false, true, -1);
15863                    mRemovedProcesses.remove(i);
15864
15865                    if (app.persistent) {
15866                        if (app.persistent) {
15867                            addAppLocked(app.info, false);
15868                        }
15869                    }
15870                }
15871            }
15872
15873            // Now update the oom adj for all processes.
15874            updateOomAdjLocked();
15875        }
15876    }
15877
15878    /** This method sends the specified signal to each of the persistent apps */
15879    public void signalPersistentProcesses(int sig) throws RemoteException {
15880        if (sig != Process.SIGNAL_USR1) {
15881            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15882        }
15883
15884        synchronized (this) {
15885            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15886                    != PackageManager.PERMISSION_GRANTED) {
15887                throw new SecurityException("Requires permission "
15888                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15889            }
15890
15891            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15892                ProcessRecord r = mLruProcesses.get(i);
15893                if (r.thread != null && r.persistent) {
15894                    Process.sendSignal(r.pid, sig);
15895                }
15896            }
15897        }
15898    }
15899
15900    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15901        if (proc == null || proc == mProfileProc) {
15902            proc = mProfileProc;
15903            path = mProfileFile;
15904            profileType = mProfileType;
15905            clearProfilerLocked();
15906        }
15907        if (proc == null) {
15908            return;
15909        }
15910        try {
15911            proc.thread.profilerControl(false, path, null, profileType);
15912        } catch (RemoteException e) {
15913            throw new IllegalStateException("Process disappeared");
15914        }
15915    }
15916
15917    private void clearProfilerLocked() {
15918        if (mProfileFd != null) {
15919            try {
15920                mProfileFd.close();
15921            } catch (IOException e) {
15922            }
15923        }
15924        mProfileApp = null;
15925        mProfileProc = null;
15926        mProfileFile = null;
15927        mProfileType = 0;
15928        mAutoStopProfiler = false;
15929    }
15930
15931    public boolean profileControl(String process, int userId, boolean start,
15932            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15933
15934        try {
15935            synchronized (this) {
15936                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15937                // its own permission.
15938                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15939                        != PackageManager.PERMISSION_GRANTED) {
15940                    throw new SecurityException("Requires permission "
15941                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15942                }
15943
15944                if (start && fd == null) {
15945                    throw new IllegalArgumentException("null fd");
15946                }
15947
15948                ProcessRecord proc = null;
15949                if (process != null) {
15950                    proc = findProcessLocked(process, userId, "profileControl");
15951                }
15952
15953                if (start && (proc == null || proc.thread == null)) {
15954                    throw new IllegalArgumentException("Unknown process: " + process);
15955                }
15956
15957                if (start) {
15958                    stopProfilerLocked(null, null, 0);
15959                    setProfileApp(proc.info, proc.processName, path, fd, false);
15960                    mProfileProc = proc;
15961                    mProfileType = profileType;
15962                    try {
15963                        fd = fd.dup();
15964                    } catch (IOException e) {
15965                        fd = null;
15966                    }
15967                    proc.thread.profilerControl(start, path, fd, profileType);
15968                    fd = null;
15969                    mProfileFd = null;
15970                } else {
15971                    stopProfilerLocked(proc, path, profileType);
15972                    if (fd != null) {
15973                        try {
15974                            fd.close();
15975                        } catch (IOException e) {
15976                        }
15977                    }
15978                }
15979
15980                return true;
15981            }
15982        } catch (RemoteException e) {
15983            throw new IllegalStateException("Process disappeared");
15984        } finally {
15985            if (fd != null) {
15986                try {
15987                    fd.close();
15988                } catch (IOException e) {
15989                }
15990            }
15991        }
15992    }
15993
15994    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15995        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15996                userId, true, true, callName, null);
15997        ProcessRecord proc = null;
15998        try {
15999            int pid = Integer.parseInt(process);
16000            synchronized (mPidsSelfLocked) {
16001                proc = mPidsSelfLocked.get(pid);
16002            }
16003        } catch (NumberFormatException e) {
16004        }
16005
16006        if (proc == null) {
16007            ArrayMap<String, SparseArray<ProcessRecord>> all
16008                    = mProcessNames.getMap();
16009            SparseArray<ProcessRecord> procs = all.get(process);
16010            if (procs != null && procs.size() > 0) {
16011                proc = procs.valueAt(0);
16012                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16013                    for (int i=1; i<procs.size(); i++) {
16014                        ProcessRecord thisProc = procs.valueAt(i);
16015                        if (thisProc.userId == userId) {
16016                            proc = thisProc;
16017                            break;
16018                        }
16019                    }
16020                }
16021            }
16022        }
16023
16024        return proc;
16025    }
16026
16027    public boolean dumpHeap(String process, int userId, boolean managed,
16028            String path, ParcelFileDescriptor fd) throws RemoteException {
16029
16030        try {
16031            synchronized (this) {
16032                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16033                // its own permission (same as profileControl).
16034                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16035                        != PackageManager.PERMISSION_GRANTED) {
16036                    throw new SecurityException("Requires permission "
16037                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16038                }
16039
16040                if (fd == null) {
16041                    throw new IllegalArgumentException("null fd");
16042                }
16043
16044                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16045                if (proc == null || proc.thread == null) {
16046                    throw new IllegalArgumentException("Unknown process: " + process);
16047                }
16048
16049                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16050                if (!isDebuggable) {
16051                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16052                        throw new SecurityException("Process not debuggable: " + proc);
16053                    }
16054                }
16055
16056                proc.thread.dumpHeap(managed, path, fd);
16057                fd = null;
16058                return true;
16059            }
16060        } catch (RemoteException e) {
16061            throw new IllegalStateException("Process disappeared");
16062        } finally {
16063            if (fd != null) {
16064                try {
16065                    fd.close();
16066                } catch (IOException e) {
16067                }
16068            }
16069        }
16070    }
16071
16072    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16073    public void monitor() {
16074        synchronized (this) { }
16075    }
16076
16077    void onCoreSettingsChange(Bundle settings) {
16078        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16079            ProcessRecord processRecord = mLruProcesses.get(i);
16080            try {
16081                if (processRecord.thread != null) {
16082                    processRecord.thread.setCoreSettings(settings);
16083                }
16084            } catch (RemoteException re) {
16085                /* ignore */
16086            }
16087        }
16088    }
16089
16090    // Multi-user methods
16091
16092    /**
16093     * Start user, if its not already running, but don't bring it to foreground.
16094     */
16095    @Override
16096    public boolean startUserInBackground(final int userId) {
16097        return startUser(userId, /* foreground */ false);
16098    }
16099
16100    @Override
16101    public boolean switchUser(final int userId) {
16102        return startUser(userId, /* foregound */ true);
16103    }
16104
16105    private boolean startUser(final int userId, boolean foreground) {
16106        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16107                != PackageManager.PERMISSION_GRANTED) {
16108            String msg = "Permission Denial: switchUser() from pid="
16109                    + Binder.getCallingPid()
16110                    + ", uid=" + Binder.getCallingUid()
16111                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16112            Slog.w(TAG, msg);
16113            throw new SecurityException(msg);
16114        }
16115
16116        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16117
16118        final long ident = Binder.clearCallingIdentity();
16119        try {
16120            synchronized (this) {
16121                final int oldUserId = mCurrentUserId;
16122                if (oldUserId == userId) {
16123                    return true;
16124                }
16125
16126                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16127                if (userInfo == null) {
16128                    Slog.w(TAG, "No user info for user #" + userId);
16129                    return false;
16130                }
16131
16132                if (foreground) {
16133                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16134                            R.anim.screen_user_enter);
16135                }
16136
16137                boolean needStart = false;
16138
16139                // If the user we are switching to is not currently started, then
16140                // we need to start it now.
16141                if (mStartedUsers.get(userId) == null) {
16142                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16143                    updateStartedUserArrayLocked();
16144                    needStart = true;
16145                }
16146
16147                final Integer userIdInt = Integer.valueOf(userId);
16148                mUserLru.remove(userIdInt);
16149                mUserLru.add(userIdInt);
16150
16151                if (foreground) {
16152                    mCurrentUserId = userId;
16153                    mWindowManager.setCurrentUser(userId);
16154                    // Once the internal notion of the active user has switched, we lock the device
16155                    // with the option to show the user switcher on the keyguard.
16156                    mWindowManager.lockNow(null);
16157                } else {
16158                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16159                    mUserLru.remove(currentUserIdInt);
16160                    mUserLru.add(currentUserIdInt);
16161                }
16162
16163                final UserStartedState uss = mStartedUsers.get(userId);
16164
16165                // Make sure user is in the started state.  If it is currently
16166                // stopping, we need to knock that off.
16167                if (uss.mState == UserStartedState.STATE_STOPPING) {
16168                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16169                    // so we can just fairly silently bring the user back from
16170                    // the almost-dead.
16171                    uss.mState = UserStartedState.STATE_RUNNING;
16172                    updateStartedUserArrayLocked();
16173                    needStart = true;
16174                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16175                    // This means ACTION_SHUTDOWN has been sent, so we will
16176                    // need to treat this as a new boot of the user.
16177                    uss.mState = UserStartedState.STATE_BOOTING;
16178                    updateStartedUserArrayLocked();
16179                    needStart = true;
16180                }
16181
16182                if (foreground) {
16183                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16184                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16185                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16186                            oldUserId, userId, uss));
16187                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16188                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16189                }
16190
16191                if (needStart) {
16192                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16193                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16194                            | Intent.FLAG_RECEIVER_FOREGROUND);
16195                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16196                    broadcastIntentLocked(null, null, intent,
16197                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16198                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16199                }
16200
16201                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16202                    if (userId != 0) {
16203                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16204                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16205                        broadcastIntentLocked(null, null, intent, null,
16206                                new IIntentReceiver.Stub() {
16207                                    public void performReceive(Intent intent, int resultCode,
16208                                            String data, Bundle extras, boolean ordered,
16209                                            boolean sticky, int sendingUser) {
16210                                        userInitialized(uss, userId);
16211                                    }
16212                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16213                                true, false, MY_PID, Process.SYSTEM_UID,
16214                                userId);
16215                        uss.initializing = true;
16216                    } else {
16217                        getUserManagerLocked().makeInitialized(userInfo.id);
16218                    }
16219                }
16220
16221                if (foreground) {
16222                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16223                    if (homeInFront) {
16224                        startHomeActivityLocked(userId);
16225                    } else {
16226                        mStackSupervisor.resumeTopActivitiesLocked();
16227                    }
16228                    EventLogTags.writeAmSwitchUser(userId);
16229                    getUserManagerLocked().userForeground(userId);
16230                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16231                }
16232
16233                if (needStart) {
16234                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16235                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16236                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16237                    broadcastIntentLocked(null, null, intent,
16238                            null, new IIntentReceiver.Stub() {
16239                                @Override
16240                                public void performReceive(Intent intent, int resultCode, String data,
16241                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16242                                        throws RemoteException {
16243                                }
16244                            }, 0, null, null,
16245                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16246                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16247                }
16248            }
16249        } finally {
16250            Binder.restoreCallingIdentity(ident);
16251        }
16252
16253        return true;
16254    }
16255
16256    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16257        long ident = Binder.clearCallingIdentity();
16258        try {
16259            Intent intent;
16260            if (oldUserId >= 0) {
16261                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16262                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16263                        | Intent.FLAG_RECEIVER_FOREGROUND);
16264                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16265                broadcastIntentLocked(null, null, intent,
16266                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16267                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16268            }
16269            if (newUserId >= 0) {
16270                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16271                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16272                        | Intent.FLAG_RECEIVER_FOREGROUND);
16273                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16274                broadcastIntentLocked(null, null, intent,
16275                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16276                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16277                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16278                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16279                        | Intent.FLAG_RECEIVER_FOREGROUND);
16280                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16281                broadcastIntentLocked(null, null, intent,
16282                        null, null, 0, null, null,
16283                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16284                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16285            }
16286        } finally {
16287            Binder.restoreCallingIdentity(ident);
16288        }
16289    }
16290
16291    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16292            final int newUserId) {
16293        final int N = mUserSwitchObservers.beginBroadcast();
16294        if (N > 0) {
16295            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16296                int mCount = 0;
16297                @Override
16298                public void sendResult(Bundle data) throws RemoteException {
16299                    synchronized (ActivityManagerService.this) {
16300                        if (mCurUserSwitchCallback == this) {
16301                            mCount++;
16302                            if (mCount == N) {
16303                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16304                            }
16305                        }
16306                    }
16307                }
16308            };
16309            synchronized (this) {
16310                uss.switching = true;
16311                mCurUserSwitchCallback = callback;
16312            }
16313            for (int i=0; i<N; i++) {
16314                try {
16315                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16316                            newUserId, callback);
16317                } catch (RemoteException e) {
16318                }
16319            }
16320        } else {
16321            synchronized (this) {
16322                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16323            }
16324        }
16325        mUserSwitchObservers.finishBroadcast();
16326    }
16327
16328    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16329        synchronized (this) {
16330            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16331            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16332        }
16333    }
16334
16335    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16336        mCurUserSwitchCallback = null;
16337        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16338        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16339                oldUserId, newUserId, uss));
16340    }
16341
16342    void userInitialized(UserStartedState uss, int newUserId) {
16343        completeSwitchAndInitalize(uss, newUserId, true, false);
16344    }
16345
16346    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16347        completeSwitchAndInitalize(uss, newUserId, false, true);
16348    }
16349
16350    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16351            boolean clearInitializing, boolean clearSwitching) {
16352        boolean unfrozen = false;
16353        synchronized (this) {
16354            if (clearInitializing) {
16355                uss.initializing = false;
16356                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16357            }
16358            if (clearSwitching) {
16359                uss.switching = false;
16360            }
16361            if (!uss.switching && !uss.initializing) {
16362                mWindowManager.stopFreezingScreen();
16363                unfrozen = true;
16364            }
16365        }
16366        if (unfrozen) {
16367            final int N = mUserSwitchObservers.beginBroadcast();
16368            for (int i=0; i<N; i++) {
16369                try {
16370                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16371                } catch (RemoteException e) {
16372                }
16373            }
16374            mUserSwitchObservers.finishBroadcast();
16375        }
16376    }
16377
16378    void scheduleStartRelatedUsersLocked() {
16379        if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) {
16380            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG),
16381                    DateUtils.SECOND_IN_MILLIS);
16382        }
16383    }
16384
16385    void startRelatedUsersLocked() {
16386        if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked");
16387        List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16388        List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size());
16389        for (UserInfo relatedUser : relatedUsers) {
16390            if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) {
16391                toStart.add(relatedUser);
16392            }
16393        }
16394        final int n = toStart.size();
16395        int i = 0;
16396        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16397            startUserInBackground(toStart.get(i).id);
16398        }
16399        if (i < n) {
16400            Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS");
16401        }
16402    }
16403
16404    void finishUserSwitch(UserStartedState uss) {
16405        synchronized (this) {
16406            if (uss.mState == UserStartedState.STATE_BOOTING
16407                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16408                uss.mState = UserStartedState.STATE_RUNNING;
16409                final int userId = uss.mHandle.getIdentifier();
16410                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16411                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16412                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16413                broadcastIntentLocked(null, null, intent,
16414                        null, null, 0, null, null,
16415                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16416                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16417            }
16418
16419            startRelatedUsersLocked();
16420
16421            int num = mUserLru.size();
16422            int i = 0;
16423            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16424                Integer oldUserId = mUserLru.get(i);
16425                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16426                if (oldUss == null) {
16427                    // Shouldn't happen, but be sane if it does.
16428                    mUserLru.remove(i);
16429                    num--;
16430                    continue;
16431                }
16432                if (oldUss.mState == UserStartedState.STATE_STOPPING
16433                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16434                    // This user is already stopping, doesn't count.
16435                    num--;
16436                    i++;
16437                    continue;
16438                }
16439                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16440                    // Owner and current can't be stopped, but count as running.
16441                    i++;
16442                    continue;
16443                }
16444                // This is a user to be stopped.
16445                stopUserLocked(oldUserId, null);
16446                num--;
16447                i++;
16448            }
16449        }
16450    }
16451
16452    @Override
16453    public int stopUser(final int userId, final IStopUserCallback callback) {
16454        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16455                != PackageManager.PERMISSION_GRANTED) {
16456            String msg = "Permission Denial: switchUser() from pid="
16457                    + Binder.getCallingPid()
16458                    + ", uid=" + Binder.getCallingUid()
16459                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16460            Slog.w(TAG, msg);
16461            throw new SecurityException(msg);
16462        }
16463        if (userId <= 0) {
16464            throw new IllegalArgumentException("Can't stop primary user " + userId);
16465        }
16466        synchronized (this) {
16467            return stopUserLocked(userId, callback);
16468        }
16469    }
16470
16471    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16472        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16473        if (mCurrentUserId == userId) {
16474            return ActivityManager.USER_OP_IS_CURRENT;
16475        }
16476
16477        final UserStartedState uss = mStartedUsers.get(userId);
16478        if (uss == null) {
16479            // User is not started, nothing to do...  but we do need to
16480            // callback if requested.
16481            if (callback != null) {
16482                mHandler.post(new Runnable() {
16483                    @Override
16484                    public void run() {
16485                        try {
16486                            callback.userStopped(userId);
16487                        } catch (RemoteException e) {
16488                        }
16489                    }
16490                });
16491            }
16492            return ActivityManager.USER_OP_SUCCESS;
16493        }
16494
16495        if (callback != null) {
16496            uss.mStopCallbacks.add(callback);
16497        }
16498
16499        if (uss.mState != UserStartedState.STATE_STOPPING
16500                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16501            uss.mState = UserStartedState.STATE_STOPPING;
16502            updateStartedUserArrayLocked();
16503
16504            long ident = Binder.clearCallingIdentity();
16505            try {
16506                // We are going to broadcast ACTION_USER_STOPPING and then
16507                // once that is done send a final ACTION_SHUTDOWN and then
16508                // stop the user.
16509                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16510                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16511                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16512                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16513                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16514                // This is the result receiver for the final shutdown broadcast.
16515                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16516                    @Override
16517                    public void performReceive(Intent intent, int resultCode, String data,
16518                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16519                        finishUserStop(uss);
16520                    }
16521                };
16522                // This is the result receiver for the initial stopping broadcast.
16523                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16524                    @Override
16525                    public void performReceive(Intent intent, int resultCode, String data,
16526                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16527                        // On to the next.
16528                        synchronized (ActivityManagerService.this) {
16529                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16530                                // Whoops, we are being started back up.  Abort, abort!
16531                                return;
16532                            }
16533                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16534                        }
16535                        broadcastIntentLocked(null, null, shutdownIntent,
16536                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16537                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16538                    }
16539                };
16540                // Kick things off.
16541                broadcastIntentLocked(null, null, stoppingIntent,
16542                        null, stoppingReceiver, 0, null, null,
16543                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16544                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16545            } finally {
16546                Binder.restoreCallingIdentity(ident);
16547            }
16548        }
16549
16550        return ActivityManager.USER_OP_SUCCESS;
16551    }
16552
16553    void finishUserStop(UserStartedState uss) {
16554        final int userId = uss.mHandle.getIdentifier();
16555        boolean stopped;
16556        ArrayList<IStopUserCallback> callbacks;
16557        synchronized (this) {
16558            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16559            if (mStartedUsers.get(userId) != uss) {
16560                stopped = false;
16561            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16562                stopped = false;
16563            } else {
16564                stopped = true;
16565                // User can no longer run.
16566                mStartedUsers.remove(userId);
16567                mUserLru.remove(Integer.valueOf(userId));
16568                updateStartedUserArrayLocked();
16569
16570                // Clean up all state and processes associated with the user.
16571                // Kill all the processes for the user.
16572                forceStopUserLocked(userId, "finish user");
16573            }
16574        }
16575
16576        for (int i=0; i<callbacks.size(); i++) {
16577            try {
16578                if (stopped) callbacks.get(i).userStopped(userId);
16579                else callbacks.get(i).userStopAborted(userId);
16580            } catch (RemoteException e) {
16581            }
16582        }
16583
16584        mStackSupervisor.removeUserLocked(userId);
16585    }
16586
16587    @Override
16588    public UserInfo getCurrentUser() {
16589        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16590                != PackageManager.PERMISSION_GRANTED) && (
16591                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16592                != PackageManager.PERMISSION_GRANTED)) {
16593            String msg = "Permission Denial: getCurrentUser() from pid="
16594                    + Binder.getCallingPid()
16595                    + ", uid=" + Binder.getCallingUid()
16596                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16597            Slog.w(TAG, msg);
16598            throw new SecurityException(msg);
16599        }
16600        synchronized (this) {
16601            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16602        }
16603    }
16604
16605    int getCurrentUserIdLocked() {
16606        return mCurrentUserId;
16607    }
16608
16609    @Override
16610    public boolean isUserRunning(int userId, boolean orStopped) {
16611        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16612                != PackageManager.PERMISSION_GRANTED) {
16613            String msg = "Permission Denial: isUserRunning() from pid="
16614                    + Binder.getCallingPid()
16615                    + ", uid=" + Binder.getCallingUid()
16616                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16617            Slog.w(TAG, msg);
16618            throw new SecurityException(msg);
16619        }
16620        synchronized (this) {
16621            return isUserRunningLocked(userId, orStopped);
16622        }
16623    }
16624
16625    boolean isUserRunningLocked(int userId, boolean orStopped) {
16626        UserStartedState state = mStartedUsers.get(userId);
16627        if (state == null) {
16628            return false;
16629        }
16630        if (orStopped) {
16631            return true;
16632        }
16633        return state.mState != UserStartedState.STATE_STOPPING
16634                && state.mState != UserStartedState.STATE_SHUTDOWN;
16635    }
16636
16637    @Override
16638    public int[] getRunningUserIds() {
16639        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16640                != PackageManager.PERMISSION_GRANTED) {
16641            String msg = "Permission Denial: isUserRunning() from pid="
16642                    + Binder.getCallingPid()
16643                    + ", uid=" + Binder.getCallingUid()
16644                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16645            Slog.w(TAG, msg);
16646            throw new SecurityException(msg);
16647        }
16648        synchronized (this) {
16649            return mStartedUserArray;
16650        }
16651    }
16652
16653    private void updateStartedUserArrayLocked() {
16654        int num = 0;
16655        for (int i=0; i<mStartedUsers.size();  i++) {
16656            UserStartedState uss = mStartedUsers.valueAt(i);
16657            // This list does not include stopping users.
16658            if (uss.mState != UserStartedState.STATE_STOPPING
16659                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16660                num++;
16661            }
16662        }
16663        mStartedUserArray = new int[num];
16664        num = 0;
16665        for (int i=0; i<mStartedUsers.size();  i++) {
16666            UserStartedState uss = mStartedUsers.valueAt(i);
16667            if (uss.mState != UserStartedState.STATE_STOPPING
16668                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16669                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16670                num++;
16671            }
16672        }
16673    }
16674
16675    @Override
16676    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16677        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16678                != PackageManager.PERMISSION_GRANTED) {
16679            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16680                    + Binder.getCallingPid()
16681                    + ", uid=" + Binder.getCallingUid()
16682                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16683            Slog.w(TAG, msg);
16684            throw new SecurityException(msg);
16685        }
16686
16687        mUserSwitchObservers.register(observer);
16688    }
16689
16690    @Override
16691    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16692        mUserSwitchObservers.unregister(observer);
16693    }
16694
16695    private boolean userExists(int userId) {
16696        if (userId == 0) {
16697            return true;
16698        }
16699        UserManagerService ums = getUserManagerLocked();
16700        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16701    }
16702
16703    int[] getUsersLocked() {
16704        UserManagerService ums = getUserManagerLocked();
16705        return ums != null ? ums.getUserIds() : new int[] { 0 };
16706    }
16707
16708    UserManagerService getUserManagerLocked() {
16709        if (mUserManager == null) {
16710            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16711            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16712        }
16713        return mUserManager;
16714    }
16715
16716    private int applyUserId(int uid, int userId) {
16717        return UserHandle.getUid(userId, uid);
16718    }
16719
16720    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16721        if (info == null) return null;
16722        ApplicationInfo newInfo = new ApplicationInfo(info);
16723        newInfo.uid = applyUserId(info.uid, userId);
16724        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16725                + info.packageName;
16726        return newInfo;
16727    }
16728
16729    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16730        if (aInfo == null
16731                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16732            return aInfo;
16733        }
16734
16735        ActivityInfo info = new ActivityInfo(aInfo);
16736        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16737        return info;
16738    }
16739}
16740