ActivityManagerService.java revision eaf2ac464b1cd741d7d0fe700771b1b7c00ddb29
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
1077    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1078    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1079    static final int FIRST_COMPAT_MODE_MSG = 300;
1080    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1081
1082    AlertDialog mUidAlert;
1083    CompatModeDialog mCompatModeDialog;
1084    long mLastMemUsageReportTime = 0;
1085
1086    /**
1087     * Flag whether the current user is a "monkey", i.e. whether
1088     * the UI is driven by a UI automation tool.
1089     */
1090    private boolean mUserIsMonkey;
1091
1092    final ServiceThread mHandlerThread;
1093    final MainHandler mHandler;
1094
1095    final class MainHandler extends Handler {
1096        public MainHandler(Looper looper) {
1097            super(looper, null, true);
1098        }
1099
1100        @Override
1101        public void handleMessage(Message msg) {
1102            switch (msg.what) {
1103            case SHOW_ERROR_MSG: {
1104                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1105                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1106                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1107                synchronized (ActivityManagerService.this) {
1108                    ProcessRecord proc = (ProcessRecord)data.get("app");
1109                    AppErrorResult res = (AppErrorResult) data.get("result");
1110                    if (proc != null && proc.crashDialog != null) {
1111                        Slog.e(TAG, "App already has crash dialog: " + proc);
1112                        if (res != null) {
1113                            res.set(0);
1114                        }
1115                        return;
1116                    }
1117                    if (!showBackground && UserHandle.getAppId(proc.uid)
1118                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1119                            && proc.pid != MY_PID) {
1120                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1121                        if (res != null) {
1122                            res.set(0);
1123                        }
1124                        return;
1125                    }
1126                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1127                        Dialog d = new AppErrorDialog(mContext,
1128                                ActivityManagerService.this, res, proc);
1129                        d.show();
1130                        proc.crashDialog = d;
1131                    } else {
1132                        // The device is asleep, so just pretend that the user
1133                        // saw a crash dialog and hit "force quit".
1134                        if (res != null) {
1135                            res.set(0);
1136                        }
1137                    }
1138                }
1139
1140                ensureBootCompleted();
1141            } break;
1142            case SHOW_NOT_RESPONDING_MSG: {
1143                synchronized (ActivityManagerService.this) {
1144                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1145                    ProcessRecord proc = (ProcessRecord)data.get("app");
1146                    if (proc != null && proc.anrDialog != null) {
1147                        Slog.e(TAG, "App already has anr dialog: " + proc);
1148                        return;
1149                    }
1150
1151                    Intent intent = new Intent("android.intent.action.ANR");
1152                    if (!mProcessesReady) {
1153                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1154                                | Intent.FLAG_RECEIVER_FOREGROUND);
1155                    }
1156                    broadcastIntentLocked(null, null, intent,
1157                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1158                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1159
1160                    if (mShowDialogs) {
1161                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1162                                mContext, proc, (ActivityRecord)data.get("activity"),
1163                                msg.arg1 != 0);
1164                        d.show();
1165                        proc.anrDialog = d;
1166                    } else {
1167                        // Just kill the app if there is no dialog to be shown.
1168                        killAppAtUsersRequest(proc, null);
1169                    }
1170                }
1171
1172                ensureBootCompleted();
1173            } break;
1174            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1175                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1176                synchronized (ActivityManagerService.this) {
1177                    ProcessRecord proc = (ProcessRecord) data.get("app");
1178                    if (proc == null) {
1179                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1180                        break;
1181                    }
1182                    if (proc.crashDialog != null) {
1183                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1184                        return;
1185                    }
1186                    AppErrorResult res = (AppErrorResult) data.get("result");
1187                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1188                        Dialog d = new StrictModeViolationDialog(mContext,
1189                                ActivityManagerService.this, res, proc);
1190                        d.show();
1191                        proc.crashDialog = d;
1192                    } else {
1193                        // The device is asleep, so just pretend that the user
1194                        // saw a crash dialog and hit "force quit".
1195                        res.set(0);
1196                    }
1197                }
1198                ensureBootCompleted();
1199            } break;
1200            case SHOW_FACTORY_ERROR_MSG: {
1201                Dialog d = new FactoryErrorDialog(
1202                    mContext, msg.getData().getCharSequence("msg"));
1203                d.show();
1204                ensureBootCompleted();
1205            } break;
1206            case UPDATE_CONFIGURATION_MSG: {
1207                final ContentResolver resolver = mContext.getContentResolver();
1208                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1209            } break;
1210            case GC_BACKGROUND_PROCESSES_MSG: {
1211                synchronized (ActivityManagerService.this) {
1212                    performAppGcsIfAppropriateLocked();
1213                }
1214            } break;
1215            case WAIT_FOR_DEBUGGER_MSG: {
1216                synchronized (ActivityManagerService.this) {
1217                    ProcessRecord app = (ProcessRecord)msg.obj;
1218                    if (msg.arg1 != 0) {
1219                        if (!app.waitedForDebugger) {
1220                            Dialog d = new AppWaitingForDebuggerDialog(
1221                                    ActivityManagerService.this,
1222                                    mContext, app);
1223                            app.waitDialog = d;
1224                            app.waitedForDebugger = true;
1225                            d.show();
1226                        }
1227                    } else {
1228                        if (app.waitDialog != null) {
1229                            app.waitDialog.dismiss();
1230                            app.waitDialog = null;
1231                        }
1232                    }
1233                }
1234            } break;
1235            case SERVICE_TIMEOUT_MSG: {
1236                if (mDidDexOpt) {
1237                    mDidDexOpt = false;
1238                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1239                    nmsg.obj = msg.obj;
1240                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1241                    return;
1242                }
1243                mServices.serviceTimeout((ProcessRecord)msg.obj);
1244            } break;
1245            case UPDATE_TIME_ZONE: {
1246                synchronized (ActivityManagerService.this) {
1247                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1248                        ProcessRecord r = mLruProcesses.get(i);
1249                        if (r.thread != null) {
1250                            try {
1251                                r.thread.updateTimeZone();
1252                            } catch (RemoteException ex) {
1253                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1254                            }
1255                        }
1256                    }
1257                }
1258            } break;
1259            case CLEAR_DNS_CACHE_MSG: {
1260                synchronized (ActivityManagerService.this) {
1261                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1262                        ProcessRecord r = mLruProcesses.get(i);
1263                        if (r.thread != null) {
1264                            try {
1265                                r.thread.clearDnsCache();
1266                            } catch (RemoteException ex) {
1267                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1268                            }
1269                        }
1270                    }
1271                }
1272            } break;
1273            case UPDATE_HTTP_PROXY_MSG: {
1274                ProxyProperties proxy = (ProxyProperties)msg.obj;
1275                String host = "";
1276                String port = "";
1277                String exclList = "";
1278                String pacFileUrl = null;
1279                if (proxy != null) {
1280                    host = proxy.getHost();
1281                    port = Integer.toString(proxy.getPort());
1282                    exclList = proxy.getExclusionList();
1283                    pacFileUrl = proxy.getPacFileUrl();
1284                }
1285                synchronized (ActivityManagerService.this) {
1286                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1287                        ProcessRecord r = mLruProcesses.get(i);
1288                        if (r.thread != null) {
1289                            try {
1290                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1291                            } catch (RemoteException ex) {
1292                                Slog.w(TAG, "Failed to update http proxy for: " +
1293                                        r.info.processName);
1294                            }
1295                        }
1296                    }
1297                }
1298            } break;
1299            case SHOW_UID_ERROR_MSG: {
1300                String title = "System UIDs Inconsistent";
1301                String text = "UIDs on the system are inconsistent, you need to wipe your"
1302                        + " data partition or your device will be unstable.";
1303                Log.e(TAG, title + ": " + text);
1304                if (mShowDialogs) {
1305                    // XXX This is a temporary dialog, no need to localize.
1306                    AlertDialog d = new BaseErrorDialog(mContext);
1307                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1308                    d.setCancelable(false);
1309                    d.setTitle(title);
1310                    d.setMessage(text);
1311                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1312                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1313                    mUidAlert = d;
1314                    d.show();
1315                }
1316            } break;
1317            case IM_FEELING_LUCKY_MSG: {
1318                if (mUidAlert != null) {
1319                    mUidAlert.dismiss();
1320                    mUidAlert = null;
1321                }
1322            } break;
1323            case PROC_START_TIMEOUT_MSG: {
1324                if (mDidDexOpt) {
1325                    mDidDexOpt = false;
1326                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1327                    nmsg.obj = msg.obj;
1328                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1329                    return;
1330                }
1331                ProcessRecord app = (ProcessRecord)msg.obj;
1332                synchronized (ActivityManagerService.this) {
1333                    processStartTimedOutLocked(app);
1334                }
1335            } break;
1336            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1337                synchronized (ActivityManagerService.this) {
1338                    doPendingActivityLaunchesLocked(true);
1339                }
1340            } break;
1341            case KILL_APPLICATION_MSG: {
1342                synchronized (ActivityManagerService.this) {
1343                    int appid = msg.arg1;
1344                    boolean restart = (msg.arg2 == 1);
1345                    Bundle bundle = (Bundle)msg.obj;
1346                    String pkg = bundle.getString("pkg");
1347                    String reason = bundle.getString("reason");
1348                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1349                            false, UserHandle.USER_ALL, reason);
1350                }
1351            } break;
1352            case FINALIZE_PENDING_INTENT_MSG: {
1353                ((PendingIntentRecord)msg.obj).completeFinalize();
1354            } break;
1355            case POST_HEAVY_NOTIFICATION_MSG: {
1356                INotificationManager inm = NotificationManager.getService();
1357                if (inm == null) {
1358                    return;
1359                }
1360
1361                ActivityRecord root = (ActivityRecord)msg.obj;
1362                ProcessRecord process = root.app;
1363                if (process == null) {
1364                    return;
1365                }
1366
1367                try {
1368                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1369                    String text = mContext.getString(R.string.heavy_weight_notification,
1370                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1371                    Notification notification = new Notification();
1372                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1373                    notification.when = 0;
1374                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1375                    notification.tickerText = text;
1376                    notification.defaults = 0; // please be quiet
1377                    notification.sound = null;
1378                    notification.vibrate = null;
1379                    notification.setLatestEventInfo(context, text,
1380                            mContext.getText(R.string.heavy_weight_notification_detail),
1381                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1382                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1383                                    new UserHandle(root.userId)));
1384
1385                    try {
1386                        int[] outId = new int[1];
1387                        inm.enqueueNotificationWithTag("android", "android", null,
1388                                R.string.heavy_weight_notification,
1389                                notification, outId, root.userId);
1390                    } catch (RuntimeException e) {
1391                        Slog.w(ActivityManagerService.TAG,
1392                                "Error showing notification for heavy-weight app", e);
1393                    } catch (RemoteException e) {
1394                    }
1395                } catch (NameNotFoundException e) {
1396                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1397                }
1398            } break;
1399            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1400                INotificationManager inm = NotificationManager.getService();
1401                if (inm == null) {
1402                    return;
1403                }
1404                try {
1405                    inm.cancelNotificationWithTag("android", null,
1406                            R.string.heavy_weight_notification,  msg.arg1);
1407                } catch (RuntimeException e) {
1408                    Slog.w(ActivityManagerService.TAG,
1409                            "Error canceling notification for service", e);
1410                } catch (RemoteException e) {
1411                }
1412            } break;
1413            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1414                synchronized (ActivityManagerService.this) {
1415                    checkExcessivePowerUsageLocked(true);
1416                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1417                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1418                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1419                }
1420            } break;
1421            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1422                synchronized (ActivityManagerService.this) {
1423                    ActivityRecord ar = (ActivityRecord)msg.obj;
1424                    if (mCompatModeDialog != null) {
1425                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1426                                ar.info.applicationInfo.packageName)) {
1427                            return;
1428                        }
1429                        mCompatModeDialog.dismiss();
1430                        mCompatModeDialog = null;
1431                    }
1432                    if (ar != null && false) {
1433                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1434                                ar.packageName)) {
1435                            int mode = mCompatModePackages.computeCompatModeLocked(
1436                                    ar.info.applicationInfo);
1437                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1438                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1439                                mCompatModeDialog = new CompatModeDialog(
1440                                        ActivityManagerService.this, mContext,
1441                                        ar.info.applicationInfo);
1442                                mCompatModeDialog.show();
1443                            }
1444                        }
1445                    }
1446                }
1447                break;
1448            }
1449            case DISPATCH_PROCESSES_CHANGED: {
1450                dispatchProcessesChanged();
1451                break;
1452            }
1453            case DISPATCH_PROCESS_DIED: {
1454                final int pid = msg.arg1;
1455                final int uid = msg.arg2;
1456                dispatchProcessDied(pid, uid);
1457                break;
1458            }
1459            case REPORT_MEM_USAGE_MSG: {
1460                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1461                Thread thread = new Thread() {
1462                    @Override public void run() {
1463                        final SparseArray<ProcessMemInfo> infoMap
1464                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1465                        for (int i=0, N=memInfos.size(); i<N; i++) {
1466                            ProcessMemInfo mi = memInfos.get(i);
1467                            infoMap.put(mi.pid, mi);
1468                        }
1469                        updateCpuStatsNow();
1470                        synchronized (mProcessCpuThread) {
1471                            final int N = mProcessCpuTracker.countStats();
1472                            for (int i=0; i<N; i++) {
1473                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1474                                if (st.vsize > 0) {
1475                                    long pss = Debug.getPss(st.pid, null);
1476                                    if (pss > 0) {
1477                                        if (infoMap.indexOfKey(st.pid) < 0) {
1478                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1479                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1480                                            mi.pss = pss;
1481                                            memInfos.add(mi);
1482                                        }
1483                                    }
1484                                }
1485                            }
1486                        }
1487
1488                        long totalPss = 0;
1489                        for (int i=0, N=memInfos.size(); i<N; i++) {
1490                            ProcessMemInfo mi = memInfos.get(i);
1491                            if (mi.pss == 0) {
1492                                mi.pss = Debug.getPss(mi.pid, null);
1493                            }
1494                            totalPss += mi.pss;
1495                        }
1496                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1497                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1498                                if (lhs.oomAdj != rhs.oomAdj) {
1499                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1500                                }
1501                                if (lhs.pss != rhs.pss) {
1502                                    return lhs.pss < rhs.pss ? 1 : -1;
1503                                }
1504                                return 0;
1505                            }
1506                        });
1507
1508                        StringBuilder tag = new StringBuilder(128);
1509                        StringBuilder stack = new StringBuilder(128);
1510                        tag.append("Low on memory -- ");
1511                        appendMemBucket(tag, totalPss, "total", false);
1512                        appendMemBucket(stack, totalPss, "total", true);
1513
1514                        StringBuilder logBuilder = new StringBuilder(1024);
1515                        logBuilder.append("Low on memory:\n");
1516
1517                        boolean firstLine = true;
1518                        int lastOomAdj = Integer.MIN_VALUE;
1519                        for (int i=0, N=memInfos.size(); i<N; i++) {
1520                            ProcessMemInfo mi = memInfos.get(i);
1521
1522                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1523                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1524                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1525                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1526                                if (lastOomAdj != mi.oomAdj) {
1527                                    lastOomAdj = mi.oomAdj;
1528                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1529                                        tag.append(" / ");
1530                                    }
1531                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1532                                        if (firstLine) {
1533                                            stack.append(":");
1534                                            firstLine = false;
1535                                        }
1536                                        stack.append("\n\t at ");
1537                                    } else {
1538                                        stack.append("$");
1539                                    }
1540                                } else {
1541                                    tag.append(" ");
1542                                    stack.append("$");
1543                                }
1544                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1545                                    appendMemBucket(tag, mi.pss, mi.name, false);
1546                                }
1547                                appendMemBucket(stack, mi.pss, mi.name, true);
1548                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1549                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1550                                    stack.append("(");
1551                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1552                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1553                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1554                                            stack.append(":");
1555                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1556                                        }
1557                                    }
1558                                    stack.append(")");
1559                                }
1560                            }
1561
1562                            logBuilder.append("  ");
1563                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1564                            logBuilder.append(' ');
1565                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1566                            logBuilder.append(' ');
1567                            ProcessList.appendRamKb(logBuilder, mi.pss);
1568                            logBuilder.append(" kB: ");
1569                            logBuilder.append(mi.name);
1570                            logBuilder.append(" (");
1571                            logBuilder.append(mi.pid);
1572                            logBuilder.append(") ");
1573                            logBuilder.append(mi.adjType);
1574                            logBuilder.append('\n');
1575                            if (mi.adjReason != null) {
1576                                logBuilder.append("                      ");
1577                                logBuilder.append(mi.adjReason);
1578                                logBuilder.append('\n');
1579                            }
1580                        }
1581
1582                        logBuilder.append("           ");
1583                        ProcessList.appendRamKb(logBuilder, totalPss);
1584                        logBuilder.append(" kB: TOTAL\n");
1585
1586                        long[] infos = new long[Debug.MEMINFO_COUNT];
1587                        Debug.getMemInfo(infos);
1588                        logBuilder.append("  MemInfo: ");
1589                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1590                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1591                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1592                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1593                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1594                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1595                            logBuilder.append("  ZRAM: ");
1596                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1597                            logBuilder.append(" kB RAM, ");
1598                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1599                            logBuilder.append(" kB swap total, ");
1600                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1601                            logBuilder.append(" kB swap free\n");
1602                        }
1603                        Slog.i(TAG, logBuilder.toString());
1604
1605                        StringBuilder dropBuilder = new StringBuilder(1024);
1606                        /*
1607                        StringWriter oomSw = new StringWriter();
1608                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1609                        StringWriter catSw = new StringWriter();
1610                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1611                        String[] emptyArgs = new String[] { };
1612                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1613                        oomPw.flush();
1614                        String oomString = oomSw.toString();
1615                        */
1616                        dropBuilder.append(stack);
1617                        dropBuilder.append('\n');
1618                        dropBuilder.append('\n');
1619                        dropBuilder.append(logBuilder);
1620                        dropBuilder.append('\n');
1621                        /*
1622                        dropBuilder.append(oomString);
1623                        dropBuilder.append('\n');
1624                        */
1625                        StringWriter catSw = new StringWriter();
1626                        synchronized (ActivityManagerService.this) {
1627                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1628                            String[] emptyArgs = new String[] { };
1629                            catPw.println();
1630                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1631                            catPw.println();
1632                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1633                                    false, false, null);
1634                            catPw.println();
1635                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1636                            catPw.flush();
1637                        }
1638                        dropBuilder.append(catSw.toString());
1639                        addErrorToDropBox("lowmem", null, "system_server", null,
1640                                null, tag.toString(), dropBuilder.toString(), null, null);
1641                        //Slog.i(TAG, "Sent to dropbox:");
1642                        //Slog.i(TAG, dropBuilder.toString());
1643                        synchronized (ActivityManagerService.this) {
1644                            long now = SystemClock.uptimeMillis();
1645                            if (mLastMemUsageReportTime < now) {
1646                                mLastMemUsageReportTime = now;
1647                            }
1648                        }
1649                    }
1650                };
1651                thread.start();
1652                break;
1653            }
1654            case REPORT_USER_SWITCH_MSG: {
1655                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1656                break;
1657            }
1658            case CONTINUE_USER_SWITCH_MSG: {
1659                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1660                break;
1661            }
1662            case USER_SWITCH_TIMEOUT_MSG: {
1663                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1664                break;
1665            }
1666            case IMMERSIVE_MODE_LOCK_MSG: {
1667                final boolean nextState = (msg.arg1 != 0);
1668                if (mUpdateLock.isHeld() != nextState) {
1669                    if (DEBUG_IMMERSIVE) {
1670                        final ActivityRecord r = (ActivityRecord) msg.obj;
1671                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1672                    }
1673                    if (nextState) {
1674                        mUpdateLock.acquire();
1675                    } else {
1676                        mUpdateLock.release();
1677                    }
1678                }
1679                break;
1680            }
1681            case PERSIST_URI_GRANTS_MSG: {
1682                writeGrantedUriPermissions();
1683                break;
1684            }
1685            case REQUEST_ALL_PSS_MSG: {
1686                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1687                break;
1688            }
1689            }
1690        }
1691    };
1692
1693    static final int COLLECT_PSS_BG_MSG = 1;
1694
1695    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1696        @Override
1697        public void handleMessage(Message msg) {
1698            switch (msg.what) {
1699            case COLLECT_PSS_BG_MSG: {
1700                int i=0, num=0;
1701                long start = SystemClock.uptimeMillis();
1702                long[] tmp = new long[1];
1703                do {
1704                    ProcessRecord proc;
1705                    int procState;
1706                    int pid;
1707                    synchronized (ActivityManagerService.this) {
1708                        if (i >= mPendingPssProcesses.size()) {
1709                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1710                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1711                            mPendingPssProcesses.clear();
1712                            return;
1713                        }
1714                        proc = mPendingPssProcesses.get(i);
1715                        procState = proc.pssProcState;
1716                        if (proc.thread != null && procState == proc.setProcState) {
1717                            pid = proc.pid;
1718                        } else {
1719                            proc = null;
1720                            pid = 0;
1721                        }
1722                        i++;
1723                    }
1724                    if (proc != null) {
1725                        long pss = Debug.getPss(pid, tmp);
1726                        synchronized (ActivityManagerService.this) {
1727                            if (proc.thread != null && proc.setProcState == procState
1728                                    && proc.pid == pid) {
1729                                num++;
1730                                proc.lastPssTime = SystemClock.uptimeMillis();
1731                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1732                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1733                                        + ": " + pss + " lastPss=" + proc.lastPss
1734                                        + " state=" + ProcessList.makeProcStateString(procState));
1735                                if (proc.initialIdlePss == 0) {
1736                                    proc.initialIdlePss = pss;
1737                                }
1738                                proc.lastPss = pss;
1739                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1740                                    proc.lastCachedPss = pss;
1741                                }
1742                            }
1743                        }
1744                    }
1745                } while (true);
1746            }
1747            }
1748        }
1749    };
1750
1751    public void setSystemProcess() {
1752        try {
1753            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1754            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1755            ServiceManager.addService("meminfo", new MemBinder(this));
1756            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1757            ServiceManager.addService("dbinfo", new DbBinder(this));
1758            if (MONITOR_CPU_USAGE) {
1759                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1760            }
1761            ServiceManager.addService("permission", new PermissionController(this));
1762
1763            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1764                    "android", STOCK_PM_FLAGS);
1765            mSystemThread.installSystemApplicationInfo(info);
1766
1767            synchronized (this) {
1768                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1769                app.persistent = true;
1770                app.pid = MY_PID;
1771                app.maxAdj = ProcessList.SYSTEM_ADJ;
1772                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1773                mProcessNames.put(app.processName, app.uid, app);
1774                synchronized (mPidsSelfLocked) {
1775                    mPidsSelfLocked.put(app.pid, app);
1776                }
1777                updateLruProcessLocked(app, false, null);
1778                updateOomAdjLocked();
1779            }
1780        } catch (PackageManager.NameNotFoundException e) {
1781            throw new RuntimeException(
1782                    "Unable to find android system package", e);
1783        }
1784    }
1785
1786    public void setWindowManager(WindowManagerService wm) {
1787        mWindowManager = wm;
1788        mStackSupervisor.setWindowManager(wm);
1789    }
1790
1791    public void startObservingNativeCrashes() {
1792        final NativeCrashListener ncl = new NativeCrashListener(this);
1793        ncl.start();
1794    }
1795
1796    public IAppOpsService getAppOpsService() {
1797        return mAppOpsService;
1798    }
1799
1800    static class MemBinder extends Binder {
1801        ActivityManagerService mActivityManagerService;
1802        MemBinder(ActivityManagerService activityManagerService) {
1803            mActivityManagerService = activityManagerService;
1804        }
1805
1806        @Override
1807        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1808            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1809                    != PackageManager.PERMISSION_GRANTED) {
1810                pw.println("Permission Denial: can't dump meminfo from from pid="
1811                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1812                        + " without permission " + android.Manifest.permission.DUMP);
1813                return;
1814            }
1815
1816            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1817        }
1818    }
1819
1820    static class GraphicsBinder extends Binder {
1821        ActivityManagerService mActivityManagerService;
1822        GraphicsBinder(ActivityManagerService activityManagerService) {
1823            mActivityManagerService = activityManagerService;
1824        }
1825
1826        @Override
1827        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1828            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1829                    != PackageManager.PERMISSION_GRANTED) {
1830                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1831                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1832                        + " without permission " + android.Manifest.permission.DUMP);
1833                return;
1834            }
1835
1836            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1837        }
1838    }
1839
1840    static class DbBinder extends Binder {
1841        ActivityManagerService mActivityManagerService;
1842        DbBinder(ActivityManagerService activityManagerService) {
1843            mActivityManagerService = activityManagerService;
1844        }
1845
1846        @Override
1847        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1848            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1849                    != PackageManager.PERMISSION_GRANTED) {
1850                pw.println("Permission Denial: can't dump dbinfo from from pid="
1851                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1852                        + " without permission " + android.Manifest.permission.DUMP);
1853                return;
1854            }
1855
1856            mActivityManagerService.dumpDbInfo(fd, pw, args);
1857        }
1858    }
1859
1860    static class CpuBinder extends Binder {
1861        ActivityManagerService mActivityManagerService;
1862        CpuBinder(ActivityManagerService activityManagerService) {
1863            mActivityManagerService = activityManagerService;
1864        }
1865
1866        @Override
1867        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1868            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1869                    != PackageManager.PERMISSION_GRANTED) {
1870                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1871                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1872                        + " without permission " + android.Manifest.permission.DUMP);
1873                return;
1874            }
1875
1876            synchronized (mActivityManagerService.mProcessCpuThread) {
1877                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1878                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1879                        SystemClock.uptimeMillis()));
1880            }
1881        }
1882    }
1883
1884    public static class Lifecycle extends SystemService {
1885        private ActivityManagerService mService;
1886
1887        @Override
1888        public void onCreate(Context context) {
1889            mService = new ActivityManagerService(context);
1890        }
1891
1892        @Override
1893        public void onStart() {
1894            mService.start();
1895        }
1896
1897        public ActivityManagerService getService() {
1898            return mService;
1899        }
1900    }
1901
1902    // Note: This method is invoked on the main thread but may need to attach various
1903    // handlers to other threads.  So take care to be explicit about the looper.
1904    public ActivityManagerService(Context systemContext) {
1905        mContext = systemContext;
1906        mFactoryTest = FactoryTest.getMode();
1907        mSystemThread = ActivityThread.currentActivityThread();
1908
1909        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1910
1911        mHandlerThread = new ServiceThread(TAG,
1912                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1913        mHandlerThread.start();
1914        mHandler = new MainHandler(mHandlerThread.getLooper());
1915
1916        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1917                "foreground", BROADCAST_FG_TIMEOUT, false);
1918        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1919                "background", BROADCAST_BG_TIMEOUT, true);
1920        mBroadcastQueues[0] = mFgBroadcastQueue;
1921        mBroadcastQueues[1] = mBgBroadcastQueue;
1922
1923        mServices = new ActiveServices(this);
1924        mProviderMap = new ProviderMap(this);
1925
1926        // TODO: Move creation of battery stats service outside of activity manager service.
1927        File dataDir = Environment.getDataDirectory();
1928        File systemDir = new File(dataDir, "system");
1929        systemDir.mkdirs();
1930        mBatteryStatsService = new BatteryStatsService(new File(
1931                systemDir, "batterystats.bin").toString(), mHandler);
1932        mBatteryStatsService.getActiveStatistics().readLocked();
1933        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1934        mOnBattery = DEBUG_POWER ? true
1935                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1936        mBatteryStatsService.getActiveStatistics().setCallback(this);
1937
1938        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1939
1940        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1941        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1942
1943        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1944
1945        // User 0 is the first and only user that runs at boot.
1946        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1947        mUserLru.add(Integer.valueOf(0));
1948        updateStartedUserArrayLocked();
1949
1950        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1951            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1952
1953        mConfiguration.setToDefaults();
1954        mConfiguration.setLocale(Locale.getDefault());
1955
1956        mConfigurationSeq = mConfiguration.seq = 1;
1957        mProcessCpuTracker.init();
1958
1959        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1960        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1961        mStackSupervisor = new ActivityStackSupervisor(this);
1962
1963        mProcessCpuThread = new Thread("CpuTracker") {
1964            @Override
1965            public void run() {
1966                while (true) {
1967                    try {
1968                        try {
1969                            synchronized(this) {
1970                                final long now = SystemClock.uptimeMillis();
1971                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1972                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1973                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1974                                //        + ", write delay=" + nextWriteDelay);
1975                                if (nextWriteDelay < nextCpuDelay) {
1976                                    nextCpuDelay = nextWriteDelay;
1977                                }
1978                                if (nextCpuDelay > 0) {
1979                                    mProcessCpuMutexFree.set(true);
1980                                    this.wait(nextCpuDelay);
1981                                }
1982                            }
1983                        } catch (InterruptedException e) {
1984                        }
1985                        updateCpuStatsNow();
1986                    } catch (Exception e) {
1987                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1988                    }
1989                }
1990            }
1991        };
1992
1993        Watchdog.getInstance().addMonitor(this);
1994        Watchdog.getInstance().addThread(mHandler);
1995    }
1996
1997    private void start() {
1998        mProcessCpuThread.start();
1999
2000        mBatteryStatsService.publish(mContext);
2001        mUsageStatsService.publish(mContext);
2002        mAppOpsService.publish(mContext);
2003        startRunning(null, null, null, null);
2004    }
2005
2006    @Override
2007    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2008            throws RemoteException {
2009        if (code == SYSPROPS_TRANSACTION) {
2010            // We need to tell all apps about the system property change.
2011            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2012            synchronized(this) {
2013                final int NP = mProcessNames.getMap().size();
2014                for (int ip=0; ip<NP; ip++) {
2015                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2016                    final int NA = apps.size();
2017                    for (int ia=0; ia<NA; ia++) {
2018                        ProcessRecord app = apps.valueAt(ia);
2019                        if (app.thread != null) {
2020                            procs.add(app.thread.asBinder());
2021                        }
2022                    }
2023                }
2024            }
2025
2026            int N = procs.size();
2027            for (int i=0; i<N; i++) {
2028                Parcel data2 = Parcel.obtain();
2029                try {
2030                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2031                } catch (RemoteException e) {
2032                }
2033                data2.recycle();
2034            }
2035        }
2036        try {
2037            return super.onTransact(code, data, reply, flags);
2038        } catch (RuntimeException e) {
2039            // The activity manager only throws security exceptions, so let's
2040            // log all others.
2041            if (!(e instanceof SecurityException)) {
2042                Slog.wtf(TAG, "Activity Manager Crash", e);
2043            }
2044            throw e;
2045        }
2046    }
2047
2048    void updateCpuStats() {
2049        final long now = SystemClock.uptimeMillis();
2050        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2051            return;
2052        }
2053        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2054            synchronized (mProcessCpuThread) {
2055                mProcessCpuThread.notify();
2056            }
2057        }
2058    }
2059
2060    void updateCpuStatsNow() {
2061        synchronized (mProcessCpuThread) {
2062            mProcessCpuMutexFree.set(false);
2063            final long now = SystemClock.uptimeMillis();
2064            boolean haveNewCpuStats = false;
2065
2066            if (MONITOR_CPU_USAGE &&
2067                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2068                mLastCpuTime.set(now);
2069                haveNewCpuStats = true;
2070                mProcessCpuTracker.update();
2071                //Slog.i(TAG, mProcessCpu.printCurrentState());
2072                //Slog.i(TAG, "Total CPU usage: "
2073                //        + mProcessCpu.getTotalCpuPercent() + "%");
2074
2075                // Slog the cpu usage if the property is set.
2076                if ("true".equals(SystemProperties.get("events.cpu"))) {
2077                    int user = mProcessCpuTracker.getLastUserTime();
2078                    int system = mProcessCpuTracker.getLastSystemTime();
2079                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2080                    int irq = mProcessCpuTracker.getLastIrqTime();
2081                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2082                    int idle = mProcessCpuTracker.getLastIdleTime();
2083
2084                    int total = user + system + iowait + irq + softIrq + idle;
2085                    if (total == 0) total = 1;
2086
2087                    EventLog.writeEvent(EventLogTags.CPU,
2088                            ((user+system+iowait+irq+softIrq) * 100) / total,
2089                            (user * 100) / total,
2090                            (system * 100) / total,
2091                            (iowait * 100) / total,
2092                            (irq * 100) / total,
2093                            (softIrq * 100) / total);
2094                }
2095            }
2096
2097            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2098            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2099            synchronized(bstats) {
2100                synchronized(mPidsSelfLocked) {
2101                    if (haveNewCpuStats) {
2102                        if (mOnBattery) {
2103                            int perc = bstats.startAddingCpuLocked();
2104                            int totalUTime = 0;
2105                            int totalSTime = 0;
2106                            final int N = mProcessCpuTracker.countStats();
2107                            for (int i=0; i<N; i++) {
2108                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2109                                if (!st.working) {
2110                                    continue;
2111                                }
2112                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2113                                int otherUTime = (st.rel_utime*perc)/100;
2114                                int otherSTime = (st.rel_stime*perc)/100;
2115                                totalUTime += otherUTime;
2116                                totalSTime += otherSTime;
2117                                if (pr != null) {
2118                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2119                                    if (ps == null || !ps.isActive()) {
2120                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2121                                                pr.info.uid, pr.processName);
2122                                    }
2123                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2124                                            st.rel_stime-otherSTime);
2125                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2126                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2127                                } else {
2128                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2129                                    if (ps == null || !ps.isActive()) {
2130                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2131                                                bstats.mapUid(st.uid), st.name);
2132                                    }
2133                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2134                                            st.rel_stime-otherSTime);
2135                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2136                                }
2137                            }
2138                            bstats.finishAddingCpuLocked(perc, totalUTime,
2139                                    totalSTime, cpuSpeedTimes);
2140                        }
2141                    }
2142                }
2143
2144                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2145                    mLastWriteTime = now;
2146                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2147                }
2148            }
2149        }
2150    }
2151
2152    @Override
2153    public void batteryNeedsCpuUpdate() {
2154        updateCpuStatsNow();
2155    }
2156
2157    @Override
2158    public void batteryPowerChanged(boolean onBattery) {
2159        // When plugging in, update the CPU stats first before changing
2160        // the plug state.
2161        updateCpuStatsNow();
2162        synchronized (this) {
2163            synchronized(mPidsSelfLocked) {
2164                mOnBattery = DEBUG_POWER ? true : onBattery;
2165            }
2166        }
2167    }
2168
2169    /**
2170     * Initialize the application bind args. These are passed to each
2171     * process when the bindApplication() IPC is sent to the process. They're
2172     * lazily setup to make sure the services are running when they're asked for.
2173     */
2174    private HashMap<String, IBinder> getCommonServicesLocked() {
2175        if (mAppBindArgs == null) {
2176            mAppBindArgs = new HashMap<String, IBinder>();
2177
2178            // Setup the application init args
2179            mAppBindArgs.put("package", ServiceManager.getService("package"));
2180            mAppBindArgs.put("window", ServiceManager.getService("window"));
2181            mAppBindArgs.put(Context.ALARM_SERVICE,
2182                    ServiceManager.getService(Context.ALARM_SERVICE));
2183        }
2184        return mAppBindArgs;
2185    }
2186
2187    final void setFocusedActivityLocked(ActivityRecord r) {
2188        if (mFocusedActivity != r) {
2189            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2190            mFocusedActivity = r;
2191            mStackSupervisor.setFocusedStack(r);
2192            if (r != null) {
2193                mWindowManager.setFocusedApp(r.appToken, true);
2194            }
2195            applyUpdateLockStateLocked(r);
2196        }
2197    }
2198
2199    @Override
2200    public void setFocusedStack(int stackId) {
2201        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2202        synchronized (ActivityManagerService.this) {
2203            ActivityStack stack = mStackSupervisor.getStack(stackId);
2204            if (stack != null) {
2205                ActivityRecord r = stack.topRunningActivityLocked(null);
2206                if (r != null) {
2207                    setFocusedActivityLocked(r);
2208                }
2209            }
2210        }
2211    }
2212
2213    @Override
2214    public void notifyActivityDrawn(IBinder token) {
2215        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2216        synchronized (this) {
2217            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2218            if (r != null) {
2219                r.task.stack.notifyActivityDrawnLocked(r);
2220            }
2221        }
2222    }
2223
2224    final void applyUpdateLockStateLocked(ActivityRecord r) {
2225        // Modifications to the UpdateLock state are done on our handler, outside
2226        // the activity manager's locks.  The new state is determined based on the
2227        // state *now* of the relevant activity record.  The object is passed to
2228        // the handler solely for logging detail, not to be consulted/modified.
2229        final boolean nextState = r != null && r.immersive;
2230        mHandler.sendMessage(
2231                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2232    }
2233
2234    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2235        Message msg = Message.obtain();
2236        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2237        msg.obj = r.task.askedCompatMode ? null : r;
2238        mHandler.sendMessage(msg);
2239    }
2240
2241    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2242            String what, Object obj, ProcessRecord srcApp) {
2243        app.lastActivityTime = now;
2244
2245        if (app.activities.size() > 0) {
2246            // Don't want to touch dependent processes that are hosting activities.
2247            return index;
2248        }
2249
2250        int lrui = mLruProcesses.lastIndexOf(app);
2251        if (lrui < 0) {
2252            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2253                    + what + " " + obj + " from " + srcApp);
2254            return index;
2255        }
2256
2257        if (lrui >= index) {
2258            // Don't want to cause this to move dependent processes *back* in the
2259            // list as if they were less frequently used.
2260            return index;
2261        }
2262
2263        if (lrui >= mLruProcessActivityStart) {
2264            // Don't want to touch dependent processes that are hosting activities.
2265            return index;
2266        }
2267
2268        mLruProcesses.remove(lrui);
2269        if (index > 0) {
2270            index--;
2271        }
2272        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2273                + " in LRU list: " + app);
2274        mLruProcesses.add(index, app);
2275        return index;
2276    }
2277
2278    final void removeLruProcessLocked(ProcessRecord app) {
2279        int lrui = mLruProcesses.lastIndexOf(app);
2280        if (lrui >= 0) {
2281            if (lrui <= mLruProcessActivityStart) {
2282                mLruProcessActivityStart--;
2283            }
2284            if (lrui <= mLruProcessServiceStart) {
2285                mLruProcessServiceStart--;
2286            }
2287            mLruProcesses.remove(lrui);
2288        }
2289    }
2290
2291    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2292            ProcessRecord client) {
2293        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2294        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2295        if (!activityChange && hasActivity) {
2296            // The process has activties, so we are only going to allow activity-based
2297            // adjustments move it.  It should be kept in the front of the list with other
2298            // processes that have activities, and we don't want those to change their
2299            // order except due to activity operations.
2300            return;
2301        }
2302
2303        mLruSeq++;
2304        final long now = SystemClock.uptimeMillis();
2305        app.lastActivityTime = now;
2306
2307        // First a quick reject: if the app is already at the position we will
2308        // put it, then there is nothing to do.
2309        if (hasActivity) {
2310            final int N = mLruProcesses.size();
2311            if (N > 0 && mLruProcesses.get(N-1) == app) {
2312                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2313                return;
2314            }
2315        } else {
2316            if (mLruProcessServiceStart > 0
2317                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2318                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2319                return;
2320            }
2321        }
2322
2323        int lrui = mLruProcesses.lastIndexOf(app);
2324
2325        if (app.persistent && lrui >= 0) {
2326            // We don't care about the position of persistent processes, as long as
2327            // they are in the list.
2328            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2329            return;
2330        }
2331
2332        /* In progress: compute new position first, so we can avoid doing work
2333           if the process is not actually going to move.  Not yet working.
2334        int addIndex;
2335        int nextIndex;
2336        boolean inActivity = false, inService = false;
2337        if (hasActivity) {
2338            // Process has activities, put it at the very tipsy-top.
2339            addIndex = mLruProcesses.size();
2340            nextIndex = mLruProcessServiceStart;
2341            inActivity = true;
2342        } else if (hasService) {
2343            // Process has services, put it at the top of the service list.
2344            addIndex = mLruProcessActivityStart;
2345            nextIndex = mLruProcessServiceStart;
2346            inActivity = true;
2347            inService = true;
2348        } else  {
2349            // Process not otherwise of interest, it goes to the top of the non-service area.
2350            addIndex = mLruProcessServiceStart;
2351            if (client != null) {
2352                int clientIndex = mLruProcesses.lastIndexOf(client);
2353                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2354                        + app);
2355                if (clientIndex >= 0 && addIndex > clientIndex) {
2356                    addIndex = clientIndex;
2357                }
2358            }
2359            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2360        }
2361
2362        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2363                + mLruProcessActivityStart + "): " + app);
2364        */
2365
2366        if (lrui >= 0) {
2367            if (lrui < mLruProcessActivityStart) {
2368                mLruProcessActivityStart--;
2369            }
2370            if (lrui < mLruProcessServiceStart) {
2371                mLruProcessServiceStart--;
2372            }
2373            /*
2374            if (addIndex > lrui) {
2375                addIndex--;
2376            }
2377            if (nextIndex > lrui) {
2378                nextIndex--;
2379            }
2380            */
2381            mLruProcesses.remove(lrui);
2382        }
2383
2384        /*
2385        mLruProcesses.add(addIndex, app);
2386        if (inActivity) {
2387            mLruProcessActivityStart++;
2388        }
2389        if (inService) {
2390            mLruProcessActivityStart++;
2391        }
2392        */
2393
2394        int nextIndex;
2395        if (hasActivity) {
2396            final int N = mLruProcesses.size();
2397            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2398                // Process doesn't have activities, but has clients with
2399                // activities...  move it up, but one below the top (the top
2400                // should always have a real activity).
2401                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2402                mLruProcesses.add(N-1, app);
2403                // To keep it from spamming the LRU list (by making a bunch of clients),
2404                // we will push down any other entries owned by the app.
2405                final int uid = app.info.uid;
2406                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2407                    ProcessRecord subProc = mLruProcesses.get(i);
2408                    if (subProc.info.uid == uid) {
2409                        // We want to push this one down the list.  If the process after
2410                        // it is for the same uid, however, don't do so, because we don't
2411                        // want them internally to be re-ordered.
2412                        if (mLruProcesses.get(i-1).info.uid != uid) {
2413                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2414                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2415                            ProcessRecord tmp = mLruProcesses.get(i);
2416                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2417                            mLruProcesses.set(i-1, tmp);
2418                            i--;
2419                        }
2420                    } else {
2421                        // A gap, we can stop here.
2422                        break;
2423                    }
2424                }
2425            } else {
2426                // Process has activities, put it at the very tipsy-top.
2427                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2428                mLruProcesses.add(app);
2429            }
2430            nextIndex = mLruProcessServiceStart;
2431        } else if (hasService) {
2432            // Process has services, put it at the top of the service list.
2433            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2434            mLruProcesses.add(mLruProcessActivityStart, app);
2435            nextIndex = mLruProcessServiceStart;
2436            mLruProcessActivityStart++;
2437        } else  {
2438            // Process not otherwise of interest, it goes to the top of the non-service area.
2439            int index = mLruProcessServiceStart;
2440            if (client != null) {
2441                // If there is a client, don't allow the process to be moved up higher
2442                // in the list than that client.
2443                int clientIndex = mLruProcesses.lastIndexOf(client);
2444                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2445                        + " when updating " + app);
2446                if (clientIndex <= lrui) {
2447                    // Don't allow the client index restriction to push it down farther in the
2448                    // list than it already is.
2449                    clientIndex = lrui;
2450                }
2451                if (clientIndex >= 0 && index > clientIndex) {
2452                    index = clientIndex;
2453                }
2454            }
2455            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2456            mLruProcesses.add(index, app);
2457            nextIndex = index-1;
2458            mLruProcessActivityStart++;
2459            mLruProcessServiceStart++;
2460        }
2461
2462        // If the app is currently using a content provider or service,
2463        // bump those processes as well.
2464        for (int j=app.connections.size()-1; j>=0; j--) {
2465            ConnectionRecord cr = app.connections.valueAt(j);
2466            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2467                    && cr.binding.service.app != null
2468                    && cr.binding.service.app.lruSeq != mLruSeq
2469                    && !cr.binding.service.app.persistent) {
2470                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2471                        "service connection", cr, app);
2472            }
2473        }
2474        for (int j=app.conProviders.size()-1; j>=0; j--) {
2475            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2476            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2477                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2478                        "provider reference", cpr, app);
2479            }
2480        }
2481    }
2482
2483    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2484        if (uid == Process.SYSTEM_UID) {
2485            // The system gets to run in any process.  If there are multiple
2486            // processes with the same uid, just pick the first (this
2487            // should never happen).
2488            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2489            if (procs == null) return null;
2490            final int N = procs.size();
2491            for (int i = 0; i < N; i++) {
2492                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2493            }
2494        }
2495        ProcessRecord proc = mProcessNames.get(processName, uid);
2496        if (false && proc != null && !keepIfLarge
2497                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2498                && proc.lastCachedPss >= 4000) {
2499            // Turn this condition on to cause killing to happen regularly, for testing.
2500            if (proc.baseProcessTracker != null) {
2501                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2502            }
2503            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2504                    + "k from cached");
2505        } else if (proc != null && !keepIfLarge
2506                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2507                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2508            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2509            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2510                if (proc.baseProcessTracker != null) {
2511                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2512                }
2513                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2514                        + "k from cached");
2515            }
2516        }
2517        return proc;
2518    }
2519
2520    void ensurePackageDexOpt(String packageName) {
2521        IPackageManager pm = AppGlobals.getPackageManager();
2522        try {
2523            if (pm.performDexOpt(packageName)) {
2524                mDidDexOpt = true;
2525            }
2526        } catch (RemoteException e) {
2527        }
2528    }
2529
2530    boolean isNextTransitionForward() {
2531        int transit = mWindowManager.getPendingAppTransition();
2532        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2533                || transit == AppTransition.TRANSIT_TASK_OPEN
2534                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2535    }
2536
2537    final ProcessRecord startProcessLocked(String processName,
2538            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2539            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2540            boolean isolated, boolean keepIfLarge) {
2541        ProcessRecord app;
2542        if (!isolated) {
2543            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2544        } else {
2545            // If this is an isolated process, it can't re-use an existing process.
2546            app = null;
2547        }
2548        // We don't have to do anything more if:
2549        // (1) There is an existing application record; and
2550        // (2) The caller doesn't think it is dead, OR there is no thread
2551        //     object attached to it so we know it couldn't have crashed; and
2552        // (3) There is a pid assigned to it, so it is either starting or
2553        //     already running.
2554        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2555                + " app=" + app + " knownToBeDead=" + knownToBeDead
2556                + " thread=" + (app != null ? app.thread : null)
2557                + " pid=" + (app != null ? app.pid : -1));
2558        if (app != null && app.pid > 0) {
2559            if (!knownToBeDead || app.thread == null) {
2560                // We already have the app running, or are waiting for it to
2561                // come up (we have a pid but not yet its thread), so keep it.
2562                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2563                // If this is a new package in the process, add the package to the list
2564                app.addPackage(info.packageName, mProcessStats);
2565                return app;
2566            }
2567
2568            // An application record is attached to a previous process,
2569            // clean it up now.
2570            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2571            handleAppDiedLocked(app, true, true);
2572        }
2573
2574        String hostingNameStr = hostingName != null
2575                ? hostingName.flattenToShortString() : null;
2576
2577        if (!isolated) {
2578            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2579                // If we are in the background, then check to see if this process
2580                // is bad.  If so, we will just silently fail.
2581                if (mBadProcesses.get(info.processName, info.uid) != null) {
2582                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2583                            + "/" + info.processName);
2584                    return null;
2585                }
2586            } else {
2587                // When the user is explicitly starting a process, then clear its
2588                // crash count so that we won't make it bad until they see at
2589                // least one crash dialog again, and make the process good again
2590                // if it had been bad.
2591                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2592                        + "/" + info.processName);
2593                mProcessCrashTimes.remove(info.processName, info.uid);
2594                if (mBadProcesses.get(info.processName, info.uid) != null) {
2595                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2596                            UserHandle.getUserId(info.uid), info.uid,
2597                            info.processName);
2598                    mBadProcesses.remove(info.processName, info.uid);
2599                    if (app != null) {
2600                        app.bad = false;
2601                    }
2602                }
2603            }
2604        }
2605
2606        if (app == null) {
2607            app = newProcessRecordLocked(info, processName, isolated);
2608            if (app == null) {
2609                Slog.w(TAG, "Failed making new process record for "
2610                        + processName + "/" + info.uid + " isolated=" + isolated);
2611                return null;
2612            }
2613            mProcessNames.put(processName, app.uid, app);
2614            if (isolated) {
2615                mIsolatedProcesses.put(app.uid, app);
2616            }
2617        } else {
2618            // If this is a new package in the process, add the package to the list
2619            app.addPackage(info.packageName, mProcessStats);
2620        }
2621
2622        // If the system is not ready yet, then hold off on starting this
2623        // process until it is.
2624        if (!mProcessesReady
2625                && !isAllowedWhileBooting(info)
2626                && !allowWhileBooting) {
2627            if (!mProcessesOnHold.contains(app)) {
2628                mProcessesOnHold.add(app);
2629            }
2630            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2631            return app;
2632        }
2633
2634        startProcessLocked(app, hostingType, hostingNameStr);
2635        return (app.pid != 0) ? app : null;
2636    }
2637
2638    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2639        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2640    }
2641
2642    private final void startProcessLocked(ProcessRecord app,
2643            String hostingType, String hostingNameStr) {
2644        if (app.pid > 0 && app.pid != MY_PID) {
2645            synchronized (mPidsSelfLocked) {
2646                mPidsSelfLocked.remove(app.pid);
2647                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2648            }
2649            app.setPid(0);
2650        }
2651
2652        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2653                "startProcessLocked removing on hold: " + app);
2654        mProcessesOnHold.remove(app);
2655
2656        updateCpuStats();
2657
2658        try {
2659            int uid = app.uid;
2660
2661            int[] gids = null;
2662            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2663            if (!app.isolated) {
2664                int[] permGids = null;
2665                try {
2666                    final PackageManager pm = mContext.getPackageManager();
2667                    permGids = pm.getPackageGids(app.info.packageName);
2668
2669                    if (Environment.isExternalStorageEmulated()) {
2670                        if (pm.checkPermission(
2671                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2672                                app.info.packageName) == PERMISSION_GRANTED) {
2673                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2674                        } else {
2675                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2676                        }
2677                    }
2678                } catch (PackageManager.NameNotFoundException e) {
2679                    Slog.w(TAG, "Unable to retrieve gids", e);
2680                }
2681
2682                /*
2683                 * Add shared application GID so applications can share some
2684                 * resources like shared libraries
2685                 */
2686                if (permGids == null) {
2687                    gids = new int[1];
2688                } else {
2689                    gids = new int[permGids.length + 1];
2690                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2691                }
2692                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2693            }
2694            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2695                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2696                        && mTopComponent != null
2697                        && app.processName.equals(mTopComponent.getPackageName())) {
2698                    uid = 0;
2699                }
2700                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2701                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2702                    uid = 0;
2703                }
2704            }
2705            int debugFlags = 0;
2706            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2707                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2708                // Also turn on CheckJNI for debuggable apps. It's quite
2709                // awkward to turn on otherwise.
2710                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2711            }
2712            // Run the app in safe mode if its manifest requests so or the
2713            // system is booted in safe mode.
2714            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2715                Zygote.systemInSafeMode == true) {
2716                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2717            }
2718            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2719                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2720            }
2721            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2722                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2723            }
2724            if ("1".equals(SystemProperties.get("debug.assert"))) {
2725                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2726            }
2727
2728            // Start the process.  It will either succeed and return a result containing
2729            // the PID of the new process, or else throw a RuntimeException.
2730            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2731                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2732                    app.info.targetSdkVersion, app.info.seinfo, null);
2733
2734            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2735            synchronized (bs) {
2736                if (bs.isOnBattery()) {
2737                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2738                }
2739            }
2740
2741            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2742                    UserHandle.getUserId(uid), startResult.pid, uid,
2743                    app.processName, hostingType,
2744                    hostingNameStr != null ? hostingNameStr : "");
2745
2746            if (app.persistent) {
2747                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2748            }
2749
2750            StringBuilder buf = mStringBuilder;
2751            buf.setLength(0);
2752            buf.append("Start proc ");
2753            buf.append(app.processName);
2754            buf.append(" for ");
2755            buf.append(hostingType);
2756            if (hostingNameStr != null) {
2757                buf.append(" ");
2758                buf.append(hostingNameStr);
2759            }
2760            buf.append(": pid=");
2761            buf.append(startResult.pid);
2762            buf.append(" uid=");
2763            buf.append(uid);
2764            buf.append(" gids={");
2765            if (gids != null) {
2766                for (int gi=0; gi<gids.length; gi++) {
2767                    if (gi != 0) buf.append(", ");
2768                    buf.append(gids[gi]);
2769
2770                }
2771            }
2772            buf.append("}");
2773            Slog.i(TAG, buf.toString());
2774            app.setPid(startResult.pid);
2775            app.usingWrapper = startResult.usingWrapper;
2776            app.removed = false;
2777            synchronized (mPidsSelfLocked) {
2778                this.mPidsSelfLocked.put(startResult.pid, app);
2779                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2780                msg.obj = app;
2781                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2782                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2783            }
2784            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2785                    app.processName, app.info.uid);
2786            if (app.isolated) {
2787                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2788            }
2789        } catch (RuntimeException e) {
2790            // XXX do better error recovery.
2791            app.setPid(0);
2792            Slog.e(TAG, "Failure starting process " + app.processName, e);
2793        }
2794    }
2795
2796    void updateUsageStats(ActivityRecord component, boolean resumed) {
2797        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2798        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2799        if (resumed) {
2800            mUsageStatsService.noteResumeComponent(component.realActivity);
2801            synchronized (stats) {
2802                stats.noteActivityResumedLocked(component.app.uid);
2803            }
2804        } else {
2805            mUsageStatsService.notePauseComponent(component.realActivity);
2806            synchronized (stats) {
2807                stats.noteActivityPausedLocked(component.app.uid);
2808            }
2809        }
2810    }
2811
2812    Intent getHomeIntent() {
2813        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2814        intent.setComponent(mTopComponent);
2815        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2816            intent.addCategory(Intent.CATEGORY_HOME);
2817        }
2818        return intent;
2819    }
2820
2821    boolean startHomeActivityLocked(int userId) {
2822        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2823                && mTopAction == null) {
2824            // We are running in factory test mode, but unable to find
2825            // the factory test app, so just sit around displaying the
2826            // error message and don't try to start anything.
2827            return false;
2828        }
2829        Intent intent = getHomeIntent();
2830        ActivityInfo aInfo =
2831            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2832        if (aInfo != null) {
2833            intent.setComponent(new ComponentName(
2834                    aInfo.applicationInfo.packageName, aInfo.name));
2835            // Don't do this if the home app is currently being
2836            // instrumented.
2837            aInfo = new ActivityInfo(aInfo);
2838            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2839            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2840                    aInfo.applicationInfo.uid, true);
2841            if (app == null || app.instrumentationClass == null) {
2842                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2843                mStackSupervisor.startHomeActivity(intent, aInfo);
2844            }
2845        }
2846
2847        return true;
2848    }
2849
2850    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2851        ActivityInfo ai = null;
2852        ComponentName comp = intent.getComponent();
2853        try {
2854            if (comp != null) {
2855                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2856            } else {
2857                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2858                        intent,
2859                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2860                            flags, userId);
2861
2862                if (info != null) {
2863                    ai = info.activityInfo;
2864                }
2865            }
2866        } catch (RemoteException e) {
2867            // ignore
2868        }
2869
2870        return ai;
2871    }
2872
2873    /**
2874     * Starts the "new version setup screen" if appropriate.
2875     */
2876    void startSetupActivityLocked() {
2877        // Only do this once per boot.
2878        if (mCheckedForSetup) {
2879            return;
2880        }
2881
2882        // We will show this screen if the current one is a different
2883        // version than the last one shown, and we are not running in
2884        // low-level factory test mode.
2885        final ContentResolver resolver = mContext.getContentResolver();
2886        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2887                Settings.Global.getInt(resolver,
2888                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2889            mCheckedForSetup = true;
2890
2891            // See if we should be showing the platform update setup UI.
2892            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2893            List<ResolveInfo> ris = mContext.getPackageManager()
2894                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2895
2896            // We don't allow third party apps to replace this.
2897            ResolveInfo ri = null;
2898            for (int i=0; ris != null && i<ris.size(); i++) {
2899                if ((ris.get(i).activityInfo.applicationInfo.flags
2900                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2901                    ri = ris.get(i);
2902                    break;
2903                }
2904            }
2905
2906            if (ri != null) {
2907                String vers = ri.activityInfo.metaData != null
2908                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2909                        : null;
2910                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2911                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2912                            Intent.METADATA_SETUP_VERSION);
2913                }
2914                String lastVers = Settings.Secure.getString(
2915                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2916                if (vers != null && !vers.equals(lastVers)) {
2917                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2918                    intent.setComponent(new ComponentName(
2919                            ri.activityInfo.packageName, ri.activityInfo.name));
2920                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2921                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2922                }
2923            }
2924        }
2925    }
2926
2927    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2928        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2929    }
2930
2931    void enforceNotIsolatedCaller(String caller) {
2932        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2933            throw new SecurityException("Isolated process not allowed to call " + caller);
2934        }
2935    }
2936
2937    @Override
2938    public int getFrontActivityScreenCompatMode() {
2939        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2940        synchronized (this) {
2941            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2942        }
2943    }
2944
2945    @Override
2946    public void setFrontActivityScreenCompatMode(int mode) {
2947        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2948                "setFrontActivityScreenCompatMode");
2949        synchronized (this) {
2950            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2951        }
2952    }
2953
2954    @Override
2955    public int getPackageScreenCompatMode(String packageName) {
2956        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2957        synchronized (this) {
2958            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2959        }
2960    }
2961
2962    @Override
2963    public void setPackageScreenCompatMode(String packageName, int mode) {
2964        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2965                "setPackageScreenCompatMode");
2966        synchronized (this) {
2967            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2968        }
2969    }
2970
2971    @Override
2972    public boolean getPackageAskScreenCompat(String packageName) {
2973        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2974        synchronized (this) {
2975            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2976        }
2977    }
2978
2979    @Override
2980    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2981        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2982                "setPackageAskScreenCompat");
2983        synchronized (this) {
2984            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2985        }
2986    }
2987
2988    private void dispatchProcessesChanged() {
2989        int N;
2990        synchronized (this) {
2991            N = mPendingProcessChanges.size();
2992            if (mActiveProcessChanges.length < N) {
2993                mActiveProcessChanges = new ProcessChangeItem[N];
2994            }
2995            mPendingProcessChanges.toArray(mActiveProcessChanges);
2996            mAvailProcessChanges.addAll(mPendingProcessChanges);
2997            mPendingProcessChanges.clear();
2998            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2999        }
3000
3001        int i = mProcessObservers.beginBroadcast();
3002        while (i > 0) {
3003            i--;
3004            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3005            if (observer != null) {
3006                try {
3007                    for (int j=0; j<N; j++) {
3008                        ProcessChangeItem item = mActiveProcessChanges[j];
3009                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3010                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3011                                    + item.pid + " uid=" + item.uid + ": "
3012                                    + item.foregroundActivities);
3013                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3014                                    item.foregroundActivities);
3015                        }
3016                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3017                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3018                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3019                            observer.onImportanceChanged(item.pid, item.uid,
3020                                    item.importance);
3021                        }
3022                    }
3023                } catch (RemoteException e) {
3024                }
3025            }
3026        }
3027        mProcessObservers.finishBroadcast();
3028    }
3029
3030    private void dispatchProcessDied(int pid, int uid) {
3031        int i = mProcessObservers.beginBroadcast();
3032        while (i > 0) {
3033            i--;
3034            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3035            if (observer != null) {
3036                try {
3037                    observer.onProcessDied(pid, uid);
3038                } catch (RemoteException e) {
3039                }
3040            }
3041        }
3042        mProcessObservers.finishBroadcast();
3043    }
3044
3045    final void doPendingActivityLaunchesLocked(boolean doResume) {
3046        final int N = mPendingActivityLaunches.size();
3047        if (N <= 0) {
3048            return;
3049        }
3050        for (int i=0; i<N; i++) {
3051            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3052            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3053                    doResume && i == (N-1), null);
3054        }
3055        mPendingActivityLaunches.clear();
3056    }
3057
3058    @Override
3059    public final int startActivity(IApplicationThread caller, String callingPackage,
3060            Intent intent, String resolvedType, IBinder resultTo,
3061            String resultWho, int requestCode, int startFlags,
3062            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3063        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3064                resultWho, requestCode,
3065                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3066    }
3067
3068    @Override
3069    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3070            Intent intent, String resolvedType, IBinder resultTo,
3071            String resultWho, int requestCode, int startFlags,
3072            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3073        enforceNotIsolatedCaller("startActivity");
3074        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3075                false, true, "startActivity", null);
3076        // TODO: Switch to user app stacks here.
3077        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3078                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3079                null, null, options, userId, null);
3080    }
3081
3082    @Override
3083    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3084            Intent intent, String resolvedType, IBinder resultTo,
3085            String resultWho, int requestCode, int startFlags, String profileFile,
3086            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3087        enforceNotIsolatedCaller("startActivityAndWait");
3088        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3089                false, true, "startActivityAndWait", null);
3090        WaitResult res = new WaitResult();
3091        // TODO: Switch to user app stacks here.
3092        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3093                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3094                res, null, options, UserHandle.getCallingUserId(), null);
3095        return res;
3096    }
3097
3098    @Override
3099    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3100            Intent intent, String resolvedType, IBinder resultTo,
3101            String resultWho, int requestCode, int startFlags, Configuration config,
3102            Bundle options, int userId) {
3103        enforceNotIsolatedCaller("startActivityWithConfig");
3104        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3105                false, true, "startActivityWithConfig", null);
3106        // TODO: Switch to user app stacks here.
3107        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3108                resolvedType, resultTo, resultWho, requestCode, startFlags,
3109                null, null, null, config, options, userId, null);
3110        return ret;
3111    }
3112
3113    @Override
3114    public int startActivityIntentSender(IApplicationThread caller,
3115            IntentSender intent, Intent fillInIntent, String resolvedType,
3116            IBinder resultTo, String resultWho, int requestCode,
3117            int flagsMask, int flagsValues, Bundle options) {
3118        enforceNotIsolatedCaller("startActivityIntentSender");
3119        // Refuse possible leaked file descriptors
3120        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3121            throw new IllegalArgumentException("File descriptors passed in Intent");
3122        }
3123
3124        IIntentSender sender = intent.getTarget();
3125        if (!(sender instanceof PendingIntentRecord)) {
3126            throw new IllegalArgumentException("Bad PendingIntent object");
3127        }
3128
3129        PendingIntentRecord pir = (PendingIntentRecord)sender;
3130
3131        synchronized (this) {
3132            // If this is coming from the currently resumed activity, it is
3133            // effectively saying that app switches are allowed at this point.
3134            final ActivityStack stack = getFocusedStack();
3135            if (stack.mResumedActivity != null &&
3136                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3137                mAppSwitchesAllowedTime = 0;
3138            }
3139        }
3140        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3141                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3142        return ret;
3143    }
3144
3145    @Override
3146    public boolean startNextMatchingActivity(IBinder callingActivity,
3147            Intent intent, Bundle options) {
3148        // Refuse possible leaked file descriptors
3149        if (intent != null && intent.hasFileDescriptors() == true) {
3150            throw new IllegalArgumentException("File descriptors passed in Intent");
3151        }
3152
3153        synchronized (this) {
3154            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3155            if (r == null) {
3156                ActivityOptions.abort(options);
3157                return false;
3158            }
3159            if (r.app == null || r.app.thread == null) {
3160                // The caller is not running...  d'oh!
3161                ActivityOptions.abort(options);
3162                return false;
3163            }
3164            intent = new Intent(intent);
3165            // The caller is not allowed to change the data.
3166            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3167            // And we are resetting to find the next component...
3168            intent.setComponent(null);
3169
3170            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3171
3172            ActivityInfo aInfo = null;
3173            try {
3174                List<ResolveInfo> resolves =
3175                    AppGlobals.getPackageManager().queryIntentActivities(
3176                            intent, r.resolvedType,
3177                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3178                            UserHandle.getCallingUserId());
3179
3180                // Look for the original activity in the list...
3181                final int N = resolves != null ? resolves.size() : 0;
3182                for (int i=0; i<N; i++) {
3183                    ResolveInfo rInfo = resolves.get(i);
3184                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3185                            && rInfo.activityInfo.name.equals(r.info.name)) {
3186                        // We found the current one...  the next matching is
3187                        // after it.
3188                        i++;
3189                        if (i<N) {
3190                            aInfo = resolves.get(i).activityInfo;
3191                        }
3192                        if (debug) {
3193                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3194                                    + "/" + r.info.name);
3195                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3196                                    + "/" + aInfo.name);
3197                        }
3198                        break;
3199                    }
3200                }
3201            } catch (RemoteException e) {
3202            }
3203
3204            if (aInfo == null) {
3205                // Nobody who is next!
3206                ActivityOptions.abort(options);
3207                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3208                return false;
3209            }
3210
3211            intent.setComponent(new ComponentName(
3212                    aInfo.applicationInfo.packageName, aInfo.name));
3213            intent.setFlags(intent.getFlags()&~(
3214                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3215                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3216                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3217                    Intent.FLAG_ACTIVITY_NEW_TASK));
3218
3219            // Okay now we need to start the new activity, replacing the
3220            // currently running activity.  This is a little tricky because
3221            // we want to start the new one as if the current one is finished,
3222            // but not finish the current one first so that there is no flicker.
3223            // And thus...
3224            final boolean wasFinishing = r.finishing;
3225            r.finishing = true;
3226
3227            // Propagate reply information over to the new activity.
3228            final ActivityRecord resultTo = r.resultTo;
3229            final String resultWho = r.resultWho;
3230            final int requestCode = r.requestCode;
3231            r.resultTo = null;
3232            if (resultTo != null) {
3233                resultTo.removeResultsLocked(r, resultWho, requestCode);
3234            }
3235
3236            final long origId = Binder.clearCallingIdentity();
3237            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3238                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3239                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3240                    options, false, null, null);
3241            Binder.restoreCallingIdentity(origId);
3242
3243            r.finishing = wasFinishing;
3244            if (res != ActivityManager.START_SUCCESS) {
3245                return false;
3246            }
3247            return true;
3248        }
3249    }
3250
3251    final int startActivityInPackage(int uid, String callingPackage,
3252            Intent intent, String resolvedType, IBinder resultTo,
3253            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3254                    IActivityContainer container) {
3255
3256        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3257                false, true, "startActivityInPackage", null);
3258
3259        // TODO: Switch to user app stacks here.
3260        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3261                resultTo, resultWho, requestCode, startFlags,
3262                null, null, null, null, options, userId, container);
3263        return ret;
3264    }
3265
3266    @Override
3267    public final int startActivities(IApplicationThread caller, String callingPackage,
3268            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3269            int userId) {
3270        enforceNotIsolatedCaller("startActivities");
3271        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3272                false, true, "startActivity", null);
3273        // TODO: Switch to user app stacks here.
3274        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3275                resolvedTypes, resultTo, options, userId);
3276        return ret;
3277    }
3278
3279    final int startActivitiesInPackage(int uid, String callingPackage,
3280            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3281            Bundle options, int userId) {
3282
3283        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3284                false, true, "startActivityInPackage", null);
3285        // TODO: Switch to user app stacks here.
3286        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3287                resultTo, options, userId);
3288        return ret;
3289    }
3290
3291    final void addRecentTaskLocked(TaskRecord task) {
3292        int N = mRecentTasks.size();
3293        // Quick case: check if the top-most recent task is the same.
3294        if (N > 0 && mRecentTasks.get(0) == task) {
3295            return;
3296        }
3297        // Remove any existing entries that are the same kind of task.
3298        for (int i=0; i<N; i++) {
3299            TaskRecord tr = mRecentTasks.get(i);
3300            if (task.userId == tr.userId
3301                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3302                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3303                tr.disposeThumbnail();
3304                mRecentTasks.remove(i);
3305                i--;
3306                N--;
3307                if (task.intent == null) {
3308                    // If the new recent task we are adding is not fully
3309                    // specified, then replace it with the existing recent task.
3310                    task = tr;
3311                }
3312            }
3313        }
3314        if (N >= MAX_RECENT_TASKS) {
3315            mRecentTasks.remove(N-1).disposeThumbnail();
3316        }
3317        mRecentTasks.add(0, task);
3318    }
3319
3320    @Override
3321    public void reportActivityFullyDrawn(IBinder token) {
3322        synchronized (this) {
3323            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3324            if (r == null) {
3325                return;
3326            }
3327            r.reportFullyDrawnLocked();
3328        }
3329    }
3330
3331    @Override
3332    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3333        synchronized (this) {
3334            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3335            if (r == null) {
3336                return;
3337            }
3338            final long origId = Binder.clearCallingIdentity();
3339            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3340            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3341                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3342            if (config != null) {
3343                r.frozenBeforeDestroy = true;
3344                if (!updateConfigurationLocked(config, r, false, false)) {
3345                    mStackSupervisor.resumeTopActivitiesLocked();
3346                }
3347            }
3348            Binder.restoreCallingIdentity(origId);
3349        }
3350    }
3351
3352    @Override
3353    public int getRequestedOrientation(IBinder token) {
3354        synchronized (this) {
3355            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3356            if (r == null) {
3357                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3358            }
3359            return mWindowManager.getAppOrientation(r.appToken);
3360        }
3361    }
3362
3363    /**
3364     * This is the internal entry point for handling Activity.finish().
3365     *
3366     * @param token The Binder token referencing the Activity we want to finish.
3367     * @param resultCode Result code, if any, from this Activity.
3368     * @param resultData Result data (Intent), if any, from this Activity.
3369     *
3370     * @return Returns true if the activity successfully finished, or false if it is still running.
3371     */
3372    @Override
3373    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3374        // Refuse possible leaked file descriptors
3375        if (resultData != null && resultData.hasFileDescriptors() == true) {
3376            throw new IllegalArgumentException("File descriptors passed in Intent");
3377        }
3378
3379        synchronized(this) {
3380            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3381            if (r == null) {
3382                return true;
3383            }
3384            if (mController != null) {
3385                // Find the first activity that is not finishing.
3386                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3387                if (next != null) {
3388                    // ask watcher if this is allowed
3389                    boolean resumeOK = true;
3390                    try {
3391                        resumeOK = mController.activityResuming(next.packageName);
3392                    } catch (RemoteException e) {
3393                        mController = null;
3394                        Watchdog.getInstance().setActivityController(null);
3395                    }
3396
3397                    if (!resumeOK) {
3398                        return false;
3399                    }
3400                }
3401            }
3402            final long origId = Binder.clearCallingIdentity();
3403            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3404                    resultData, "app-request", true);
3405            Binder.restoreCallingIdentity(origId);
3406            return res;
3407        }
3408    }
3409
3410    @Override
3411    public final void finishHeavyWeightApp() {
3412        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3413                != PackageManager.PERMISSION_GRANTED) {
3414            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3415                    + Binder.getCallingPid()
3416                    + ", uid=" + Binder.getCallingUid()
3417                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3418            Slog.w(TAG, msg);
3419            throw new SecurityException(msg);
3420        }
3421
3422        synchronized(this) {
3423            if (mHeavyWeightProcess == null) {
3424                return;
3425            }
3426
3427            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3428                    mHeavyWeightProcess.activities);
3429            for (int i=0; i<activities.size(); i++) {
3430                ActivityRecord r = activities.get(i);
3431                if (!r.finishing) {
3432                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3433                            null, "finish-heavy", true);
3434                }
3435            }
3436
3437            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3438                    mHeavyWeightProcess.userId, 0));
3439            mHeavyWeightProcess = null;
3440        }
3441    }
3442
3443    @Override
3444    public void crashApplication(int uid, int initialPid, String packageName,
3445            String message) {
3446        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3447                != PackageManager.PERMISSION_GRANTED) {
3448            String msg = "Permission Denial: crashApplication() from pid="
3449                    + Binder.getCallingPid()
3450                    + ", uid=" + Binder.getCallingUid()
3451                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3452            Slog.w(TAG, msg);
3453            throw new SecurityException(msg);
3454        }
3455
3456        synchronized(this) {
3457            ProcessRecord proc = null;
3458
3459            // Figure out which process to kill.  We don't trust that initialPid
3460            // still has any relation to current pids, so must scan through the
3461            // list.
3462            synchronized (mPidsSelfLocked) {
3463                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3464                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3465                    if (p.uid != uid) {
3466                        continue;
3467                    }
3468                    if (p.pid == initialPid) {
3469                        proc = p;
3470                        break;
3471                    }
3472                    if (p.pkgList.containsKey(packageName)) {
3473                        proc = p;
3474                    }
3475                }
3476            }
3477
3478            if (proc == null) {
3479                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3480                        + " initialPid=" + initialPid
3481                        + " packageName=" + packageName);
3482                return;
3483            }
3484
3485            if (proc.thread != null) {
3486                if (proc.pid == Process.myPid()) {
3487                    Log.w(TAG, "crashApplication: trying to crash self!");
3488                    return;
3489                }
3490                long ident = Binder.clearCallingIdentity();
3491                try {
3492                    proc.thread.scheduleCrash(message);
3493                } catch (RemoteException e) {
3494                }
3495                Binder.restoreCallingIdentity(ident);
3496            }
3497        }
3498    }
3499
3500    @Override
3501    public final void finishSubActivity(IBinder token, String resultWho,
3502            int requestCode) {
3503        synchronized(this) {
3504            final long origId = Binder.clearCallingIdentity();
3505            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3506            if (r != null) {
3507                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3508            }
3509            Binder.restoreCallingIdentity(origId);
3510        }
3511    }
3512
3513    @Override
3514    public boolean finishActivityAffinity(IBinder token) {
3515        synchronized(this) {
3516            final long origId = Binder.clearCallingIdentity();
3517            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3518            boolean res = false;
3519            if (r != null) {
3520                res = r.task.stack.finishActivityAffinityLocked(r);
3521            }
3522            Binder.restoreCallingIdentity(origId);
3523            return res;
3524        }
3525    }
3526
3527    @Override
3528    public boolean willActivityBeVisible(IBinder token) {
3529        synchronized(this) {
3530            ActivityStack stack = ActivityRecord.getStackLocked(token);
3531            if (stack != null) {
3532                return stack.willActivityBeVisibleLocked(token);
3533            }
3534            return false;
3535        }
3536    }
3537
3538    @Override
3539    public void overridePendingTransition(IBinder token, String packageName,
3540            int enterAnim, int exitAnim) {
3541        synchronized(this) {
3542            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3543            if (self == null) {
3544                return;
3545            }
3546
3547            final long origId = Binder.clearCallingIdentity();
3548
3549            if (self.state == ActivityState.RESUMED
3550                    || self.state == ActivityState.PAUSING) {
3551                mWindowManager.overridePendingAppTransition(packageName,
3552                        enterAnim, exitAnim, null);
3553            }
3554
3555            Binder.restoreCallingIdentity(origId);
3556        }
3557    }
3558
3559    /**
3560     * Main function for removing an existing process from the activity manager
3561     * as a result of that process going away.  Clears out all connections
3562     * to the process.
3563     */
3564    private final void handleAppDiedLocked(ProcessRecord app,
3565            boolean restarting, boolean allowRestart) {
3566        int pid = app.pid;
3567        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3568        if (!restarting) {
3569            removeLruProcessLocked(app);
3570            if (pid > 0) {
3571                ProcessList.remove(pid);
3572            }
3573        }
3574
3575        if (mProfileProc == app) {
3576            clearProfilerLocked();
3577        }
3578
3579        // Remove this application's activities from active lists.
3580        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3581
3582        app.activities.clear();
3583
3584        if (app.instrumentationClass != null) {
3585            Slog.w(TAG, "Crash of app " + app.processName
3586                  + " running instrumentation " + app.instrumentationClass);
3587            Bundle info = new Bundle();
3588            info.putString("shortMsg", "Process crashed.");
3589            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3590        }
3591
3592        if (!restarting) {
3593            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3594                // If there was nothing to resume, and we are not already
3595                // restarting this process, but there is a visible activity that
3596                // is hosted by the process...  then make sure all visible
3597                // activities are running, taking care of restarting this
3598                // process.
3599                if (hasVisibleActivities) {
3600                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3601                }
3602            }
3603        }
3604    }
3605
3606    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3607        IBinder threadBinder = thread.asBinder();
3608        // Find the application record.
3609        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3610            ProcessRecord rec = mLruProcesses.get(i);
3611            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3612                return i;
3613            }
3614        }
3615        return -1;
3616    }
3617
3618    final ProcessRecord getRecordForAppLocked(
3619            IApplicationThread thread) {
3620        if (thread == null) {
3621            return null;
3622        }
3623
3624        int appIndex = getLRURecordIndexForAppLocked(thread);
3625        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3626    }
3627
3628    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3629        // If there are no longer any background processes running,
3630        // and the app that died was not running instrumentation,
3631        // then tell everyone we are now low on memory.
3632        boolean haveBg = false;
3633        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3634            ProcessRecord rec = mLruProcesses.get(i);
3635            if (rec.thread != null
3636                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3637                haveBg = true;
3638                break;
3639            }
3640        }
3641
3642        if (!haveBg) {
3643            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3644            if (doReport) {
3645                long now = SystemClock.uptimeMillis();
3646                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3647                    doReport = false;
3648                } else {
3649                    mLastMemUsageReportTime = now;
3650                }
3651            }
3652            final ArrayList<ProcessMemInfo> memInfos
3653                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3654            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3655            long now = SystemClock.uptimeMillis();
3656            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3657                ProcessRecord rec = mLruProcesses.get(i);
3658                if (rec == dyingProc || rec.thread == null) {
3659                    continue;
3660                }
3661                if (doReport) {
3662                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3663                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3664                }
3665                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3666                    // The low memory report is overriding any current
3667                    // state for a GC request.  Make sure to do
3668                    // heavy/important/visible/foreground processes first.
3669                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3670                        rec.lastRequestedGc = 0;
3671                    } else {
3672                        rec.lastRequestedGc = rec.lastLowMemory;
3673                    }
3674                    rec.reportLowMemory = true;
3675                    rec.lastLowMemory = now;
3676                    mProcessesToGc.remove(rec);
3677                    addProcessToGcListLocked(rec);
3678                }
3679            }
3680            if (doReport) {
3681                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3682                mHandler.sendMessage(msg);
3683            }
3684            scheduleAppGcsLocked();
3685        }
3686    }
3687
3688    final void appDiedLocked(ProcessRecord app, int pid,
3689            IApplicationThread thread) {
3690
3691        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3692        synchronized (stats) {
3693            stats.noteProcessDiedLocked(app.info.uid, pid);
3694        }
3695
3696        // Clean up already done if the process has been re-started.
3697        if (app.pid == pid && app.thread != null &&
3698                app.thread.asBinder() == thread.asBinder()) {
3699            boolean doLowMem = app.instrumentationClass == null;
3700            boolean doOomAdj = doLowMem;
3701            if (!app.killedByAm) {
3702                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3703                        + ") has died.");
3704                mAllowLowerMemLevel = true;
3705            } else {
3706                // Note that we always want to do oom adj to update our state with the
3707                // new number of procs.
3708                mAllowLowerMemLevel = false;
3709                doLowMem = false;
3710            }
3711            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3712            if (DEBUG_CLEANUP) Slog.v(
3713                TAG, "Dying app: " + app + ", pid: " + pid
3714                + ", thread: " + thread.asBinder());
3715            handleAppDiedLocked(app, false, true);
3716
3717            if (doOomAdj) {
3718                updateOomAdjLocked();
3719            }
3720            if (doLowMem) {
3721                doLowMemReportIfNeededLocked(app);
3722            }
3723        } else if (app.pid != pid) {
3724            // A new process has already been started.
3725            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3726                    + ") has died and restarted (pid " + app.pid + ").");
3727            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3728        } else if (DEBUG_PROCESSES) {
3729            Slog.d(TAG, "Received spurious death notification for thread "
3730                    + thread.asBinder());
3731        }
3732    }
3733
3734    /**
3735     * If a stack trace dump file is configured, dump process stack traces.
3736     * @param clearTraces causes the dump file to be erased prior to the new
3737     *    traces being written, if true; when false, the new traces will be
3738     *    appended to any existing file content.
3739     * @param firstPids of dalvik VM processes to dump stack traces for first
3740     * @param lastPids of dalvik VM processes to dump stack traces for last
3741     * @param nativeProcs optional list of native process names to dump stack crawls
3742     * @return file containing stack traces, or null if no dump file is configured
3743     */
3744    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3745            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3746        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3747        if (tracesPath == null || tracesPath.length() == 0) {
3748            return null;
3749        }
3750
3751        File tracesFile = new File(tracesPath);
3752        try {
3753            File tracesDir = tracesFile.getParentFile();
3754            if (!tracesDir.exists()) {
3755                tracesFile.mkdirs();
3756                if (!SELinux.restorecon(tracesDir)) {
3757                    return null;
3758                }
3759            }
3760            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3761
3762            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3763            tracesFile.createNewFile();
3764            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3765        } catch (IOException e) {
3766            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3767            return null;
3768        }
3769
3770        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3771        return tracesFile;
3772    }
3773
3774    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3775            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3776        // Use a FileObserver to detect when traces finish writing.
3777        // The order of traces is considered important to maintain for legibility.
3778        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3779            @Override
3780            public synchronized void onEvent(int event, String path) { notify(); }
3781        };
3782
3783        try {
3784            observer.startWatching();
3785
3786            // First collect all of the stacks of the most important pids.
3787            if (firstPids != null) {
3788                try {
3789                    int num = firstPids.size();
3790                    for (int i = 0; i < num; i++) {
3791                        synchronized (observer) {
3792                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3793                            observer.wait(200);  // Wait for write-close, give up after 200msec
3794                        }
3795                    }
3796                } catch (InterruptedException e) {
3797                    Log.wtf(TAG, e);
3798                }
3799            }
3800
3801            // Next collect the stacks of the native pids
3802            if (nativeProcs != null) {
3803                int[] pids = Process.getPidsForCommands(nativeProcs);
3804                if (pids != null) {
3805                    for (int pid : pids) {
3806                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3807                    }
3808                }
3809            }
3810
3811            // Lastly, measure CPU usage.
3812            if (processCpuTracker != null) {
3813                processCpuTracker.init();
3814                System.gc();
3815                processCpuTracker.update();
3816                try {
3817                    synchronized (processCpuTracker) {
3818                        processCpuTracker.wait(500); // measure over 1/2 second.
3819                    }
3820                } catch (InterruptedException e) {
3821                }
3822                processCpuTracker.update();
3823
3824                // We'll take the stack crawls of just the top apps using CPU.
3825                final int N = processCpuTracker.countWorkingStats();
3826                int numProcs = 0;
3827                for (int i=0; i<N && numProcs<5; i++) {
3828                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3829                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3830                        numProcs++;
3831                        try {
3832                            synchronized (observer) {
3833                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3834                                observer.wait(200);  // Wait for write-close, give up after 200msec
3835                            }
3836                        } catch (InterruptedException e) {
3837                            Log.wtf(TAG, e);
3838                        }
3839
3840                    }
3841                }
3842            }
3843        } finally {
3844            observer.stopWatching();
3845        }
3846    }
3847
3848    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3849        if (true || IS_USER_BUILD) {
3850            return;
3851        }
3852        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3853        if (tracesPath == null || tracesPath.length() == 0) {
3854            return;
3855        }
3856
3857        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3858        StrictMode.allowThreadDiskWrites();
3859        try {
3860            final File tracesFile = new File(tracesPath);
3861            final File tracesDir = tracesFile.getParentFile();
3862            final File tracesTmp = new File(tracesDir, "__tmp__");
3863            try {
3864                if (!tracesDir.exists()) {
3865                    tracesFile.mkdirs();
3866                    if (!SELinux.restorecon(tracesDir.getPath())) {
3867                        return;
3868                    }
3869                }
3870                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3871
3872                if (tracesFile.exists()) {
3873                    tracesTmp.delete();
3874                    tracesFile.renameTo(tracesTmp);
3875                }
3876                StringBuilder sb = new StringBuilder();
3877                Time tobj = new Time();
3878                tobj.set(System.currentTimeMillis());
3879                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3880                sb.append(": ");
3881                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3882                sb.append(" since ");
3883                sb.append(msg);
3884                FileOutputStream fos = new FileOutputStream(tracesFile);
3885                fos.write(sb.toString().getBytes());
3886                if (app == null) {
3887                    fos.write("\n*** No application process!".getBytes());
3888                }
3889                fos.close();
3890                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3891            } catch (IOException e) {
3892                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3893                return;
3894            }
3895
3896            if (app != null) {
3897                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3898                firstPids.add(app.pid);
3899                dumpStackTraces(tracesPath, firstPids, null, null, null);
3900            }
3901
3902            File lastTracesFile = null;
3903            File curTracesFile = null;
3904            for (int i=9; i>=0; i--) {
3905                String name = String.format(Locale.US, "slow%02d.txt", i);
3906                curTracesFile = new File(tracesDir, name);
3907                if (curTracesFile.exists()) {
3908                    if (lastTracesFile != null) {
3909                        curTracesFile.renameTo(lastTracesFile);
3910                    } else {
3911                        curTracesFile.delete();
3912                    }
3913                }
3914                lastTracesFile = curTracesFile;
3915            }
3916            tracesFile.renameTo(curTracesFile);
3917            if (tracesTmp.exists()) {
3918                tracesTmp.renameTo(tracesFile);
3919            }
3920        } finally {
3921            StrictMode.setThreadPolicy(oldPolicy);
3922        }
3923    }
3924
3925    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3926            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3927        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3928        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3929
3930        if (mController != null) {
3931            try {
3932                // 0 == continue, -1 = kill process immediately
3933                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3934                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3935            } catch (RemoteException e) {
3936                mController = null;
3937                Watchdog.getInstance().setActivityController(null);
3938            }
3939        }
3940
3941        long anrTime = SystemClock.uptimeMillis();
3942        if (MONITOR_CPU_USAGE) {
3943            updateCpuStatsNow();
3944        }
3945
3946        synchronized (this) {
3947            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3948            if (mShuttingDown) {
3949                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3950                return;
3951            } else if (app.notResponding) {
3952                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3953                return;
3954            } else if (app.crashing) {
3955                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3956                return;
3957            }
3958
3959            // In case we come through here for the same app before completing
3960            // this one, mark as anring now so we will bail out.
3961            app.notResponding = true;
3962
3963            // Log the ANR to the event log.
3964            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3965                    app.processName, app.info.flags, annotation);
3966
3967            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3968            firstPids.add(app.pid);
3969
3970            int parentPid = app.pid;
3971            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3972            if (parentPid != app.pid) firstPids.add(parentPid);
3973
3974            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3975
3976            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3977                ProcessRecord r = mLruProcesses.get(i);
3978                if (r != null && r.thread != null) {
3979                    int pid = r.pid;
3980                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3981                        if (r.persistent) {
3982                            firstPids.add(pid);
3983                        } else {
3984                            lastPids.put(pid, Boolean.TRUE);
3985                        }
3986                    }
3987                }
3988            }
3989        }
3990
3991        // Log the ANR to the main log.
3992        StringBuilder info = new StringBuilder();
3993        info.setLength(0);
3994        info.append("ANR in ").append(app.processName);
3995        if (activity != null && activity.shortComponentName != null) {
3996            info.append(" (").append(activity.shortComponentName).append(")");
3997        }
3998        info.append("\n");
3999        info.append("PID: ").append(app.pid).append("\n");
4000        if (annotation != null) {
4001            info.append("Reason: ").append(annotation).append("\n");
4002        }
4003        if (parent != null && parent != activity) {
4004            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4005        }
4006
4007        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4008
4009        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4010                NATIVE_STACKS_OF_INTEREST);
4011
4012        String cpuInfo = null;
4013        if (MONITOR_CPU_USAGE) {
4014            updateCpuStatsNow();
4015            synchronized (mProcessCpuThread) {
4016                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4017            }
4018            info.append(processCpuTracker.printCurrentLoad());
4019            info.append(cpuInfo);
4020        }
4021
4022        info.append(processCpuTracker.printCurrentState(anrTime));
4023
4024        Slog.e(TAG, info.toString());
4025        if (tracesFile == null) {
4026            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4027            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4028        }
4029
4030        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4031                cpuInfo, tracesFile, null);
4032
4033        if (mController != null) {
4034            try {
4035                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4036                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4037                if (res != 0) {
4038                    if (res < 0 && app.pid != MY_PID) {
4039                        Process.killProcess(app.pid);
4040                    } else {
4041                        synchronized (this) {
4042                            mServices.scheduleServiceTimeoutLocked(app);
4043                        }
4044                    }
4045                    return;
4046                }
4047            } catch (RemoteException e) {
4048                mController = null;
4049                Watchdog.getInstance().setActivityController(null);
4050            }
4051        }
4052
4053        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4054        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4055                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4056
4057        synchronized (this) {
4058            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4059                killUnneededProcessLocked(app, "background ANR");
4060                return;
4061            }
4062
4063            // Set the app's notResponding state, and look up the errorReportReceiver
4064            makeAppNotRespondingLocked(app,
4065                    activity != null ? activity.shortComponentName : null,
4066                    annotation != null ? "ANR " + annotation : "ANR",
4067                    info.toString());
4068
4069            // Bring up the infamous App Not Responding dialog
4070            Message msg = Message.obtain();
4071            HashMap<String, Object> map = new HashMap<String, Object>();
4072            msg.what = SHOW_NOT_RESPONDING_MSG;
4073            msg.obj = map;
4074            msg.arg1 = aboveSystem ? 1 : 0;
4075            map.put("app", app);
4076            if (activity != null) {
4077                map.put("activity", activity);
4078            }
4079
4080            mHandler.sendMessage(msg);
4081        }
4082    }
4083
4084    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4085        if (!mLaunchWarningShown) {
4086            mLaunchWarningShown = true;
4087            mHandler.post(new Runnable() {
4088                @Override
4089                public void run() {
4090                    synchronized (ActivityManagerService.this) {
4091                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4092                        d.show();
4093                        mHandler.postDelayed(new Runnable() {
4094                            @Override
4095                            public void run() {
4096                                synchronized (ActivityManagerService.this) {
4097                                    d.dismiss();
4098                                    mLaunchWarningShown = false;
4099                                }
4100                            }
4101                        }, 4000);
4102                    }
4103                }
4104            });
4105        }
4106    }
4107
4108    @Override
4109    public boolean clearApplicationUserData(final String packageName,
4110            final IPackageDataObserver observer, int userId) {
4111        enforceNotIsolatedCaller("clearApplicationUserData");
4112        int uid = Binder.getCallingUid();
4113        int pid = Binder.getCallingPid();
4114        userId = handleIncomingUser(pid, uid,
4115                userId, false, true, "clearApplicationUserData", null);
4116        long callingId = Binder.clearCallingIdentity();
4117        try {
4118            IPackageManager pm = AppGlobals.getPackageManager();
4119            int pkgUid = -1;
4120            synchronized(this) {
4121                try {
4122                    pkgUid = pm.getPackageUid(packageName, userId);
4123                } catch (RemoteException e) {
4124                }
4125                if (pkgUid == -1) {
4126                    Slog.w(TAG, "Invalid packageName: " + packageName);
4127                    if (observer != null) {
4128                        try {
4129                            observer.onRemoveCompleted(packageName, false);
4130                        } catch (RemoteException e) {
4131                            Slog.i(TAG, "Observer no longer exists.");
4132                        }
4133                    }
4134                    return false;
4135                }
4136                if (uid == pkgUid || checkComponentPermission(
4137                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4138                        pid, uid, -1, true)
4139                        == PackageManager.PERMISSION_GRANTED) {
4140                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4141                } else {
4142                    throw new SecurityException("PID " + pid + " does not have permission "
4143                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4144                                    + " of package " + packageName);
4145                }
4146            }
4147
4148            try {
4149                // Clear application user data
4150                pm.clearApplicationUserData(packageName, observer, userId);
4151
4152                // Remove all permissions granted from/to this package
4153                removeUriPermissionsForPackageLocked(packageName, userId, true);
4154
4155                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4156                        Uri.fromParts("package", packageName, null));
4157                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4158                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4159                        null, null, 0, null, null, null, false, false, userId);
4160            } catch (RemoteException e) {
4161            }
4162        } finally {
4163            Binder.restoreCallingIdentity(callingId);
4164        }
4165        return true;
4166    }
4167
4168    @Override
4169    public void killBackgroundProcesses(final String packageName, int userId) {
4170        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4171                != PackageManager.PERMISSION_GRANTED &&
4172                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4173                        != PackageManager.PERMISSION_GRANTED) {
4174            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4175                    + Binder.getCallingPid()
4176                    + ", uid=" + Binder.getCallingUid()
4177                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4178            Slog.w(TAG, msg);
4179            throw new SecurityException(msg);
4180        }
4181
4182        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4183                userId, true, true, "killBackgroundProcesses", null);
4184        long callingId = Binder.clearCallingIdentity();
4185        try {
4186            IPackageManager pm = AppGlobals.getPackageManager();
4187            synchronized(this) {
4188                int appId = -1;
4189                try {
4190                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4191                } catch (RemoteException e) {
4192                }
4193                if (appId == -1) {
4194                    Slog.w(TAG, "Invalid packageName: " + packageName);
4195                    return;
4196                }
4197                killPackageProcessesLocked(packageName, appId, userId,
4198                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4199            }
4200        } finally {
4201            Binder.restoreCallingIdentity(callingId);
4202        }
4203    }
4204
4205    @Override
4206    public void killAllBackgroundProcesses() {
4207        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4208                != PackageManager.PERMISSION_GRANTED) {
4209            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4210                    + Binder.getCallingPid()
4211                    + ", uid=" + Binder.getCallingUid()
4212                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4213            Slog.w(TAG, msg);
4214            throw new SecurityException(msg);
4215        }
4216
4217        long callingId = Binder.clearCallingIdentity();
4218        try {
4219            synchronized(this) {
4220                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4221                final int NP = mProcessNames.getMap().size();
4222                for (int ip=0; ip<NP; ip++) {
4223                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4224                    final int NA = apps.size();
4225                    for (int ia=0; ia<NA; ia++) {
4226                        ProcessRecord app = apps.valueAt(ia);
4227                        if (app.persistent) {
4228                            // we don't kill persistent processes
4229                            continue;
4230                        }
4231                        if (app.removed) {
4232                            procs.add(app);
4233                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4234                            app.removed = true;
4235                            procs.add(app);
4236                        }
4237                    }
4238                }
4239
4240                int N = procs.size();
4241                for (int i=0; i<N; i++) {
4242                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4243                }
4244                mAllowLowerMemLevel = true;
4245                updateOomAdjLocked();
4246                doLowMemReportIfNeededLocked(null);
4247            }
4248        } finally {
4249            Binder.restoreCallingIdentity(callingId);
4250        }
4251    }
4252
4253    @Override
4254    public void forceStopPackage(final String packageName, int userId) {
4255        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4256                != PackageManager.PERMISSION_GRANTED) {
4257            String msg = "Permission Denial: forceStopPackage() from pid="
4258                    + Binder.getCallingPid()
4259                    + ", uid=" + Binder.getCallingUid()
4260                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4261            Slog.w(TAG, msg);
4262            throw new SecurityException(msg);
4263        }
4264        final int callingPid = Binder.getCallingPid();
4265        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4266                userId, true, true, "forceStopPackage", null);
4267        long callingId = Binder.clearCallingIdentity();
4268        try {
4269            IPackageManager pm = AppGlobals.getPackageManager();
4270            synchronized(this) {
4271                int[] users = userId == UserHandle.USER_ALL
4272                        ? getUsersLocked() : new int[] { userId };
4273                for (int user : users) {
4274                    int pkgUid = -1;
4275                    try {
4276                        pkgUid = pm.getPackageUid(packageName, user);
4277                    } catch (RemoteException e) {
4278                    }
4279                    if (pkgUid == -1) {
4280                        Slog.w(TAG, "Invalid packageName: " + packageName);
4281                        continue;
4282                    }
4283                    try {
4284                        pm.setPackageStoppedState(packageName, true, user);
4285                    } catch (RemoteException e) {
4286                    } catch (IllegalArgumentException e) {
4287                        Slog.w(TAG, "Failed trying to unstop package "
4288                                + packageName + ": " + e);
4289                    }
4290                    if (isUserRunningLocked(user, false)) {
4291                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4292                    }
4293                }
4294            }
4295        } finally {
4296            Binder.restoreCallingIdentity(callingId);
4297        }
4298    }
4299
4300    /*
4301     * The pkg name and app id have to be specified.
4302     */
4303    @Override
4304    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4305        if (pkg == null) {
4306            return;
4307        }
4308        // Make sure the uid is valid.
4309        if (appid < 0) {
4310            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4311            return;
4312        }
4313        int callerUid = Binder.getCallingUid();
4314        // Only the system server can kill an application
4315        if (callerUid == Process.SYSTEM_UID) {
4316            // Post an aysnc message to kill the application
4317            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4318            msg.arg1 = appid;
4319            msg.arg2 = 0;
4320            Bundle bundle = new Bundle();
4321            bundle.putString("pkg", pkg);
4322            bundle.putString("reason", reason);
4323            msg.obj = bundle;
4324            mHandler.sendMessage(msg);
4325        } else {
4326            throw new SecurityException(callerUid + " cannot kill pkg: " +
4327                    pkg);
4328        }
4329    }
4330
4331    @Override
4332    public void closeSystemDialogs(String reason) {
4333        enforceNotIsolatedCaller("closeSystemDialogs");
4334
4335        final int pid = Binder.getCallingPid();
4336        final int uid = Binder.getCallingUid();
4337        final long origId = Binder.clearCallingIdentity();
4338        try {
4339            synchronized (this) {
4340                // Only allow this from foreground processes, so that background
4341                // applications can't abuse it to prevent system UI from being shown.
4342                if (uid >= Process.FIRST_APPLICATION_UID) {
4343                    ProcessRecord proc;
4344                    synchronized (mPidsSelfLocked) {
4345                        proc = mPidsSelfLocked.get(pid);
4346                    }
4347                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4348                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4349                                + " from background process " + proc);
4350                        return;
4351                    }
4352                }
4353                closeSystemDialogsLocked(reason);
4354            }
4355        } finally {
4356            Binder.restoreCallingIdentity(origId);
4357        }
4358    }
4359
4360    void closeSystemDialogsLocked(String reason) {
4361        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4362        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4363                | Intent.FLAG_RECEIVER_FOREGROUND);
4364        if (reason != null) {
4365            intent.putExtra("reason", reason);
4366        }
4367        mWindowManager.closeSystemDialogs(reason);
4368
4369        mStackSupervisor.closeSystemDialogsLocked();
4370
4371        broadcastIntentLocked(null, null, intent, null,
4372                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4373                Process.SYSTEM_UID, UserHandle.USER_ALL);
4374    }
4375
4376    @Override
4377    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4378        enforceNotIsolatedCaller("getProcessMemoryInfo");
4379        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4380        for (int i=pids.length-1; i>=0; i--) {
4381            ProcessRecord proc;
4382            int oomAdj;
4383            synchronized (this) {
4384                synchronized (mPidsSelfLocked) {
4385                    proc = mPidsSelfLocked.get(pids[i]);
4386                    oomAdj = proc != null ? proc.setAdj : 0;
4387                }
4388            }
4389            infos[i] = new Debug.MemoryInfo();
4390            Debug.getMemoryInfo(pids[i], infos[i]);
4391            if (proc != null) {
4392                synchronized (this) {
4393                    if (proc.thread != null && proc.setAdj == oomAdj) {
4394                        // Record this for posterity if the process has been stable.
4395                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4396                                infos[i].getTotalUss(), false, proc.pkgList);
4397                    }
4398                }
4399            }
4400        }
4401        return infos;
4402    }
4403
4404    @Override
4405    public long[] getProcessPss(int[] pids) {
4406        enforceNotIsolatedCaller("getProcessPss");
4407        long[] pss = new long[pids.length];
4408        for (int i=pids.length-1; i>=0; i--) {
4409            ProcessRecord proc;
4410            int oomAdj;
4411            synchronized (this) {
4412                synchronized (mPidsSelfLocked) {
4413                    proc = mPidsSelfLocked.get(pids[i]);
4414                    oomAdj = proc != null ? proc.setAdj : 0;
4415                }
4416            }
4417            long[] tmpUss = new long[1];
4418            pss[i] = Debug.getPss(pids[i], tmpUss);
4419            if (proc != null) {
4420                synchronized (this) {
4421                    if (proc.thread != null && proc.setAdj == oomAdj) {
4422                        // Record this for posterity if the process has been stable.
4423                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4424                    }
4425                }
4426            }
4427        }
4428        return pss;
4429    }
4430
4431    @Override
4432    public void killApplicationProcess(String processName, int uid) {
4433        if (processName == null) {
4434            return;
4435        }
4436
4437        int callerUid = Binder.getCallingUid();
4438        // Only the system server can kill an application
4439        if (callerUid == Process.SYSTEM_UID) {
4440            synchronized (this) {
4441                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4442                if (app != null && app.thread != null) {
4443                    try {
4444                        app.thread.scheduleSuicide();
4445                    } catch (RemoteException e) {
4446                        // If the other end already died, then our work here is done.
4447                    }
4448                } else {
4449                    Slog.w(TAG, "Process/uid not found attempting kill of "
4450                            + processName + " / " + uid);
4451                }
4452            }
4453        } else {
4454            throw new SecurityException(callerUid + " cannot kill app process: " +
4455                    processName);
4456        }
4457    }
4458
4459    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4460        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4461                false, true, false, false, UserHandle.getUserId(uid), reason);
4462        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4463                Uri.fromParts("package", packageName, null));
4464        if (!mProcessesReady) {
4465            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4466                    | Intent.FLAG_RECEIVER_FOREGROUND);
4467        }
4468        intent.putExtra(Intent.EXTRA_UID, uid);
4469        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4470        broadcastIntentLocked(null, null, intent,
4471                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4472                false, false,
4473                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4474    }
4475
4476    private void forceStopUserLocked(int userId, String reason) {
4477        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4478        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4479        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4480                | Intent.FLAG_RECEIVER_FOREGROUND);
4481        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4482        broadcastIntentLocked(null, null, intent,
4483                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4484                false, false,
4485                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4486    }
4487
4488    private final boolean killPackageProcessesLocked(String packageName, int appId,
4489            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4490            boolean doit, boolean evenPersistent, String reason) {
4491        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4492
4493        // Remove all processes this package may have touched: all with the
4494        // same UID (except for the system or root user), and all whose name
4495        // matches the package name.
4496        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4497        final int NP = mProcessNames.getMap().size();
4498        for (int ip=0; ip<NP; ip++) {
4499            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4500            final int NA = apps.size();
4501            for (int ia=0; ia<NA; ia++) {
4502                ProcessRecord app = apps.valueAt(ia);
4503                if (app.persistent && !evenPersistent) {
4504                    // we don't kill persistent processes
4505                    continue;
4506                }
4507                if (app.removed) {
4508                    if (doit) {
4509                        procs.add(app);
4510                    }
4511                    continue;
4512                }
4513
4514                // Skip process if it doesn't meet our oom adj requirement.
4515                if (app.setAdj < minOomAdj) {
4516                    continue;
4517                }
4518
4519                // If no package is specified, we call all processes under the
4520                // give user id.
4521                if (packageName == null) {
4522                    if (app.userId != userId) {
4523                        continue;
4524                    }
4525                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4526                        continue;
4527                    }
4528                // Package has been specified, we want to hit all processes
4529                // that match it.  We need to qualify this by the processes
4530                // that are running under the specified app and user ID.
4531                } else {
4532                    if (UserHandle.getAppId(app.uid) != appId) {
4533                        continue;
4534                    }
4535                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4536                        continue;
4537                    }
4538                    if (!app.pkgList.containsKey(packageName)) {
4539                        continue;
4540                    }
4541                }
4542
4543                // Process has passed all conditions, kill it!
4544                if (!doit) {
4545                    return true;
4546                }
4547                app.removed = true;
4548                procs.add(app);
4549            }
4550        }
4551
4552        int N = procs.size();
4553        for (int i=0; i<N; i++) {
4554            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4555        }
4556        updateOomAdjLocked();
4557        return N > 0;
4558    }
4559
4560    private final boolean forceStopPackageLocked(String name, int appId,
4561            boolean callerWillRestart, boolean purgeCache, boolean doit,
4562            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4563        int i;
4564        int N;
4565
4566        if (userId == UserHandle.USER_ALL && name == null) {
4567            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4568        }
4569
4570        if (appId < 0 && name != null) {
4571            try {
4572                appId = UserHandle.getAppId(
4573                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4574            } catch (RemoteException e) {
4575            }
4576        }
4577
4578        if (doit) {
4579            if (name != null) {
4580                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4581                        + " user=" + userId + ": " + reason);
4582            } else {
4583                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4584            }
4585
4586            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4587            for (int ip=pmap.size()-1; ip>=0; ip--) {
4588                SparseArray<Long> ba = pmap.valueAt(ip);
4589                for (i=ba.size()-1; i>=0; i--) {
4590                    boolean remove = false;
4591                    final int entUid = ba.keyAt(i);
4592                    if (name != null) {
4593                        if (userId == UserHandle.USER_ALL) {
4594                            if (UserHandle.getAppId(entUid) == appId) {
4595                                remove = true;
4596                            }
4597                        } else {
4598                            if (entUid == UserHandle.getUid(userId, appId)) {
4599                                remove = true;
4600                            }
4601                        }
4602                    } else if (UserHandle.getUserId(entUid) == userId) {
4603                        remove = true;
4604                    }
4605                    if (remove) {
4606                        ba.removeAt(i);
4607                    }
4608                }
4609                if (ba.size() == 0) {
4610                    pmap.removeAt(ip);
4611                }
4612            }
4613        }
4614
4615        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4616                -100, callerWillRestart, true, doit, evenPersistent,
4617                name == null ? ("stop user " + userId) : ("stop " + name));
4618
4619        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4620            if (!doit) {
4621                return true;
4622            }
4623            didSomething = true;
4624        }
4625
4626        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4627            if (!doit) {
4628                return true;
4629            }
4630            didSomething = true;
4631        }
4632
4633        if (name == null) {
4634            // Remove all sticky broadcasts from this user.
4635            mStickyBroadcasts.remove(userId);
4636        }
4637
4638        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4639        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4640                userId, providers)) {
4641            if (!doit) {
4642                return true;
4643            }
4644            didSomething = true;
4645        }
4646        N = providers.size();
4647        for (i=0; i<N; i++) {
4648            removeDyingProviderLocked(null, providers.get(i), true);
4649        }
4650
4651        // Remove transient permissions granted from/to this package/user
4652        removeUriPermissionsForPackageLocked(name, userId, false);
4653
4654        if (name == null || uninstalling) {
4655            // Remove pending intents.  For now we only do this when force
4656            // stopping users, because we have some problems when doing this
4657            // for packages -- app widgets are not currently cleaned up for
4658            // such packages, so they can be left with bad pending intents.
4659            if (mIntentSenderRecords.size() > 0) {
4660                Iterator<WeakReference<PendingIntentRecord>> it
4661                        = mIntentSenderRecords.values().iterator();
4662                while (it.hasNext()) {
4663                    WeakReference<PendingIntentRecord> wpir = it.next();
4664                    if (wpir == null) {
4665                        it.remove();
4666                        continue;
4667                    }
4668                    PendingIntentRecord pir = wpir.get();
4669                    if (pir == null) {
4670                        it.remove();
4671                        continue;
4672                    }
4673                    if (name == null) {
4674                        // Stopping user, remove all objects for the user.
4675                        if (pir.key.userId != userId) {
4676                            // Not the same user, skip it.
4677                            continue;
4678                        }
4679                    } else {
4680                        if (UserHandle.getAppId(pir.uid) != appId) {
4681                            // Different app id, skip it.
4682                            continue;
4683                        }
4684                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4685                            // Different user, skip it.
4686                            continue;
4687                        }
4688                        if (!pir.key.packageName.equals(name)) {
4689                            // Different package, skip it.
4690                            continue;
4691                        }
4692                    }
4693                    if (!doit) {
4694                        return true;
4695                    }
4696                    didSomething = true;
4697                    it.remove();
4698                    pir.canceled = true;
4699                    if (pir.key.activity != null) {
4700                        pir.key.activity.pendingResults.remove(pir.ref);
4701                    }
4702                }
4703            }
4704        }
4705
4706        if (doit) {
4707            if (purgeCache && name != null) {
4708                AttributeCache ac = AttributeCache.instance();
4709                if (ac != null) {
4710                    ac.removePackage(name);
4711                }
4712            }
4713            if (mBooted) {
4714                mStackSupervisor.resumeTopActivitiesLocked();
4715                mStackSupervisor.scheduleIdleLocked();
4716            }
4717        }
4718
4719        return didSomething;
4720    }
4721
4722    private final boolean removeProcessLocked(ProcessRecord app,
4723            boolean callerWillRestart, boolean allowRestart, String reason) {
4724        final String name = app.processName;
4725        final int uid = app.uid;
4726        if (DEBUG_PROCESSES) Slog.d(
4727            TAG, "Force removing proc " + app.toShortString() + " (" + name
4728            + "/" + uid + ")");
4729
4730        mProcessNames.remove(name, uid);
4731        mIsolatedProcesses.remove(app.uid);
4732        if (mHeavyWeightProcess == app) {
4733            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4734                    mHeavyWeightProcess.userId, 0));
4735            mHeavyWeightProcess = null;
4736        }
4737        boolean needRestart = false;
4738        if (app.pid > 0 && app.pid != MY_PID) {
4739            int pid = app.pid;
4740            synchronized (mPidsSelfLocked) {
4741                mPidsSelfLocked.remove(pid);
4742                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4743            }
4744            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4745                    app.processName, app.info.uid);
4746            if (app.isolated) {
4747                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4748            }
4749            killUnneededProcessLocked(app, reason);
4750            handleAppDiedLocked(app, true, allowRestart);
4751            removeLruProcessLocked(app);
4752
4753            if (app.persistent && !app.isolated) {
4754                if (!callerWillRestart) {
4755                    addAppLocked(app.info, false);
4756                } else {
4757                    needRestart = true;
4758                }
4759            }
4760        } else {
4761            mRemovedProcesses.add(app);
4762        }
4763
4764        return needRestart;
4765    }
4766
4767    private final void processStartTimedOutLocked(ProcessRecord app) {
4768        final int pid = app.pid;
4769        boolean gone = false;
4770        synchronized (mPidsSelfLocked) {
4771            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4772            if (knownApp != null && knownApp.thread == null) {
4773                mPidsSelfLocked.remove(pid);
4774                gone = true;
4775            }
4776        }
4777
4778        if (gone) {
4779            Slog.w(TAG, "Process " + app + " failed to attach");
4780            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4781                    pid, app.uid, app.processName);
4782            mProcessNames.remove(app.processName, app.uid);
4783            mIsolatedProcesses.remove(app.uid);
4784            if (mHeavyWeightProcess == app) {
4785                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4786                        mHeavyWeightProcess.userId, 0));
4787                mHeavyWeightProcess = null;
4788            }
4789            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4790                    app.processName, app.info.uid);
4791            if (app.isolated) {
4792                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4793            }
4794            // Take care of any launching providers waiting for this process.
4795            checkAppInLaunchingProvidersLocked(app, true);
4796            // Take care of any services that are waiting for the process.
4797            mServices.processStartTimedOutLocked(app);
4798            killUnneededProcessLocked(app, "start timeout");
4799            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4800                Slog.w(TAG, "Unattached app died before backup, skipping");
4801                try {
4802                    IBackupManager bm = IBackupManager.Stub.asInterface(
4803                            ServiceManager.getService(Context.BACKUP_SERVICE));
4804                    bm.agentDisconnected(app.info.packageName);
4805                } catch (RemoteException e) {
4806                    // Can't happen; the backup manager is local
4807                }
4808            }
4809            if (isPendingBroadcastProcessLocked(pid)) {
4810                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4811                skipPendingBroadcastLocked(pid);
4812            }
4813        } else {
4814            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4815        }
4816    }
4817
4818    private final boolean attachApplicationLocked(IApplicationThread thread,
4819            int pid) {
4820
4821        // Find the application record that is being attached...  either via
4822        // the pid if we are running in multiple processes, or just pull the
4823        // next app record if we are emulating process with anonymous threads.
4824        ProcessRecord app;
4825        if (pid != MY_PID && pid >= 0) {
4826            synchronized (mPidsSelfLocked) {
4827                app = mPidsSelfLocked.get(pid);
4828            }
4829        } else {
4830            app = null;
4831        }
4832
4833        if (app == null) {
4834            Slog.w(TAG, "No pending application record for pid " + pid
4835                    + " (IApplicationThread " + thread + "); dropping process");
4836            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4837            if (pid > 0 && pid != MY_PID) {
4838                Process.killProcessQuiet(pid);
4839            } else {
4840                try {
4841                    thread.scheduleExit();
4842                } catch (Exception e) {
4843                    // Ignore exceptions.
4844                }
4845            }
4846            return false;
4847        }
4848
4849        // If this application record is still attached to a previous
4850        // process, clean it up now.
4851        if (app.thread != null) {
4852            handleAppDiedLocked(app, true, true);
4853        }
4854
4855        // Tell the process all about itself.
4856
4857        if (localLOGV) Slog.v(
4858                TAG, "Binding process pid " + pid + " to record " + app);
4859
4860        final String processName = app.processName;
4861        try {
4862            AppDeathRecipient adr = new AppDeathRecipient(
4863                    app, pid, thread);
4864            thread.asBinder().linkToDeath(adr, 0);
4865            app.deathRecipient = adr;
4866        } catch (RemoteException e) {
4867            app.resetPackageList(mProcessStats);
4868            startProcessLocked(app, "link fail", processName);
4869            return false;
4870        }
4871
4872        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4873
4874        app.makeActive(thread, mProcessStats);
4875        app.curAdj = app.setAdj = -100;
4876        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4877        app.forcingToForeground = null;
4878        updateProcessForegroundLocked(app, false, false);
4879        app.hasShownUi = false;
4880        app.debugging = false;
4881        app.cached = false;
4882
4883        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4884
4885        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4886        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4887
4888        if (!normalMode) {
4889            Slog.i(TAG, "Launching preboot mode app: " + app);
4890        }
4891
4892        if (localLOGV) Slog.v(
4893            TAG, "New app record " + app
4894            + " thread=" + thread.asBinder() + " pid=" + pid);
4895        try {
4896            int testMode = IApplicationThread.DEBUG_OFF;
4897            if (mDebugApp != null && mDebugApp.equals(processName)) {
4898                testMode = mWaitForDebugger
4899                    ? IApplicationThread.DEBUG_WAIT
4900                    : IApplicationThread.DEBUG_ON;
4901                app.debugging = true;
4902                if (mDebugTransient) {
4903                    mDebugApp = mOrigDebugApp;
4904                    mWaitForDebugger = mOrigWaitForDebugger;
4905                }
4906            }
4907            String profileFile = app.instrumentationProfileFile;
4908            ParcelFileDescriptor profileFd = null;
4909            boolean profileAutoStop = false;
4910            if (mProfileApp != null && mProfileApp.equals(processName)) {
4911                mProfileProc = app;
4912                profileFile = mProfileFile;
4913                profileFd = mProfileFd;
4914                profileAutoStop = mAutoStopProfiler;
4915            }
4916            boolean enableOpenGlTrace = false;
4917            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4918                enableOpenGlTrace = true;
4919                mOpenGlTraceApp = null;
4920            }
4921
4922            // If the app is being launched for restore or full backup, set it up specially
4923            boolean isRestrictedBackupMode = false;
4924            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4925                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4926                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4927                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4928            }
4929
4930            ensurePackageDexOpt(app.instrumentationInfo != null
4931                    ? app.instrumentationInfo.packageName
4932                    : app.info.packageName);
4933            if (app.instrumentationClass != null) {
4934                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4935            }
4936            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4937                    + processName + " with config " + mConfiguration);
4938            ApplicationInfo appInfo = app.instrumentationInfo != null
4939                    ? app.instrumentationInfo : app.info;
4940            app.compat = compatibilityInfoForPackageLocked(appInfo);
4941            if (profileFd != null) {
4942                profileFd = profileFd.dup();
4943            }
4944            thread.bindApplication(processName, appInfo, providers,
4945                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4946                    app.instrumentationArguments, app.instrumentationWatcher,
4947                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4948                    isRestrictedBackupMode || !normalMode, app.persistent,
4949                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4950                    mCoreSettingsObserver.getCoreSettingsLocked());
4951            updateLruProcessLocked(app, false, null);
4952            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4953        } catch (Exception e) {
4954            // todo: Yikes!  What should we do?  For now we will try to
4955            // start another process, but that could easily get us in
4956            // an infinite loop of restarting processes...
4957            Slog.w(TAG, "Exception thrown during bind!", e);
4958
4959            app.resetPackageList(mProcessStats);
4960            app.unlinkDeathRecipient();
4961            startProcessLocked(app, "bind fail", processName);
4962            return false;
4963        }
4964
4965        // Remove this record from the list of starting applications.
4966        mPersistentStartingProcesses.remove(app);
4967        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4968                "Attach application locked removing on hold: " + app);
4969        mProcessesOnHold.remove(app);
4970
4971        boolean badApp = false;
4972        boolean didSomething = false;
4973
4974        // See if the top visible activity is waiting to run in this process...
4975        if (normalMode) {
4976            try {
4977                if (mStackSupervisor.attachApplicationLocked(app)) {
4978                    didSomething = true;
4979                }
4980            } catch (Exception e) {
4981                badApp = true;
4982            }
4983        }
4984
4985        // Find any services that should be running in this process...
4986        if (!badApp) {
4987            try {
4988                didSomething |= mServices.attachApplicationLocked(app, processName);
4989            } catch (Exception e) {
4990                badApp = true;
4991            }
4992        }
4993
4994        // Check if a next-broadcast receiver is in this process...
4995        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4996            try {
4997                didSomething |= sendPendingBroadcastsLocked(app);
4998            } catch (Exception e) {
4999                // If the app died trying to launch the receiver we declare it 'bad'
5000                badApp = true;
5001            }
5002        }
5003
5004        // Check whether the next backup agent is in this process...
5005        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5006            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5007            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5008            try {
5009                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5010                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5011                        mBackupTarget.backupMode);
5012            } catch (Exception e) {
5013                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5014                e.printStackTrace();
5015            }
5016        }
5017
5018        if (badApp) {
5019            // todo: Also need to kill application to deal with all
5020            // kinds of exceptions.
5021            handleAppDiedLocked(app, false, true);
5022            return false;
5023        }
5024
5025        if (!didSomething) {
5026            updateOomAdjLocked();
5027        }
5028
5029        return true;
5030    }
5031
5032    @Override
5033    public final void attachApplication(IApplicationThread thread) {
5034        synchronized (this) {
5035            int callingPid = Binder.getCallingPid();
5036            final long origId = Binder.clearCallingIdentity();
5037            attachApplicationLocked(thread, callingPid);
5038            Binder.restoreCallingIdentity(origId);
5039        }
5040    }
5041
5042    @Override
5043    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5044        final long origId = Binder.clearCallingIdentity();
5045        synchronized (this) {
5046            ActivityStack stack = ActivityRecord.getStackLocked(token);
5047            if (stack != null) {
5048                ActivityRecord r =
5049                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5050                if (stopProfiling) {
5051                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5052                        try {
5053                            mProfileFd.close();
5054                        } catch (IOException e) {
5055                        }
5056                        clearProfilerLocked();
5057                    }
5058                }
5059            }
5060        }
5061        Binder.restoreCallingIdentity(origId);
5062    }
5063
5064    void enableScreenAfterBoot() {
5065        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5066                SystemClock.uptimeMillis());
5067        mWindowManager.enableScreenAfterBoot();
5068
5069        synchronized (this) {
5070            updateEventDispatchingLocked();
5071        }
5072    }
5073
5074    @Override
5075    public void showBootMessage(final CharSequence msg, final boolean always) {
5076        enforceNotIsolatedCaller("showBootMessage");
5077        mWindowManager.showBootMessage(msg, always);
5078    }
5079
5080    @Override
5081    public void dismissKeyguardOnNextActivity() {
5082        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5083        final long token = Binder.clearCallingIdentity();
5084        try {
5085            synchronized (this) {
5086                if (DEBUG_LOCKSCREEN) logLockScreen("");
5087                if (mLockScreenShown) {
5088                    mLockScreenShown = false;
5089                    comeOutOfSleepIfNeededLocked();
5090                }
5091                mStackSupervisor.setDismissKeyguard(true);
5092            }
5093        } finally {
5094            Binder.restoreCallingIdentity(token);
5095        }
5096    }
5097
5098    final void finishBooting() {
5099        IntentFilter pkgFilter = new IntentFilter();
5100        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5101        pkgFilter.addDataScheme("package");
5102        mContext.registerReceiver(new BroadcastReceiver() {
5103            @Override
5104            public void onReceive(Context context, Intent intent) {
5105                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5106                if (pkgs != null) {
5107                    for (String pkg : pkgs) {
5108                        synchronized (ActivityManagerService.this) {
5109                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5110                                    "finished booting")) {
5111                                setResultCode(Activity.RESULT_OK);
5112                                return;
5113                            }
5114                        }
5115                    }
5116                }
5117            }
5118        }, pkgFilter);
5119
5120        synchronized (this) {
5121            // Ensure that any processes we had put on hold are now started
5122            // up.
5123            final int NP = mProcessesOnHold.size();
5124            if (NP > 0) {
5125                ArrayList<ProcessRecord> procs =
5126                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5127                for (int ip=0; ip<NP; ip++) {
5128                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5129                            + procs.get(ip));
5130                    startProcessLocked(procs.get(ip), "on-hold", null);
5131                }
5132            }
5133
5134            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5135                // Start looking for apps that are abusing wake locks.
5136                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5137                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5138                // Tell anyone interested that we are done booting!
5139                SystemProperties.set("sys.boot_completed", "1");
5140                SystemProperties.set("dev.bootcomplete", "1");
5141                for (int i=0; i<mStartedUsers.size(); i++) {
5142                    UserStartedState uss = mStartedUsers.valueAt(i);
5143                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5144                        uss.mState = UserStartedState.STATE_RUNNING;
5145                        final int userId = mStartedUsers.keyAt(i);
5146                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5147                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5148                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5149                        broadcastIntentLocked(null, null, intent, null,
5150                                new IIntentReceiver.Stub() {
5151                                    @Override
5152                                    public void performReceive(Intent intent, int resultCode,
5153                                            String data, Bundle extras, boolean ordered,
5154                                            boolean sticky, int sendingUser) {
5155                                        synchronized (ActivityManagerService.this) {
5156                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5157                                                    true, false);
5158                                        }
5159                                    }
5160                                },
5161                                0, null, null,
5162                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5163                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5164                                userId);
5165                    }
5166                }
5167            }
5168        }
5169    }
5170
5171    final void ensureBootCompleted() {
5172        boolean booting;
5173        boolean enableScreen;
5174        synchronized (this) {
5175            booting = mBooting;
5176            mBooting = false;
5177            enableScreen = !mBooted;
5178            mBooted = true;
5179        }
5180
5181        if (booting) {
5182            finishBooting();
5183        }
5184
5185        if (enableScreen) {
5186            enableScreenAfterBoot();
5187        }
5188    }
5189
5190    @Override
5191    public final void activityResumed(IBinder token) {
5192        final long origId = Binder.clearCallingIdentity();
5193        synchronized(this) {
5194            ActivityStack stack = ActivityRecord.getStackLocked(token);
5195            if (stack != null) {
5196                ActivityRecord.activityResumedLocked(token);
5197            }
5198        }
5199        Binder.restoreCallingIdentity(origId);
5200    }
5201
5202    @Override
5203    public final void activityPaused(IBinder token) {
5204        final long origId = Binder.clearCallingIdentity();
5205        synchronized(this) {
5206            ActivityStack stack = ActivityRecord.getStackLocked(token);
5207            if (stack != null) {
5208                stack.activityPausedLocked(token, false);
5209            }
5210        }
5211        Binder.restoreCallingIdentity(origId);
5212    }
5213
5214    @Override
5215    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5216            CharSequence description) {
5217        if (localLOGV) Slog.v(
5218            TAG, "Activity stopped: token=" + token);
5219
5220        // Refuse possible leaked file descriptors
5221        if (icicle != null && icicle.hasFileDescriptors()) {
5222            throw new IllegalArgumentException("File descriptors passed in Bundle");
5223        }
5224
5225        ActivityRecord r = null;
5226
5227        final long origId = Binder.clearCallingIdentity();
5228
5229        synchronized (this) {
5230            r = ActivityRecord.isInStackLocked(token);
5231            if (r != null) {
5232                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5233            }
5234        }
5235
5236        if (r != null) {
5237            sendPendingThumbnail(r, null, null, null, false);
5238        }
5239
5240        trimApplications();
5241
5242        Binder.restoreCallingIdentity(origId);
5243    }
5244
5245    @Override
5246    public final void activityDestroyed(IBinder token) {
5247        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5248        synchronized (this) {
5249            ActivityStack stack = ActivityRecord.getStackLocked(token);
5250            if (stack != null) {
5251                stack.activityDestroyedLocked(token);
5252            }
5253        }
5254    }
5255
5256    @Override
5257    public String getCallingPackage(IBinder token) {
5258        synchronized (this) {
5259            ActivityRecord r = getCallingRecordLocked(token);
5260            return r != null ? r.info.packageName : null;
5261        }
5262    }
5263
5264    @Override
5265    public ComponentName getCallingActivity(IBinder token) {
5266        synchronized (this) {
5267            ActivityRecord r = getCallingRecordLocked(token);
5268            return r != null ? r.intent.getComponent() : null;
5269        }
5270    }
5271
5272    private ActivityRecord getCallingRecordLocked(IBinder token) {
5273        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5274        if (r == null) {
5275            return null;
5276        }
5277        return r.resultTo;
5278    }
5279
5280    @Override
5281    public ComponentName getActivityClassForToken(IBinder token) {
5282        synchronized(this) {
5283            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5284            if (r == null) {
5285                return null;
5286            }
5287            return r.intent.getComponent();
5288        }
5289    }
5290
5291    @Override
5292    public String getPackageForToken(IBinder token) {
5293        synchronized(this) {
5294            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5295            if (r == null) {
5296                return null;
5297            }
5298            return r.packageName;
5299        }
5300    }
5301
5302    @Override
5303    public IIntentSender getIntentSender(int type,
5304            String packageName, IBinder token, String resultWho,
5305            int requestCode, Intent[] intents, String[] resolvedTypes,
5306            int flags, Bundle options, int userId) {
5307        enforceNotIsolatedCaller("getIntentSender");
5308        // Refuse possible leaked file descriptors
5309        if (intents != null) {
5310            if (intents.length < 1) {
5311                throw new IllegalArgumentException("Intents array length must be >= 1");
5312            }
5313            for (int i=0; i<intents.length; i++) {
5314                Intent intent = intents[i];
5315                if (intent != null) {
5316                    if (intent.hasFileDescriptors()) {
5317                        throw new IllegalArgumentException("File descriptors passed in Intent");
5318                    }
5319                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5320                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5321                        throw new IllegalArgumentException(
5322                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5323                    }
5324                    intents[i] = new Intent(intent);
5325                }
5326            }
5327            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5328                throw new IllegalArgumentException(
5329                        "Intent array length does not match resolvedTypes length");
5330            }
5331        }
5332        if (options != null) {
5333            if (options.hasFileDescriptors()) {
5334                throw new IllegalArgumentException("File descriptors passed in options");
5335            }
5336        }
5337
5338        synchronized(this) {
5339            int callingUid = Binder.getCallingUid();
5340            int origUserId = userId;
5341            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5342                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5343                    "getIntentSender", null);
5344            if (origUserId == UserHandle.USER_CURRENT) {
5345                // We don't want to evaluate this until the pending intent is
5346                // actually executed.  However, we do want to always do the
5347                // security checking for it above.
5348                userId = UserHandle.USER_CURRENT;
5349            }
5350            try {
5351                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5352                    int uid = AppGlobals.getPackageManager()
5353                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5354                    if (!UserHandle.isSameApp(callingUid, uid)) {
5355                        String msg = "Permission Denial: getIntentSender() from pid="
5356                            + Binder.getCallingPid()
5357                            + ", uid=" + Binder.getCallingUid()
5358                            + ", (need uid=" + uid + ")"
5359                            + " is not allowed to send as package " + packageName;
5360                        Slog.w(TAG, msg);
5361                        throw new SecurityException(msg);
5362                    }
5363                }
5364
5365                return getIntentSenderLocked(type, packageName, callingUid, userId,
5366                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5367
5368            } catch (RemoteException e) {
5369                throw new SecurityException(e);
5370            }
5371        }
5372    }
5373
5374    IIntentSender getIntentSenderLocked(int type, String packageName,
5375            int callingUid, int userId, IBinder token, String resultWho,
5376            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5377            Bundle options) {
5378        if (DEBUG_MU)
5379            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5380        ActivityRecord activity = null;
5381        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5382            activity = ActivityRecord.isInStackLocked(token);
5383            if (activity == null) {
5384                return null;
5385            }
5386            if (activity.finishing) {
5387                return null;
5388            }
5389        }
5390
5391        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5392        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5393        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5394        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5395                |PendingIntent.FLAG_UPDATE_CURRENT);
5396
5397        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5398                type, packageName, activity, resultWho,
5399                requestCode, intents, resolvedTypes, flags, options, userId);
5400        WeakReference<PendingIntentRecord> ref;
5401        ref = mIntentSenderRecords.get(key);
5402        PendingIntentRecord rec = ref != null ? ref.get() : null;
5403        if (rec != null) {
5404            if (!cancelCurrent) {
5405                if (updateCurrent) {
5406                    if (rec.key.requestIntent != null) {
5407                        rec.key.requestIntent.replaceExtras(intents != null ?
5408                                intents[intents.length - 1] : null);
5409                    }
5410                    if (intents != null) {
5411                        intents[intents.length-1] = rec.key.requestIntent;
5412                        rec.key.allIntents = intents;
5413                        rec.key.allResolvedTypes = resolvedTypes;
5414                    } else {
5415                        rec.key.allIntents = null;
5416                        rec.key.allResolvedTypes = null;
5417                    }
5418                }
5419                return rec;
5420            }
5421            rec.canceled = true;
5422            mIntentSenderRecords.remove(key);
5423        }
5424        if (noCreate) {
5425            return rec;
5426        }
5427        rec = new PendingIntentRecord(this, key, callingUid);
5428        mIntentSenderRecords.put(key, rec.ref);
5429        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5430            if (activity.pendingResults == null) {
5431                activity.pendingResults
5432                        = new HashSet<WeakReference<PendingIntentRecord>>();
5433            }
5434            activity.pendingResults.add(rec.ref);
5435        }
5436        return rec;
5437    }
5438
5439    @Override
5440    public void cancelIntentSender(IIntentSender sender) {
5441        if (!(sender instanceof PendingIntentRecord)) {
5442            return;
5443        }
5444        synchronized(this) {
5445            PendingIntentRecord rec = (PendingIntentRecord)sender;
5446            try {
5447                int uid = AppGlobals.getPackageManager()
5448                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5449                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5450                    String msg = "Permission Denial: cancelIntentSender() from pid="
5451                        + Binder.getCallingPid()
5452                        + ", uid=" + Binder.getCallingUid()
5453                        + " is not allowed to cancel packges "
5454                        + rec.key.packageName;
5455                    Slog.w(TAG, msg);
5456                    throw new SecurityException(msg);
5457                }
5458            } catch (RemoteException e) {
5459                throw new SecurityException(e);
5460            }
5461            cancelIntentSenderLocked(rec, true);
5462        }
5463    }
5464
5465    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5466        rec.canceled = true;
5467        mIntentSenderRecords.remove(rec.key);
5468        if (cleanActivity && rec.key.activity != null) {
5469            rec.key.activity.pendingResults.remove(rec.ref);
5470        }
5471    }
5472
5473    @Override
5474    public String getPackageForIntentSender(IIntentSender pendingResult) {
5475        if (!(pendingResult instanceof PendingIntentRecord)) {
5476            return null;
5477        }
5478        try {
5479            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5480            return res.key.packageName;
5481        } catch (ClassCastException e) {
5482        }
5483        return null;
5484    }
5485
5486    @Override
5487    public int getUidForIntentSender(IIntentSender sender) {
5488        if (sender instanceof PendingIntentRecord) {
5489            try {
5490                PendingIntentRecord res = (PendingIntentRecord)sender;
5491                return res.uid;
5492            } catch (ClassCastException e) {
5493            }
5494        }
5495        return -1;
5496    }
5497
5498    @Override
5499    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5500        if (!(pendingResult instanceof PendingIntentRecord)) {
5501            return false;
5502        }
5503        try {
5504            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5505            if (res.key.allIntents == null) {
5506                return false;
5507            }
5508            for (int i=0; i<res.key.allIntents.length; i++) {
5509                Intent intent = res.key.allIntents[i];
5510                if (intent.getPackage() != null && intent.getComponent() != null) {
5511                    return false;
5512                }
5513            }
5514            return true;
5515        } catch (ClassCastException e) {
5516        }
5517        return false;
5518    }
5519
5520    @Override
5521    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5522        if (!(pendingResult instanceof PendingIntentRecord)) {
5523            return false;
5524        }
5525        try {
5526            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5527            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5528                return true;
5529            }
5530            return false;
5531        } catch (ClassCastException e) {
5532        }
5533        return false;
5534    }
5535
5536    @Override
5537    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5538        if (!(pendingResult instanceof PendingIntentRecord)) {
5539            return null;
5540        }
5541        try {
5542            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5543            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5544        } catch (ClassCastException e) {
5545        }
5546        return null;
5547    }
5548
5549    @Override
5550    public void setProcessLimit(int max) {
5551        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5552                "setProcessLimit()");
5553        synchronized (this) {
5554            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5555            mProcessLimitOverride = max;
5556        }
5557        trimApplications();
5558    }
5559
5560    @Override
5561    public int getProcessLimit() {
5562        synchronized (this) {
5563            return mProcessLimitOverride;
5564        }
5565    }
5566
5567    void foregroundTokenDied(ForegroundToken token) {
5568        synchronized (ActivityManagerService.this) {
5569            synchronized (mPidsSelfLocked) {
5570                ForegroundToken cur
5571                    = mForegroundProcesses.get(token.pid);
5572                if (cur != token) {
5573                    return;
5574                }
5575                mForegroundProcesses.remove(token.pid);
5576                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5577                if (pr == null) {
5578                    return;
5579                }
5580                pr.forcingToForeground = null;
5581                updateProcessForegroundLocked(pr, false, false);
5582            }
5583            updateOomAdjLocked();
5584        }
5585    }
5586
5587    @Override
5588    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5589        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5590                "setProcessForeground()");
5591        synchronized(this) {
5592            boolean changed = false;
5593
5594            synchronized (mPidsSelfLocked) {
5595                ProcessRecord pr = mPidsSelfLocked.get(pid);
5596                if (pr == null && isForeground) {
5597                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5598                    return;
5599                }
5600                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5601                if (oldToken != null) {
5602                    oldToken.token.unlinkToDeath(oldToken, 0);
5603                    mForegroundProcesses.remove(pid);
5604                    if (pr != null) {
5605                        pr.forcingToForeground = null;
5606                    }
5607                    changed = true;
5608                }
5609                if (isForeground && token != null) {
5610                    ForegroundToken newToken = new ForegroundToken() {
5611                        @Override
5612                        public void binderDied() {
5613                            foregroundTokenDied(this);
5614                        }
5615                    };
5616                    newToken.pid = pid;
5617                    newToken.token = token;
5618                    try {
5619                        token.linkToDeath(newToken, 0);
5620                        mForegroundProcesses.put(pid, newToken);
5621                        pr.forcingToForeground = token;
5622                        changed = true;
5623                    } catch (RemoteException e) {
5624                        // If the process died while doing this, we will later
5625                        // do the cleanup with the process death link.
5626                    }
5627                }
5628            }
5629
5630            if (changed) {
5631                updateOomAdjLocked();
5632            }
5633        }
5634    }
5635
5636    // =========================================================
5637    // PERMISSIONS
5638    // =========================================================
5639
5640    static class PermissionController extends IPermissionController.Stub {
5641        ActivityManagerService mActivityManagerService;
5642        PermissionController(ActivityManagerService activityManagerService) {
5643            mActivityManagerService = activityManagerService;
5644        }
5645
5646        @Override
5647        public boolean checkPermission(String permission, int pid, int uid) {
5648            return mActivityManagerService.checkPermission(permission, pid,
5649                    uid) == PackageManager.PERMISSION_GRANTED;
5650        }
5651    }
5652
5653    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5654        @Override
5655        public int checkComponentPermission(String permission, int pid, int uid,
5656                int owningUid, boolean exported) {
5657            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5658                    owningUid, exported);
5659        }
5660
5661        @Override
5662        public Object getAMSLock() {
5663            return ActivityManagerService.this;
5664        }
5665    }
5666
5667    /**
5668     * This can be called with or without the global lock held.
5669     */
5670    int checkComponentPermission(String permission, int pid, int uid,
5671            int owningUid, boolean exported) {
5672        // We might be performing an operation on behalf of an indirect binder
5673        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5674        // client identity accordingly before proceeding.
5675        Identity tlsIdentity = sCallerIdentity.get();
5676        if (tlsIdentity != null) {
5677            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5678                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5679            uid = tlsIdentity.uid;
5680            pid = tlsIdentity.pid;
5681        }
5682
5683        if (pid == MY_PID) {
5684            return PackageManager.PERMISSION_GRANTED;
5685        }
5686
5687        return ActivityManager.checkComponentPermission(permission, uid,
5688                owningUid, exported);
5689    }
5690
5691    /**
5692     * As the only public entry point for permissions checking, this method
5693     * can enforce the semantic that requesting a check on a null global
5694     * permission is automatically denied.  (Internally a null permission
5695     * string is used when calling {@link #checkComponentPermission} in cases
5696     * when only uid-based security is needed.)
5697     *
5698     * This can be called with or without the global lock held.
5699     */
5700    @Override
5701    public int checkPermission(String permission, int pid, int uid) {
5702        if (permission == null) {
5703            return PackageManager.PERMISSION_DENIED;
5704        }
5705        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5706    }
5707
5708    /**
5709     * Binder IPC calls go through the public entry point.
5710     * This can be called with or without the global lock held.
5711     */
5712    int checkCallingPermission(String permission) {
5713        return checkPermission(permission,
5714                Binder.getCallingPid(),
5715                UserHandle.getAppId(Binder.getCallingUid()));
5716    }
5717
5718    /**
5719     * This can be called with or without the global lock held.
5720     */
5721    void enforceCallingPermission(String permission, String func) {
5722        if (checkCallingPermission(permission)
5723                == PackageManager.PERMISSION_GRANTED) {
5724            return;
5725        }
5726
5727        String msg = "Permission Denial: " + func + " from pid="
5728                + Binder.getCallingPid()
5729                + ", uid=" + Binder.getCallingUid()
5730                + " requires " + permission;
5731        Slog.w(TAG, msg);
5732        throw new SecurityException(msg);
5733    }
5734
5735    /**
5736     * Determine if UID is holding permissions required to access {@link Uri} in
5737     * the given {@link ProviderInfo}. Final permission checking is always done
5738     * in {@link ContentProvider}.
5739     */
5740    private final boolean checkHoldingPermissionsLocked(
5741            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5742        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5743                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5744
5745        if (pi.applicationInfo.uid == uid) {
5746            return true;
5747        } else if (!pi.exported) {
5748            return false;
5749        }
5750
5751        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5752        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5753        try {
5754            // check if target holds top-level <provider> permissions
5755            if (!readMet && pi.readPermission != null
5756                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5757                readMet = true;
5758            }
5759            if (!writeMet && pi.writePermission != null
5760                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5761                writeMet = true;
5762            }
5763
5764            // track if unprotected read/write is allowed; any denied
5765            // <path-permission> below removes this ability
5766            boolean allowDefaultRead = pi.readPermission == null;
5767            boolean allowDefaultWrite = pi.writePermission == null;
5768
5769            // check if target holds any <path-permission> that match uri
5770            final PathPermission[] pps = pi.pathPermissions;
5771            if (pps != null) {
5772                final String path = uri.getPath();
5773                int i = pps.length;
5774                while (i > 0 && (!readMet || !writeMet)) {
5775                    i--;
5776                    PathPermission pp = pps[i];
5777                    if (pp.match(path)) {
5778                        if (!readMet) {
5779                            final String pprperm = pp.getReadPermission();
5780                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5781                                    + pprperm + " for " + pp.getPath()
5782                                    + ": match=" + pp.match(path)
5783                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5784                            if (pprperm != null) {
5785                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5786                                    readMet = true;
5787                                } else {
5788                                    allowDefaultRead = false;
5789                                }
5790                            }
5791                        }
5792                        if (!writeMet) {
5793                            final String ppwperm = pp.getWritePermission();
5794                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5795                                    + ppwperm + " for " + pp.getPath()
5796                                    + ": match=" + pp.match(path)
5797                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5798                            if (ppwperm != null) {
5799                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5800                                    writeMet = true;
5801                                } else {
5802                                    allowDefaultWrite = false;
5803                                }
5804                            }
5805                        }
5806                    }
5807                }
5808            }
5809
5810            // grant unprotected <provider> read/write, if not blocked by
5811            // <path-permission> above
5812            if (allowDefaultRead) readMet = true;
5813            if (allowDefaultWrite) writeMet = true;
5814
5815        } catch (RemoteException e) {
5816            return false;
5817        }
5818
5819        return readMet && writeMet;
5820    }
5821
5822    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5823        ProviderInfo pi = null;
5824        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5825        if (cpr != null) {
5826            pi = cpr.info;
5827        } else {
5828            try {
5829                pi = AppGlobals.getPackageManager().resolveContentProvider(
5830                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5831            } catch (RemoteException ex) {
5832            }
5833        }
5834        return pi;
5835    }
5836
5837    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5838        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5839        if (targetUris != null) {
5840            return targetUris.get(uri);
5841        } else {
5842            return null;
5843        }
5844    }
5845
5846    private UriPermission findOrCreateUriPermissionLocked(
5847            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5848        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5849        if (targetUris == null) {
5850            targetUris = Maps.newArrayMap();
5851            mGrantedUriPermissions.put(targetUid, targetUris);
5852        }
5853
5854        UriPermission perm = targetUris.get(uri);
5855        if (perm == null) {
5856            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5857            targetUris.put(uri, perm);
5858        }
5859
5860        return perm;
5861    }
5862
5863    private final boolean checkUriPermissionLocked(
5864            Uri uri, int uid, int modeFlags, int minStrength) {
5865        // Root gets to do everything.
5866        if (uid == 0) {
5867            return true;
5868        }
5869        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5870        if (perms == null) return false;
5871        UriPermission perm = perms.get(uri);
5872        if (perm == null) return false;
5873        return perm.getStrength(modeFlags) >= minStrength;
5874    }
5875
5876    @Override
5877    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5878        enforceNotIsolatedCaller("checkUriPermission");
5879
5880        // Another redirected-binder-call permissions check as in
5881        // {@link checkComponentPermission}.
5882        Identity tlsIdentity = sCallerIdentity.get();
5883        if (tlsIdentity != null) {
5884            uid = tlsIdentity.uid;
5885            pid = tlsIdentity.pid;
5886        }
5887
5888        // Our own process gets to do everything.
5889        if (pid == MY_PID) {
5890            return PackageManager.PERMISSION_GRANTED;
5891        }
5892        synchronized(this) {
5893            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5894                    ? PackageManager.PERMISSION_GRANTED
5895                    : PackageManager.PERMISSION_DENIED;
5896        }
5897    }
5898
5899    /**
5900     * Check if the targetPkg can be granted permission to access uri by
5901     * the callingUid using the given modeFlags.  Throws a security exception
5902     * if callingUid is not allowed to do this.  Returns the uid of the target
5903     * if the URI permission grant should be performed; returns -1 if it is not
5904     * needed (for example targetPkg already has permission to access the URI).
5905     * If you already know the uid of the target, you can supply it in
5906     * lastTargetUid else set that to -1.
5907     */
5908    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5909            Uri uri, int modeFlags, int lastTargetUid) {
5910        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5911        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5912                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5913        if (modeFlags == 0) {
5914            return -1;
5915        }
5916
5917        if (targetPkg != null) {
5918            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5919                    "Checking grant " + targetPkg + " permission to " + uri);
5920        }
5921
5922        final IPackageManager pm = AppGlobals.getPackageManager();
5923
5924        // If this is not a content: uri, we can't do anything with it.
5925        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5926            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5927                    "Can't grant URI permission for non-content URI: " + uri);
5928            return -1;
5929        }
5930
5931        final String authority = uri.getAuthority();
5932        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5933        if (pi == null) {
5934            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5935            return -1;
5936        }
5937
5938        int targetUid = lastTargetUid;
5939        if (targetUid < 0 && targetPkg != null) {
5940            try {
5941                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5942                if (targetUid < 0) {
5943                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5944                            "Can't grant URI permission no uid for: " + targetPkg);
5945                    return -1;
5946                }
5947            } catch (RemoteException ex) {
5948                return -1;
5949            }
5950        }
5951
5952        if (targetUid >= 0) {
5953            // First...  does the target actually need this permission?
5954            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5955                // No need to grant the target this permission.
5956                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5957                        "Target " + targetPkg + " already has full permission to " + uri);
5958                return -1;
5959            }
5960        } else {
5961            // First...  there is no target package, so can anyone access it?
5962            boolean allowed = pi.exported;
5963            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5964                if (pi.readPermission != null) {
5965                    allowed = false;
5966                }
5967            }
5968            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5969                if (pi.writePermission != null) {
5970                    allowed = false;
5971                }
5972            }
5973            if (allowed) {
5974                return -1;
5975            }
5976        }
5977
5978        // Second...  is the provider allowing granting of URI permissions?
5979        if (!pi.grantUriPermissions) {
5980            throw new SecurityException("Provider " + pi.packageName
5981                    + "/" + pi.name
5982                    + " does not allow granting of Uri permissions (uri "
5983                    + uri + ")");
5984        }
5985        if (pi.uriPermissionPatterns != null) {
5986            final int N = pi.uriPermissionPatterns.length;
5987            boolean allowed = false;
5988            for (int i=0; i<N; i++) {
5989                if (pi.uriPermissionPatterns[i] != null
5990                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5991                    allowed = true;
5992                    break;
5993                }
5994            }
5995            if (!allowed) {
5996                throw new SecurityException("Provider " + pi.packageName
5997                        + "/" + pi.name
5998                        + " does not allow granting of permission to path of Uri "
5999                        + uri);
6000            }
6001        }
6002
6003        // Third...  does the caller itself have permission to access
6004        // this uri?
6005        if (callingUid != Process.myUid()) {
6006            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6007                // Require they hold a strong enough Uri permission
6008                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6009                        : UriPermission.STRENGTH_OWNED;
6010                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6011                    throw new SecurityException("Uid " + callingUid
6012                            + " does not have permission to uri " + uri);
6013                }
6014            }
6015        }
6016
6017        return targetUid;
6018    }
6019
6020    @Override
6021    public int checkGrantUriPermission(int callingUid, String targetPkg,
6022            Uri uri, int modeFlags) {
6023        enforceNotIsolatedCaller("checkGrantUriPermission");
6024        synchronized(this) {
6025            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6026        }
6027    }
6028
6029    void grantUriPermissionUncheckedLocked(
6030            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6031        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6032        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6033                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6034        if (modeFlags == 0) {
6035            return;
6036        }
6037
6038        // So here we are: the caller has the assumed permission
6039        // to the uri, and the target doesn't.  Let's now give this to
6040        // the target.
6041
6042        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6043                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6044
6045        final String authority = uri.getAuthority();
6046        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6047        if (pi == null) {
6048            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6049            return;
6050        }
6051
6052        final UriPermission perm = findOrCreateUriPermissionLocked(
6053                pi.packageName, targetPkg, targetUid, uri);
6054        perm.grantModes(modeFlags, persistable, owner);
6055    }
6056
6057    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6058            int modeFlags, UriPermissionOwner owner) {
6059        if (targetPkg == null) {
6060            throw new NullPointerException("targetPkg");
6061        }
6062
6063        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6064        if (targetUid < 0) {
6065            return;
6066        }
6067
6068        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6069    }
6070
6071    static class NeededUriGrants extends ArrayList<Uri> {
6072        final String targetPkg;
6073        final int targetUid;
6074        final int flags;
6075
6076        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6077            this.targetPkg = targetPkg;
6078            this.targetUid = targetUid;
6079            this.flags = flags;
6080        }
6081    }
6082
6083    /**
6084     * Like checkGrantUriPermissionLocked, but takes an Intent.
6085     */
6086    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6087            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6088        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6089                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6090                + " clip=" + (intent != null ? intent.getClipData() : null)
6091                + " from " + intent + "; flags=0x"
6092                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6093
6094        if (targetPkg == null) {
6095            throw new NullPointerException("targetPkg");
6096        }
6097
6098        if (intent == null) {
6099            return null;
6100        }
6101        Uri data = intent.getData();
6102        ClipData clip = intent.getClipData();
6103        if (data == null && clip == null) {
6104            return null;
6105        }
6106
6107        if (data != null) {
6108            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6109                mode, needed != null ? needed.targetUid : -1);
6110            if (targetUid > 0) {
6111                if (needed == null) {
6112                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6113                }
6114                needed.add(data);
6115            }
6116        }
6117        if (clip != null) {
6118            for (int i=0; i<clip.getItemCount(); i++) {
6119                Uri uri = clip.getItemAt(i).getUri();
6120                if (uri != null) {
6121                    int targetUid = -1;
6122                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6123                            mode, needed != null ? needed.targetUid : -1);
6124                    if (targetUid > 0) {
6125                        if (needed == null) {
6126                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6127                        }
6128                        needed.add(uri);
6129                    }
6130                } else {
6131                    Intent clipIntent = clip.getItemAt(i).getIntent();
6132                    if (clipIntent != null) {
6133                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6134                                callingUid, targetPkg, clipIntent, mode, needed);
6135                        if (newNeeded != null) {
6136                            needed = newNeeded;
6137                        }
6138                    }
6139                }
6140            }
6141        }
6142
6143        return needed;
6144    }
6145
6146    /**
6147     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6148     */
6149    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6150            UriPermissionOwner owner) {
6151        if (needed != null) {
6152            for (int i=0; i<needed.size(); i++) {
6153                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6154                        needed.get(i), needed.flags, owner);
6155            }
6156        }
6157    }
6158
6159    void grantUriPermissionFromIntentLocked(int callingUid,
6160            String targetPkg, Intent intent, UriPermissionOwner owner) {
6161        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6162                intent, intent != null ? intent.getFlags() : 0, null);
6163        if (needed == null) {
6164            return;
6165        }
6166
6167        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6168    }
6169
6170    @Override
6171    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6172            Uri uri, int modeFlags) {
6173        enforceNotIsolatedCaller("grantUriPermission");
6174        synchronized(this) {
6175            final ProcessRecord r = getRecordForAppLocked(caller);
6176            if (r == null) {
6177                throw new SecurityException("Unable to find app for caller "
6178                        + caller
6179                        + " when granting permission to uri " + uri);
6180            }
6181            if (targetPkg == null) {
6182                throw new IllegalArgumentException("null target");
6183            }
6184            if (uri == null) {
6185                throw new IllegalArgumentException("null uri");
6186            }
6187
6188            // Persistable only supported through Intents
6189            Preconditions.checkFlagsArgument(modeFlags,
6190                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6191
6192            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6193                    null);
6194        }
6195    }
6196
6197    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6198        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6199                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6200            ArrayMap<Uri, UriPermission> perms
6201                    = mGrantedUriPermissions.get(perm.targetUid);
6202            if (perms != null) {
6203                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6204                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6205                perms.remove(perm.uri);
6206                if (perms.size() == 0) {
6207                    mGrantedUriPermissions.remove(perm.targetUid);
6208                }
6209            }
6210        }
6211    }
6212
6213    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6214        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6215
6216        final IPackageManager pm = AppGlobals.getPackageManager();
6217        final String authority = uri.getAuthority();
6218        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6219        if (pi == null) {
6220            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6221            return;
6222        }
6223
6224        // Does the caller have this permission on the URI?
6225        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6226            // Right now, if you are not the original owner of the permission,
6227            // you are not allowed to revoke it.
6228            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6229                throw new SecurityException("Uid " + callingUid
6230                        + " does not have permission to uri " + uri);
6231            //}
6232        }
6233
6234        boolean persistChanged = false;
6235
6236        // Go through all of the permissions and remove any that match.
6237        final List<String> SEGMENTS = uri.getPathSegments();
6238        if (SEGMENTS != null) {
6239            final int NS = SEGMENTS.size();
6240            int N = mGrantedUriPermissions.size();
6241            for (int i=0; i<N; i++) {
6242                ArrayMap<Uri, UriPermission> perms
6243                        = mGrantedUriPermissions.valueAt(i);
6244                Iterator<UriPermission> it = perms.values().iterator();
6245            toploop:
6246                while (it.hasNext()) {
6247                    UriPermission perm = it.next();
6248                    Uri targetUri = perm.uri;
6249                    if (!authority.equals(targetUri.getAuthority())) {
6250                        continue;
6251                    }
6252                    List<String> targetSegments = targetUri.getPathSegments();
6253                    if (targetSegments == null) {
6254                        continue;
6255                    }
6256                    if (targetSegments.size() < NS) {
6257                        continue;
6258                    }
6259                    for (int j=0; j<NS; j++) {
6260                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6261                            continue toploop;
6262                        }
6263                    }
6264                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6265                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6266                    persistChanged |= perm.clearModes(modeFlags, true);
6267                    if (perm.modeFlags == 0) {
6268                        it.remove();
6269                    }
6270                }
6271                if (perms.size() == 0) {
6272                    mGrantedUriPermissions.remove(
6273                            mGrantedUriPermissions.keyAt(i));
6274                    N--;
6275                    i--;
6276                }
6277            }
6278        }
6279
6280        if (persistChanged) {
6281            schedulePersistUriGrants();
6282        }
6283    }
6284
6285    @Override
6286    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6287            int modeFlags) {
6288        enforceNotIsolatedCaller("revokeUriPermission");
6289        synchronized(this) {
6290            final ProcessRecord r = getRecordForAppLocked(caller);
6291            if (r == null) {
6292                throw new SecurityException("Unable to find app for caller "
6293                        + caller
6294                        + " when revoking permission to uri " + uri);
6295            }
6296            if (uri == null) {
6297                Slog.w(TAG, "revokeUriPermission: null uri");
6298                return;
6299            }
6300
6301            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6302                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6303            if (modeFlags == 0) {
6304                return;
6305            }
6306
6307            final IPackageManager pm = AppGlobals.getPackageManager();
6308            final String authority = uri.getAuthority();
6309            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6310            if (pi == null) {
6311                Slog.w(TAG, "No content provider found for permission revoke: "
6312                        + uri.toSafeString());
6313                return;
6314            }
6315
6316            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6317        }
6318    }
6319
6320    /**
6321     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6322     * given package.
6323     *
6324     * @param packageName Package name to match, or {@code null} to apply to all
6325     *            packages.
6326     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6327     *            to all users.
6328     * @param persistable If persistable grants should be removed.
6329     */
6330    private void removeUriPermissionsForPackageLocked(
6331            String packageName, int userHandle, boolean persistable) {
6332        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6333            throw new IllegalArgumentException("Must narrow by either package or user");
6334        }
6335
6336        boolean persistChanged = false;
6337
6338        final int size = mGrantedUriPermissions.size();
6339        for (int i = 0; i < size; i++) {
6340            // Only inspect grants matching user
6341            if (userHandle == UserHandle.USER_ALL
6342                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6343                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6344                        .values().iterator();
6345                while (it.hasNext()) {
6346                    final UriPermission perm = it.next();
6347
6348                    // Only inspect grants matching package
6349                    if (packageName == null || perm.sourcePkg.equals(packageName)
6350                            || perm.targetPkg.equals(packageName)) {
6351                        persistChanged |= perm.clearModes(~0, persistable);
6352
6353                        // Only remove when no modes remain; any persisted grants
6354                        // will keep this alive.
6355                        if (perm.modeFlags == 0) {
6356                            it.remove();
6357                        }
6358                    }
6359                }
6360            }
6361        }
6362
6363        if (persistChanged) {
6364            schedulePersistUriGrants();
6365        }
6366    }
6367
6368    @Override
6369    public IBinder newUriPermissionOwner(String name) {
6370        enforceNotIsolatedCaller("newUriPermissionOwner");
6371        synchronized(this) {
6372            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6373            return owner.getExternalTokenLocked();
6374        }
6375    }
6376
6377    @Override
6378    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6379            Uri uri, int modeFlags) {
6380        synchronized(this) {
6381            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6382            if (owner == null) {
6383                throw new IllegalArgumentException("Unknown owner: " + token);
6384            }
6385            if (fromUid != Binder.getCallingUid()) {
6386                if (Binder.getCallingUid() != Process.myUid()) {
6387                    // Only system code can grant URI permissions on behalf
6388                    // of other users.
6389                    throw new SecurityException("nice try");
6390                }
6391            }
6392            if (targetPkg == null) {
6393                throw new IllegalArgumentException("null target");
6394            }
6395            if (uri == null) {
6396                throw new IllegalArgumentException("null uri");
6397            }
6398
6399            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6400        }
6401    }
6402
6403    @Override
6404    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6405        synchronized(this) {
6406            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6407            if (owner == null) {
6408                throw new IllegalArgumentException("Unknown owner: " + token);
6409            }
6410
6411            if (uri == null) {
6412                owner.removeUriPermissionsLocked(mode);
6413            } else {
6414                owner.removeUriPermissionLocked(uri, mode);
6415            }
6416        }
6417    }
6418
6419    private void schedulePersistUriGrants() {
6420        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6421            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6422                    10 * DateUtils.SECOND_IN_MILLIS);
6423        }
6424    }
6425
6426    private void writeGrantedUriPermissions() {
6427        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6428
6429        // Snapshot permissions so we can persist without lock
6430        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6431        synchronized (this) {
6432            final int size = mGrantedUriPermissions.size();
6433            for (int i = 0 ; i < size; i++) {
6434                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6435                    if (perm.persistedModeFlags != 0) {
6436                        persist.add(perm.snapshot());
6437                    }
6438                }
6439            }
6440        }
6441
6442        FileOutputStream fos = null;
6443        try {
6444            fos = mGrantFile.startWrite();
6445
6446            XmlSerializer out = new FastXmlSerializer();
6447            out.setOutput(fos, "utf-8");
6448            out.startDocument(null, true);
6449            out.startTag(null, TAG_URI_GRANTS);
6450            for (UriPermission.Snapshot perm : persist) {
6451                out.startTag(null, TAG_URI_GRANT);
6452                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6453                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6454                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6455                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6456                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6457                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6458                out.endTag(null, TAG_URI_GRANT);
6459            }
6460            out.endTag(null, TAG_URI_GRANTS);
6461            out.endDocument();
6462
6463            mGrantFile.finishWrite(fos);
6464        } catch (IOException e) {
6465            if (fos != null) {
6466                mGrantFile.failWrite(fos);
6467            }
6468        }
6469    }
6470
6471    private void readGrantedUriPermissionsLocked() {
6472        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6473
6474        final long now = System.currentTimeMillis();
6475
6476        FileInputStream fis = null;
6477        try {
6478            fis = mGrantFile.openRead();
6479            final XmlPullParser in = Xml.newPullParser();
6480            in.setInput(fis, null);
6481
6482            int type;
6483            while ((type = in.next()) != END_DOCUMENT) {
6484                final String tag = in.getName();
6485                if (type == START_TAG) {
6486                    if (TAG_URI_GRANT.equals(tag)) {
6487                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6488                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6489                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6490                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6491                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6492                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6493
6494                        // Sanity check that provider still belongs to source package
6495                        final ProviderInfo pi = getProviderInfoLocked(
6496                                uri.getAuthority(), userHandle);
6497                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6498                            int targetUid = -1;
6499                            try {
6500                                targetUid = AppGlobals.getPackageManager()
6501                                        .getPackageUid(targetPkg, userHandle);
6502                            } catch (RemoteException e) {
6503                            }
6504                            if (targetUid != -1) {
6505                                final UriPermission perm = findOrCreateUriPermissionLocked(
6506                                        sourcePkg, targetPkg, targetUid, uri);
6507                                perm.initPersistedModes(modeFlags, createdTime);
6508                            }
6509                        } else {
6510                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6511                                    + " but instead found " + pi);
6512                        }
6513                    }
6514                }
6515            }
6516        } catch (FileNotFoundException e) {
6517            // Missing grants is okay
6518        } catch (IOException e) {
6519            Log.wtf(TAG, "Failed reading Uri grants", e);
6520        } catch (XmlPullParserException e) {
6521            Log.wtf(TAG, "Failed reading Uri grants", e);
6522        } finally {
6523            IoUtils.closeQuietly(fis);
6524        }
6525    }
6526
6527    @Override
6528    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6529        enforceNotIsolatedCaller("takePersistableUriPermission");
6530
6531        Preconditions.checkFlagsArgument(modeFlags,
6532                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6533
6534        synchronized (this) {
6535            final int callingUid = Binder.getCallingUid();
6536            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6537            if (perm == null) {
6538                throw new SecurityException("No permission grant found for UID " + callingUid
6539                        + " and Uri " + uri.toSafeString());
6540            }
6541
6542            boolean persistChanged = perm.takePersistableModes(modeFlags);
6543            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6544
6545            if (persistChanged) {
6546                schedulePersistUriGrants();
6547            }
6548        }
6549    }
6550
6551    @Override
6552    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6553        enforceNotIsolatedCaller("releasePersistableUriPermission");
6554
6555        Preconditions.checkFlagsArgument(modeFlags,
6556                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6557
6558        synchronized (this) {
6559            final int callingUid = Binder.getCallingUid();
6560
6561            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6562            if (perm == null) {
6563                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6564                        + uri.toSafeString());
6565                return;
6566            }
6567
6568            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6569            removeUriPermissionIfNeededLocked(perm);
6570            if (persistChanged) {
6571                schedulePersistUriGrants();
6572            }
6573        }
6574    }
6575
6576    /**
6577     * Prune any older {@link UriPermission} for the given UID until outstanding
6578     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6579     *
6580     * @return if any mutations occured that require persisting.
6581     */
6582    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6583        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6584        if (perms == null) return false;
6585        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6586
6587        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6588        for (UriPermission perm : perms.values()) {
6589            if (perm.persistedModeFlags != 0) {
6590                persisted.add(perm);
6591            }
6592        }
6593
6594        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6595        if (trimCount <= 0) return false;
6596
6597        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6598        for (int i = 0; i < trimCount; i++) {
6599            final UriPermission perm = persisted.get(i);
6600
6601            if (DEBUG_URI_PERMISSION) {
6602                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6603            }
6604
6605            perm.releasePersistableModes(~0);
6606            removeUriPermissionIfNeededLocked(perm);
6607        }
6608
6609        return true;
6610    }
6611
6612    @Override
6613    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6614            String packageName, boolean incoming) {
6615        enforceNotIsolatedCaller("getPersistedUriPermissions");
6616        Preconditions.checkNotNull(packageName, "packageName");
6617
6618        final int callingUid = Binder.getCallingUid();
6619        final IPackageManager pm = AppGlobals.getPackageManager();
6620        try {
6621            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6622            if (packageUid != callingUid) {
6623                throw new SecurityException(
6624                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6625            }
6626        } catch (RemoteException e) {
6627            throw new SecurityException("Failed to verify package name ownership");
6628        }
6629
6630        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6631        synchronized (this) {
6632            if (incoming) {
6633                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6634                if (perms == null) {
6635                    Slog.w(TAG, "No permission grants found for " + packageName);
6636                } else {
6637                    final int size = perms.size();
6638                    for (int i = 0; i < size; i++) {
6639                        final UriPermission perm = perms.valueAt(i);
6640                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6641                            result.add(perm.buildPersistedPublicApiObject());
6642                        }
6643                    }
6644                }
6645            } else {
6646                final int size = mGrantedUriPermissions.size();
6647                for (int i = 0; i < size; i++) {
6648                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6649                    final int permsSize = perms.size();
6650                    for (int j = 0; j < permsSize; j++) {
6651                        final UriPermission perm = perms.valueAt(j);
6652                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6653                            result.add(perm.buildPersistedPublicApiObject());
6654                        }
6655                    }
6656                }
6657            }
6658        }
6659        return new ParceledListSlice<android.content.UriPermission>(result);
6660    }
6661
6662    @Override
6663    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6664        synchronized (this) {
6665            ProcessRecord app =
6666                who != null ? getRecordForAppLocked(who) : null;
6667            if (app == null) return;
6668
6669            Message msg = Message.obtain();
6670            msg.what = WAIT_FOR_DEBUGGER_MSG;
6671            msg.obj = app;
6672            msg.arg1 = waiting ? 1 : 0;
6673            mHandler.sendMessage(msg);
6674        }
6675    }
6676
6677    @Override
6678    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6679        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6680        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6681        outInfo.availMem = Process.getFreeMemory();
6682        outInfo.totalMem = Process.getTotalMemory();
6683        outInfo.threshold = homeAppMem;
6684        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6685        outInfo.hiddenAppThreshold = cachedAppMem;
6686        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6687                ProcessList.SERVICE_ADJ);
6688        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6689                ProcessList.VISIBLE_APP_ADJ);
6690        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6691                ProcessList.FOREGROUND_APP_ADJ);
6692    }
6693
6694    // =========================================================
6695    // TASK MANAGEMENT
6696    // =========================================================
6697
6698    @Override
6699    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6700                         IThumbnailReceiver receiver) {
6701        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6702
6703        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6704        ActivityRecord topRecord = null;
6705
6706        synchronized(this) {
6707            if (localLOGV) Slog.v(
6708                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6709                + ", receiver=" + receiver);
6710
6711            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6712                    != PackageManager.PERMISSION_GRANTED) {
6713                if (receiver != null) {
6714                    // If the caller wants to wait for pending thumbnails,
6715                    // it ain't gonna get them.
6716                    try {
6717                        receiver.finished();
6718                    } catch (RemoteException ex) {
6719                    }
6720                }
6721                String msg = "Permission Denial: getTasks() from pid="
6722                        + Binder.getCallingPid()
6723                        + ", uid=" + Binder.getCallingUid()
6724                        + " requires " + android.Manifest.permission.GET_TASKS;
6725                Slog.w(TAG, msg);
6726                throw new SecurityException(msg);
6727            }
6728
6729            // TODO: Improve with MRU list from all ActivityStacks.
6730            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6731
6732            if (!pending.pendingRecords.isEmpty()) {
6733                mPendingThumbnails.add(pending);
6734            }
6735        }
6736
6737        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6738
6739        if (topRecord != null) {
6740            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6741            try {
6742                IApplicationThread topThumbnail = topRecord.app.thread;
6743                topThumbnail.requestThumbnail(topRecord.appToken);
6744            } catch (Exception e) {
6745                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6746                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6747            }
6748        }
6749
6750        if (pending == null && receiver != null) {
6751            // In this case all thumbnails were available and the client
6752            // is being asked to be told when the remaining ones come in...
6753            // which is unusually, since the top-most currently running
6754            // activity should never have a canned thumbnail!  Oh well.
6755            try {
6756                receiver.finished();
6757            } catch (RemoteException ex) {
6758            }
6759        }
6760
6761        return list;
6762    }
6763
6764    TaskRecord getMostRecentTask() {
6765        return mRecentTasks.get(0);
6766    }
6767
6768    @Override
6769    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6770            int flags, int userId) {
6771        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6772                false, true, "getRecentTasks", null);
6773
6774        synchronized (this) {
6775            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6776                    "getRecentTasks()");
6777            final boolean detailed = checkCallingPermission(
6778                    android.Manifest.permission.GET_DETAILED_TASKS)
6779                    == PackageManager.PERMISSION_GRANTED;
6780
6781            IPackageManager pm = AppGlobals.getPackageManager();
6782
6783            final int N = mRecentTasks.size();
6784            ArrayList<ActivityManager.RecentTaskInfo> res
6785                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6786                            maxNum < N ? maxNum : N);
6787            for (int i=0; i<N && maxNum > 0; i++) {
6788                TaskRecord tr = mRecentTasks.get(i);
6789                // Only add calling user's recent tasks
6790                if (tr.userId != userId) continue;
6791                // Return the entry if desired by the caller.  We always return
6792                // the first entry, because callers always expect this to be the
6793                // foreground app.  We may filter others if the caller has
6794                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6795                // we should exclude the entry.
6796
6797                if (i == 0
6798                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6799                        || (tr.intent == null)
6800                        || ((tr.intent.getFlags()
6801                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6802                    ActivityManager.RecentTaskInfo rti
6803                            = new ActivityManager.RecentTaskInfo();
6804                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6805                    rti.persistentId = tr.taskId;
6806                    rti.baseIntent = new Intent(
6807                            tr.intent != null ? tr.intent : tr.affinityIntent);
6808                    if (!detailed) {
6809                        rti.baseIntent.replaceExtras((Bundle)null);
6810                    }
6811                    rti.origActivity = tr.origActivity;
6812                    rti.description = tr.lastDescription;
6813                    rti.stackId = tr.stack.mStackId;
6814
6815                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6816                        // Check whether this activity is currently available.
6817                        try {
6818                            if (rti.origActivity != null) {
6819                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6820                                        == null) {
6821                                    continue;
6822                                }
6823                            } else if (rti.baseIntent != null) {
6824                                if (pm.queryIntentActivities(rti.baseIntent,
6825                                        null, 0, userId) == null) {
6826                                    continue;
6827                                }
6828                            }
6829                        } catch (RemoteException e) {
6830                            // Will never happen.
6831                        }
6832                    }
6833
6834                    res.add(rti);
6835                    maxNum--;
6836                }
6837            }
6838            return res;
6839        }
6840    }
6841
6842    private TaskRecord recentTaskForIdLocked(int id) {
6843        final int N = mRecentTasks.size();
6844            for (int i=0; i<N; i++) {
6845                TaskRecord tr = mRecentTasks.get(i);
6846                if (tr.taskId == id) {
6847                    return tr;
6848                }
6849            }
6850            return null;
6851    }
6852
6853    @Override
6854    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6855        synchronized (this) {
6856            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6857                    "getTaskThumbnails()");
6858            TaskRecord tr = recentTaskForIdLocked(id);
6859            if (tr != null) {
6860                return tr.getTaskThumbnailsLocked();
6861            }
6862        }
6863        return null;
6864    }
6865
6866    @Override
6867    public Bitmap getTaskTopThumbnail(int id) {
6868        synchronized (this) {
6869            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6870                    "getTaskTopThumbnail()");
6871            TaskRecord tr = recentTaskForIdLocked(id);
6872            if (tr != null) {
6873                return tr.getTaskTopThumbnailLocked();
6874            }
6875        }
6876        return null;
6877    }
6878
6879    @Override
6880    public boolean removeSubTask(int taskId, int subTaskIndex) {
6881        synchronized (this) {
6882            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6883                    "removeSubTask()");
6884            long ident = Binder.clearCallingIdentity();
6885            try {
6886                TaskRecord tr = recentTaskForIdLocked(taskId);
6887                if (tr != null) {
6888                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6889                }
6890                return false;
6891            } finally {
6892                Binder.restoreCallingIdentity(ident);
6893            }
6894        }
6895    }
6896
6897    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6898        if (!pr.killedByAm) {
6899            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6900            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6901                    pr.processName, pr.setAdj, reason);
6902            pr.killedByAm = true;
6903            Process.killProcessQuiet(pr.pid);
6904        }
6905    }
6906
6907    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6908        tr.disposeThumbnail();
6909        mRecentTasks.remove(tr);
6910        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6911        Intent baseIntent = new Intent(
6912                tr.intent != null ? tr.intent : tr.affinityIntent);
6913        ComponentName component = baseIntent.getComponent();
6914        if (component == null) {
6915            Slog.w(TAG, "Now component for base intent of task: " + tr);
6916            return;
6917        }
6918
6919        // Find any running services associated with this app.
6920        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6921
6922        if (killProcesses) {
6923            // Find any running processes associated with this app.
6924            final String pkg = component.getPackageName();
6925            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6926            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6927            for (int i=0; i<pmap.size(); i++) {
6928                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6929                for (int j=0; j<uids.size(); j++) {
6930                    ProcessRecord proc = uids.valueAt(j);
6931                    if (proc.userId != tr.userId) {
6932                        continue;
6933                    }
6934                    if (!proc.pkgList.containsKey(pkg)) {
6935                        continue;
6936                    }
6937                    procs.add(proc);
6938                }
6939            }
6940
6941            // Kill the running processes.
6942            for (int i=0; i<procs.size(); i++) {
6943                ProcessRecord pr = procs.get(i);
6944                if (pr == mHomeProcess) {
6945                    // Don't kill the home process along with tasks from the same package.
6946                    continue;
6947                }
6948                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6949                    killUnneededProcessLocked(pr, "remove task");
6950                } else {
6951                    pr.waitingToKill = "remove task";
6952                }
6953            }
6954        }
6955    }
6956
6957    @Override
6958    public boolean removeTask(int taskId, int flags) {
6959        synchronized (this) {
6960            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6961                    "removeTask()");
6962            long ident = Binder.clearCallingIdentity();
6963            try {
6964                TaskRecord tr = recentTaskForIdLocked(taskId);
6965                if (tr != null) {
6966                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6967                    if (r != null) {
6968                        cleanUpRemovedTaskLocked(tr, flags);
6969                        return true;
6970                    }
6971                    if (tr.mActivities.size() == 0) {
6972                        // Caller is just removing a recent task that is
6973                        // not actively running.  That is easy!
6974                        cleanUpRemovedTaskLocked(tr, flags);
6975                        return true;
6976                    }
6977                    Slog.w(TAG, "removeTask: task " + taskId
6978                            + " does not have activities to remove, "
6979                            + " but numActivities=" + tr.numActivities
6980                            + ": " + tr);
6981                }
6982            } finally {
6983                Binder.restoreCallingIdentity(ident);
6984            }
6985        }
6986        return false;
6987    }
6988
6989    /**
6990     * TODO: Add mController hook
6991     */
6992    @Override
6993    public void moveTaskToFront(int task, int flags, Bundle options) {
6994        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6995                "moveTaskToFront()");
6996
6997        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
6998        synchronized(this) {
6999            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7000                    Binder.getCallingUid(), "Task to front")) {
7001                ActivityOptions.abort(options);
7002                return;
7003            }
7004            final long origId = Binder.clearCallingIdentity();
7005            try {
7006                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7007            } finally {
7008                Binder.restoreCallingIdentity(origId);
7009            }
7010            ActivityOptions.abort(options);
7011        }
7012    }
7013
7014    @Override
7015    public void moveTaskToBack(int taskId) {
7016        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7017                "moveTaskToBack()");
7018
7019        synchronized(this) {
7020            TaskRecord tr = recentTaskForIdLocked(taskId);
7021            if (tr != null) {
7022                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7023                ActivityStack stack = tr.stack;
7024                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7025                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7026                            Binder.getCallingUid(), "Task to back")) {
7027                        return;
7028                    }
7029                }
7030                final long origId = Binder.clearCallingIdentity();
7031                try {
7032                    stack.moveTaskToBackLocked(taskId, null);
7033                } finally {
7034                    Binder.restoreCallingIdentity(origId);
7035                }
7036            }
7037        }
7038    }
7039
7040    /**
7041     * Moves an activity, and all of the other activities within the same task, to the bottom
7042     * of the history stack.  The activity's order within the task is unchanged.
7043     *
7044     * @param token A reference to the activity we wish to move
7045     * @param nonRoot If false then this only works if the activity is the root
7046     *                of a task; if true it will work for any activity in a task.
7047     * @return Returns true if the move completed, false if not.
7048     */
7049    @Override
7050    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7051        enforceNotIsolatedCaller("moveActivityTaskToBack");
7052        synchronized(this) {
7053            final long origId = Binder.clearCallingIdentity();
7054            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7055            if (taskId >= 0) {
7056                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7057            }
7058            Binder.restoreCallingIdentity(origId);
7059        }
7060        return false;
7061    }
7062
7063    @Override
7064    public void moveTaskBackwards(int task) {
7065        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7066                "moveTaskBackwards()");
7067
7068        synchronized(this) {
7069            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7070                    Binder.getCallingUid(), "Task backwards")) {
7071                return;
7072            }
7073            final long origId = Binder.clearCallingIdentity();
7074            moveTaskBackwardsLocked(task);
7075            Binder.restoreCallingIdentity(origId);
7076        }
7077    }
7078
7079    private final void moveTaskBackwardsLocked(int task) {
7080        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7081    }
7082
7083    @Override
7084    public IBinder getHomeActivityToken() throws RemoteException {
7085        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7086                "getHomeActivityToken()");
7087        synchronized (this) {
7088            return mStackSupervisor.getHomeActivityToken();
7089        }
7090    }
7091
7092    @Override
7093    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7094            IActivityContainerCallback callback) throws RemoteException {
7095        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7096                "createActivityContainer()");
7097        synchronized (this) {
7098            if (parentActivityToken == null) {
7099                throw new IllegalArgumentException("parent token must not be null");
7100            }
7101            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7102            if (r == null) {
7103                return null;
7104            }
7105            return mStackSupervisor.createActivityContainer(r, callback);
7106        }
7107    }
7108
7109    @Override
7110    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7111            throws RemoteException {
7112        synchronized (this) {
7113            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7114            if (stack != null) {
7115                return stack.mActivityContainer;
7116            }
7117            return null;
7118        }
7119    }
7120
7121    @Override
7122    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7123        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7124                "moveTaskToStack()");
7125        if (stackId == HOME_STACK_ID) {
7126            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7127                    new RuntimeException("here").fillInStackTrace());
7128        }
7129        synchronized (this) {
7130            long ident = Binder.clearCallingIdentity();
7131            try {
7132                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7133                        + stackId + " toTop=" + toTop);
7134                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7135            } finally {
7136                Binder.restoreCallingIdentity(ident);
7137            }
7138        }
7139    }
7140
7141    @Override
7142    public void resizeStack(int stackBoxId, Rect bounds) {
7143        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7144                "resizeStackBox()");
7145        long ident = Binder.clearCallingIdentity();
7146        try {
7147            mWindowManager.resizeStack(stackBoxId, bounds);
7148        } finally {
7149            Binder.restoreCallingIdentity(ident);
7150        }
7151    }
7152
7153    @Override
7154    public List<StackInfo> getAllStackInfos() {
7155        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7156                "getAllStackInfos()");
7157        long ident = Binder.clearCallingIdentity();
7158        try {
7159            synchronized (this) {
7160                return mStackSupervisor.getAllStackInfosLocked();
7161            }
7162        } finally {
7163            Binder.restoreCallingIdentity(ident);
7164        }
7165    }
7166
7167    @Override
7168    public StackInfo getStackInfo(int stackId) {
7169        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7170                "getStackInfo()");
7171        long ident = Binder.clearCallingIdentity();
7172        try {
7173            synchronized (this) {
7174                return mStackSupervisor.getStackInfoLocked(stackId);
7175            }
7176        } finally {
7177            Binder.restoreCallingIdentity(ident);
7178        }
7179    }
7180
7181    @Override
7182    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7183        synchronized(this) {
7184            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7185        }
7186    }
7187
7188    // =========================================================
7189    // THUMBNAILS
7190    // =========================================================
7191
7192    public void reportThumbnail(IBinder token,
7193            Bitmap thumbnail, CharSequence description) {
7194        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7195        final long origId = Binder.clearCallingIdentity();
7196        sendPendingThumbnail(null, token, thumbnail, description, true);
7197        Binder.restoreCallingIdentity(origId);
7198    }
7199
7200    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7201            Bitmap thumbnail, CharSequence description, boolean always) {
7202        TaskRecord task;
7203        ArrayList<PendingThumbnailsRecord> receivers = null;
7204
7205        //System.out.println("Send pending thumbnail: " + r);
7206
7207        synchronized(this) {
7208            if (r == null) {
7209                r = ActivityRecord.isInStackLocked(token);
7210                if (r == null) {
7211                    return;
7212                }
7213            }
7214            if (thumbnail == null && r.thumbHolder != null) {
7215                thumbnail = r.thumbHolder.lastThumbnail;
7216                description = r.thumbHolder.lastDescription;
7217            }
7218            if (thumbnail == null && !always) {
7219                // If there is no thumbnail, and this entry is not actually
7220                // going away, then abort for now and pick up the next
7221                // thumbnail we get.
7222                return;
7223            }
7224            task = r.task;
7225
7226            int N = mPendingThumbnails.size();
7227            int i=0;
7228            while (i<N) {
7229                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7230                //System.out.println("Looking in " + pr.pendingRecords);
7231                if (pr.pendingRecords.remove(r)) {
7232                    if (receivers == null) {
7233                        receivers = new ArrayList<PendingThumbnailsRecord>();
7234                    }
7235                    receivers.add(pr);
7236                    if (pr.pendingRecords.size() == 0) {
7237                        pr.finished = true;
7238                        mPendingThumbnails.remove(i);
7239                        N--;
7240                        continue;
7241                    }
7242                }
7243                i++;
7244            }
7245        }
7246
7247        if (receivers != null) {
7248            final int N = receivers.size();
7249            for (int i=0; i<N; i++) {
7250                try {
7251                    PendingThumbnailsRecord pr = receivers.get(i);
7252                    pr.receiver.newThumbnail(
7253                        task != null ? task.taskId : -1, thumbnail, description);
7254                    if (pr.finished) {
7255                        pr.receiver.finished();
7256                    }
7257                } catch (Exception e) {
7258                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7259                }
7260            }
7261        }
7262    }
7263
7264    // =========================================================
7265    // CONTENT PROVIDERS
7266    // =========================================================
7267
7268    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7269        List<ProviderInfo> providers = null;
7270        try {
7271            providers = AppGlobals.getPackageManager().
7272                queryContentProviders(app.processName, app.uid,
7273                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7274        } catch (RemoteException ex) {
7275        }
7276        if (DEBUG_MU)
7277            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7278        int userId = app.userId;
7279        if (providers != null) {
7280            int N = providers.size();
7281            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7282            for (int i=0; i<N; i++) {
7283                ProviderInfo cpi =
7284                    (ProviderInfo)providers.get(i);
7285                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7286                        cpi.name, cpi.flags);
7287                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7288                    // This is a singleton provider, but a user besides the
7289                    // default user is asking to initialize a process it runs
7290                    // in...  well, no, it doesn't actually run in this process,
7291                    // it runs in the process of the default user.  Get rid of it.
7292                    providers.remove(i);
7293                    N--;
7294                    i--;
7295                    continue;
7296                }
7297
7298                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7299                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7300                if (cpr == null) {
7301                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7302                    mProviderMap.putProviderByClass(comp, cpr);
7303                }
7304                if (DEBUG_MU)
7305                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7306                app.pubProviders.put(cpi.name, cpr);
7307                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7308                    // Don't add this if it is a platform component that is marked
7309                    // to run in multiple processes, because this is actually
7310                    // part of the framework so doesn't make sense to track as a
7311                    // separate apk in the process.
7312                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7313                }
7314                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7315            }
7316        }
7317        return providers;
7318    }
7319
7320    /**
7321     * Check if {@link ProcessRecord} has a possible chance at accessing the
7322     * given {@link ProviderInfo}. Final permission checking is always done
7323     * in {@link ContentProvider}.
7324     */
7325    private final String checkContentProviderPermissionLocked(
7326            ProviderInfo cpi, ProcessRecord r) {
7327        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7328        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7329        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7330                cpi.applicationInfo.uid, cpi.exported)
7331                == PackageManager.PERMISSION_GRANTED) {
7332            return null;
7333        }
7334        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7335                cpi.applicationInfo.uid, cpi.exported)
7336                == PackageManager.PERMISSION_GRANTED) {
7337            return null;
7338        }
7339
7340        PathPermission[] pps = cpi.pathPermissions;
7341        if (pps != null) {
7342            int i = pps.length;
7343            while (i > 0) {
7344                i--;
7345                PathPermission pp = pps[i];
7346                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7347                        cpi.applicationInfo.uid, cpi.exported)
7348                        == PackageManager.PERMISSION_GRANTED) {
7349                    return null;
7350                }
7351                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7352                        cpi.applicationInfo.uid, cpi.exported)
7353                        == PackageManager.PERMISSION_GRANTED) {
7354                    return null;
7355                }
7356            }
7357        }
7358
7359        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7360        if (perms != null) {
7361            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7362                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7363                    return null;
7364                }
7365            }
7366        }
7367
7368        String msg;
7369        if (!cpi.exported) {
7370            msg = "Permission Denial: opening provider " + cpi.name
7371                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7372                    + ", uid=" + callingUid + ") that is not exported from uid "
7373                    + cpi.applicationInfo.uid;
7374        } else {
7375            msg = "Permission Denial: opening provider " + cpi.name
7376                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7377                    + ", uid=" + callingUid + ") requires "
7378                    + cpi.readPermission + " or " + cpi.writePermission;
7379        }
7380        Slog.w(TAG, msg);
7381        return msg;
7382    }
7383
7384    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7385            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7386        if (r != null) {
7387            for (int i=0; i<r.conProviders.size(); i++) {
7388                ContentProviderConnection conn = r.conProviders.get(i);
7389                if (conn.provider == cpr) {
7390                    if (DEBUG_PROVIDER) Slog.v(TAG,
7391                            "Adding provider requested by "
7392                            + r.processName + " from process "
7393                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7394                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7395                    if (stable) {
7396                        conn.stableCount++;
7397                        conn.numStableIncs++;
7398                    } else {
7399                        conn.unstableCount++;
7400                        conn.numUnstableIncs++;
7401                    }
7402                    return conn;
7403                }
7404            }
7405            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7406            if (stable) {
7407                conn.stableCount = 1;
7408                conn.numStableIncs = 1;
7409            } else {
7410                conn.unstableCount = 1;
7411                conn.numUnstableIncs = 1;
7412            }
7413            cpr.connections.add(conn);
7414            r.conProviders.add(conn);
7415            return conn;
7416        }
7417        cpr.addExternalProcessHandleLocked(externalProcessToken);
7418        return null;
7419    }
7420
7421    boolean decProviderCountLocked(ContentProviderConnection conn,
7422            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7423        if (conn != null) {
7424            cpr = conn.provider;
7425            if (DEBUG_PROVIDER) Slog.v(TAG,
7426                    "Removing provider requested by "
7427                    + conn.client.processName + " from process "
7428                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7429                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7430            if (stable) {
7431                conn.stableCount--;
7432            } else {
7433                conn.unstableCount--;
7434            }
7435            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7436                cpr.connections.remove(conn);
7437                conn.client.conProviders.remove(conn);
7438                return true;
7439            }
7440            return false;
7441        }
7442        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7443        return false;
7444    }
7445
7446    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7447            String name, IBinder token, boolean stable, int userId) {
7448        ContentProviderRecord cpr;
7449        ContentProviderConnection conn = null;
7450        ProviderInfo cpi = null;
7451
7452        synchronized(this) {
7453            ProcessRecord r = null;
7454            if (caller != null) {
7455                r = getRecordForAppLocked(caller);
7456                if (r == null) {
7457                    throw new SecurityException(
7458                            "Unable to find app for caller " + caller
7459                          + " (pid=" + Binder.getCallingPid()
7460                          + ") when getting content provider " + name);
7461                }
7462            }
7463
7464            // First check if this content provider has been published...
7465            cpr = mProviderMap.getProviderByName(name, userId);
7466            boolean providerRunning = cpr != null;
7467            if (providerRunning) {
7468                cpi = cpr.info;
7469                String msg;
7470                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7471                    throw new SecurityException(msg);
7472                }
7473
7474                if (r != null && cpr.canRunHere(r)) {
7475                    // This provider has been published or is in the process
7476                    // of being published...  but it is also allowed to run
7477                    // in the caller's process, so don't make a connection
7478                    // and just let the caller instantiate its own instance.
7479                    ContentProviderHolder holder = cpr.newHolder(null);
7480                    // don't give caller the provider object, it needs
7481                    // to make its own.
7482                    holder.provider = null;
7483                    return holder;
7484                }
7485
7486                final long origId = Binder.clearCallingIdentity();
7487
7488                // In this case the provider instance already exists, so we can
7489                // return it right away.
7490                conn = incProviderCountLocked(r, cpr, token, stable);
7491                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7492                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7493                        // If this is a perceptible app accessing the provider,
7494                        // make sure to count it as being accessed and thus
7495                        // back up on the LRU list.  This is good because
7496                        // content providers are often expensive to start.
7497                        updateLruProcessLocked(cpr.proc, false, null);
7498                    }
7499                }
7500
7501                if (cpr.proc != null) {
7502                    if (false) {
7503                        if (cpr.name.flattenToShortString().equals(
7504                                "com.android.providers.calendar/.CalendarProvider2")) {
7505                            Slog.v(TAG, "****************** KILLING "
7506                                + cpr.name.flattenToShortString());
7507                            Process.killProcess(cpr.proc.pid);
7508                        }
7509                    }
7510                    boolean success = updateOomAdjLocked(cpr.proc);
7511                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7512                    // NOTE: there is still a race here where a signal could be
7513                    // pending on the process even though we managed to update its
7514                    // adj level.  Not sure what to do about this, but at least
7515                    // the race is now smaller.
7516                    if (!success) {
7517                        // Uh oh...  it looks like the provider's process
7518                        // has been killed on us.  We need to wait for a new
7519                        // process to be started, and make sure its death
7520                        // doesn't kill our process.
7521                        Slog.i(TAG,
7522                                "Existing provider " + cpr.name.flattenToShortString()
7523                                + " is crashing; detaching " + r);
7524                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7525                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7526                        if (!lastRef) {
7527                            // This wasn't the last ref our process had on
7528                            // the provider...  we have now been killed, bail.
7529                            return null;
7530                        }
7531                        providerRunning = false;
7532                        conn = null;
7533                    }
7534                }
7535
7536                Binder.restoreCallingIdentity(origId);
7537            }
7538
7539            boolean singleton;
7540            if (!providerRunning) {
7541                try {
7542                    cpi = AppGlobals.getPackageManager().
7543                        resolveContentProvider(name,
7544                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7545                } catch (RemoteException ex) {
7546                }
7547                if (cpi == null) {
7548                    return null;
7549                }
7550                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7551                        cpi.name, cpi.flags);
7552                if (singleton) {
7553                    userId = 0;
7554                }
7555                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7556
7557                String msg;
7558                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7559                    throw new SecurityException(msg);
7560                }
7561
7562                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7563                        && !cpi.processName.equals("system")) {
7564                    // If this content provider does not run in the system
7565                    // process, and the system is not yet ready to run other
7566                    // processes, then fail fast instead of hanging.
7567                    throw new IllegalArgumentException(
7568                            "Attempt to launch content provider before system ready");
7569                }
7570
7571                // Make sure that the user who owns this provider is started.  If not,
7572                // we don't want to allow it to run.
7573                if (mStartedUsers.get(userId) == null) {
7574                    Slog.w(TAG, "Unable to launch app "
7575                            + cpi.applicationInfo.packageName + "/"
7576                            + cpi.applicationInfo.uid + " for provider "
7577                            + name + ": user " + userId + " is stopped");
7578                    return null;
7579                }
7580
7581                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7582                cpr = mProviderMap.getProviderByClass(comp, userId);
7583                final boolean firstClass = cpr == null;
7584                if (firstClass) {
7585                    try {
7586                        ApplicationInfo ai =
7587                            AppGlobals.getPackageManager().
7588                                getApplicationInfo(
7589                                        cpi.applicationInfo.packageName,
7590                                        STOCK_PM_FLAGS, userId);
7591                        if (ai == null) {
7592                            Slog.w(TAG, "No package info for content provider "
7593                                    + cpi.name);
7594                            return null;
7595                        }
7596                        ai = getAppInfoForUser(ai, userId);
7597                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7598                    } catch (RemoteException ex) {
7599                        // pm is in same process, this will never happen.
7600                    }
7601                }
7602
7603                if (r != null && cpr.canRunHere(r)) {
7604                    // If this is a multiprocess provider, then just return its
7605                    // info and allow the caller to instantiate it.  Only do
7606                    // this if the provider is the same user as the caller's
7607                    // process, or can run as root (so can be in any process).
7608                    return cpr.newHolder(null);
7609                }
7610
7611                if (DEBUG_PROVIDER) {
7612                    RuntimeException e = new RuntimeException("here");
7613                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7614                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7615                }
7616
7617                // This is single process, and our app is now connecting to it.
7618                // See if we are already in the process of launching this
7619                // provider.
7620                final int N = mLaunchingProviders.size();
7621                int i;
7622                for (i=0; i<N; i++) {
7623                    if (mLaunchingProviders.get(i) == cpr) {
7624                        break;
7625                    }
7626                }
7627
7628                // If the provider is not already being launched, then get it
7629                // started.
7630                if (i >= N) {
7631                    final long origId = Binder.clearCallingIdentity();
7632
7633                    try {
7634                        // Content provider is now in use, its package can't be stopped.
7635                        try {
7636                            AppGlobals.getPackageManager().setPackageStoppedState(
7637                                    cpr.appInfo.packageName, false, userId);
7638                        } catch (RemoteException e) {
7639                        } catch (IllegalArgumentException e) {
7640                            Slog.w(TAG, "Failed trying to unstop package "
7641                                    + cpr.appInfo.packageName + ": " + e);
7642                        }
7643
7644                        // Use existing process if already started
7645                        ProcessRecord proc = getProcessRecordLocked(
7646                                cpi.processName, cpr.appInfo.uid, false);
7647                        if (proc != null && proc.thread != null) {
7648                            if (DEBUG_PROVIDER) {
7649                                Slog.d(TAG, "Installing in existing process " + proc);
7650                            }
7651                            proc.pubProviders.put(cpi.name, cpr);
7652                            try {
7653                                proc.thread.scheduleInstallProvider(cpi);
7654                            } catch (RemoteException e) {
7655                            }
7656                        } else {
7657                            proc = startProcessLocked(cpi.processName,
7658                                    cpr.appInfo, false, 0, "content provider",
7659                                    new ComponentName(cpi.applicationInfo.packageName,
7660                                            cpi.name), false, false, false);
7661                            if (proc == null) {
7662                                Slog.w(TAG, "Unable to launch app "
7663                                        + cpi.applicationInfo.packageName + "/"
7664                                        + cpi.applicationInfo.uid + " for provider "
7665                                        + name + ": process is bad");
7666                                return null;
7667                            }
7668                        }
7669                        cpr.launchingApp = proc;
7670                        mLaunchingProviders.add(cpr);
7671                    } finally {
7672                        Binder.restoreCallingIdentity(origId);
7673                    }
7674                }
7675
7676                // Make sure the provider is published (the same provider class
7677                // may be published under multiple names).
7678                if (firstClass) {
7679                    mProviderMap.putProviderByClass(comp, cpr);
7680                }
7681
7682                mProviderMap.putProviderByName(name, cpr);
7683                conn = incProviderCountLocked(r, cpr, token, stable);
7684                if (conn != null) {
7685                    conn.waiting = true;
7686                }
7687            }
7688        }
7689
7690        // Wait for the provider to be published...
7691        synchronized (cpr) {
7692            while (cpr.provider == null) {
7693                if (cpr.launchingApp == null) {
7694                    Slog.w(TAG, "Unable to launch app "
7695                            + cpi.applicationInfo.packageName + "/"
7696                            + cpi.applicationInfo.uid + " for provider "
7697                            + name + ": launching app became null");
7698                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7699                            UserHandle.getUserId(cpi.applicationInfo.uid),
7700                            cpi.applicationInfo.packageName,
7701                            cpi.applicationInfo.uid, name);
7702                    return null;
7703                }
7704                try {
7705                    if (DEBUG_MU) {
7706                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7707                                + cpr.launchingApp);
7708                    }
7709                    if (conn != null) {
7710                        conn.waiting = true;
7711                    }
7712                    cpr.wait();
7713                } catch (InterruptedException ex) {
7714                } finally {
7715                    if (conn != null) {
7716                        conn.waiting = false;
7717                    }
7718                }
7719            }
7720        }
7721        return cpr != null ? cpr.newHolder(conn) : null;
7722    }
7723
7724    public final ContentProviderHolder getContentProvider(
7725            IApplicationThread caller, String name, int userId, boolean stable) {
7726        enforceNotIsolatedCaller("getContentProvider");
7727        if (caller == null) {
7728            String msg = "null IApplicationThread when getting content provider "
7729                    + name;
7730            Slog.w(TAG, msg);
7731            throw new SecurityException(msg);
7732        }
7733
7734        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7735                false, true, "getContentProvider", null);
7736        return getContentProviderImpl(caller, name, null, stable, userId);
7737    }
7738
7739    public ContentProviderHolder getContentProviderExternal(
7740            String name, int userId, IBinder token) {
7741        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7742            "Do not have permission in call getContentProviderExternal()");
7743        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7744                false, true, "getContentProvider", null);
7745        return getContentProviderExternalUnchecked(name, token, userId);
7746    }
7747
7748    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7749            IBinder token, int userId) {
7750        return getContentProviderImpl(null, name, token, true, userId);
7751    }
7752
7753    /**
7754     * Drop a content provider from a ProcessRecord's bookkeeping
7755     */
7756    public void removeContentProvider(IBinder connection, boolean stable) {
7757        enforceNotIsolatedCaller("removeContentProvider");
7758        synchronized (this) {
7759            ContentProviderConnection conn;
7760            try {
7761                conn = (ContentProviderConnection)connection;
7762            } catch (ClassCastException e) {
7763                String msg ="removeContentProvider: " + connection
7764                        + " not a ContentProviderConnection";
7765                Slog.w(TAG, msg);
7766                throw new IllegalArgumentException(msg);
7767            }
7768            if (conn == null) {
7769                throw new NullPointerException("connection is null");
7770            }
7771            if (decProviderCountLocked(conn, null, null, stable)) {
7772                updateOomAdjLocked();
7773            }
7774        }
7775    }
7776
7777    public void removeContentProviderExternal(String name, IBinder token) {
7778        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7779            "Do not have permission in call removeContentProviderExternal()");
7780        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7781    }
7782
7783    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7784        synchronized (this) {
7785            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7786            if(cpr == null) {
7787                //remove from mProvidersByClass
7788                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7789                return;
7790            }
7791
7792            //update content provider record entry info
7793            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7794            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7795            if (localCpr.hasExternalProcessHandles()) {
7796                if (localCpr.removeExternalProcessHandleLocked(token)) {
7797                    updateOomAdjLocked();
7798                } else {
7799                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7800                            + " with no external reference for token: "
7801                            + token + ".");
7802                }
7803            } else {
7804                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7805                        + " with no external references.");
7806            }
7807        }
7808    }
7809
7810    public final void publishContentProviders(IApplicationThread caller,
7811            List<ContentProviderHolder> providers) {
7812        if (providers == null) {
7813            return;
7814        }
7815
7816        enforceNotIsolatedCaller("publishContentProviders");
7817        synchronized (this) {
7818            final ProcessRecord r = getRecordForAppLocked(caller);
7819            if (DEBUG_MU)
7820                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7821            if (r == null) {
7822                throw new SecurityException(
7823                        "Unable to find app for caller " + caller
7824                      + " (pid=" + Binder.getCallingPid()
7825                      + ") when publishing content providers");
7826            }
7827
7828            final long origId = Binder.clearCallingIdentity();
7829
7830            final int N = providers.size();
7831            for (int i=0; i<N; i++) {
7832                ContentProviderHolder src = providers.get(i);
7833                if (src == null || src.info == null || src.provider == null) {
7834                    continue;
7835                }
7836                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7837                if (DEBUG_MU)
7838                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7839                if (dst != null) {
7840                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7841                    mProviderMap.putProviderByClass(comp, dst);
7842                    String names[] = dst.info.authority.split(";");
7843                    for (int j = 0; j < names.length; j++) {
7844                        mProviderMap.putProviderByName(names[j], dst);
7845                    }
7846
7847                    int NL = mLaunchingProviders.size();
7848                    int j;
7849                    for (j=0; j<NL; j++) {
7850                        if (mLaunchingProviders.get(j) == dst) {
7851                            mLaunchingProviders.remove(j);
7852                            j--;
7853                            NL--;
7854                        }
7855                    }
7856                    synchronized (dst) {
7857                        dst.provider = src.provider;
7858                        dst.proc = r;
7859                        dst.notifyAll();
7860                    }
7861                    updateOomAdjLocked(r);
7862                }
7863            }
7864
7865            Binder.restoreCallingIdentity(origId);
7866        }
7867    }
7868
7869    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7870        ContentProviderConnection conn;
7871        try {
7872            conn = (ContentProviderConnection)connection;
7873        } catch (ClassCastException e) {
7874            String msg ="refContentProvider: " + connection
7875                    + " not a ContentProviderConnection";
7876            Slog.w(TAG, msg);
7877            throw new IllegalArgumentException(msg);
7878        }
7879        if (conn == null) {
7880            throw new NullPointerException("connection is null");
7881        }
7882
7883        synchronized (this) {
7884            if (stable > 0) {
7885                conn.numStableIncs += stable;
7886            }
7887            stable = conn.stableCount + stable;
7888            if (stable < 0) {
7889                throw new IllegalStateException("stableCount < 0: " + stable);
7890            }
7891
7892            if (unstable > 0) {
7893                conn.numUnstableIncs += unstable;
7894            }
7895            unstable = conn.unstableCount + unstable;
7896            if (unstable < 0) {
7897                throw new IllegalStateException("unstableCount < 0: " + unstable);
7898            }
7899
7900            if ((stable+unstable) <= 0) {
7901                throw new IllegalStateException("ref counts can't go to zero here: stable="
7902                        + stable + " unstable=" + unstable);
7903            }
7904            conn.stableCount = stable;
7905            conn.unstableCount = unstable;
7906            return !conn.dead;
7907        }
7908    }
7909
7910    public void unstableProviderDied(IBinder connection) {
7911        ContentProviderConnection conn;
7912        try {
7913            conn = (ContentProviderConnection)connection;
7914        } catch (ClassCastException e) {
7915            String msg ="refContentProvider: " + connection
7916                    + " not a ContentProviderConnection";
7917            Slog.w(TAG, msg);
7918            throw new IllegalArgumentException(msg);
7919        }
7920        if (conn == null) {
7921            throw new NullPointerException("connection is null");
7922        }
7923
7924        // Safely retrieve the content provider associated with the connection.
7925        IContentProvider provider;
7926        synchronized (this) {
7927            provider = conn.provider.provider;
7928        }
7929
7930        if (provider == null) {
7931            // Um, yeah, we're way ahead of you.
7932            return;
7933        }
7934
7935        // Make sure the caller is being honest with us.
7936        if (provider.asBinder().pingBinder()) {
7937            // Er, no, still looks good to us.
7938            synchronized (this) {
7939                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7940                        + " says " + conn + " died, but we don't agree");
7941                return;
7942            }
7943        }
7944
7945        // Well look at that!  It's dead!
7946        synchronized (this) {
7947            if (conn.provider.provider != provider) {
7948                // But something changed...  good enough.
7949                return;
7950            }
7951
7952            ProcessRecord proc = conn.provider.proc;
7953            if (proc == null || proc.thread == null) {
7954                // Seems like the process is already cleaned up.
7955                return;
7956            }
7957
7958            // As far as we're concerned, this is just like receiving a
7959            // death notification...  just a bit prematurely.
7960            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7961                    + ") early provider death");
7962            final long ident = Binder.clearCallingIdentity();
7963            try {
7964                appDiedLocked(proc, proc.pid, proc.thread);
7965            } finally {
7966                Binder.restoreCallingIdentity(ident);
7967            }
7968        }
7969    }
7970
7971    @Override
7972    public void appNotRespondingViaProvider(IBinder connection) {
7973        enforceCallingPermission(
7974                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7975
7976        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7977        if (conn == null) {
7978            Slog.w(TAG, "ContentProviderConnection is null");
7979            return;
7980        }
7981
7982        final ProcessRecord host = conn.provider.proc;
7983        if (host == null) {
7984            Slog.w(TAG, "Failed to find hosting ProcessRecord");
7985            return;
7986        }
7987
7988        final long token = Binder.clearCallingIdentity();
7989        try {
7990            appNotResponding(host, null, null, false, "ContentProvider not responding");
7991        } finally {
7992            Binder.restoreCallingIdentity(token);
7993        }
7994    }
7995
7996    public final void installSystemProviders() {
7997        List<ProviderInfo> providers;
7998        synchronized (this) {
7999            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8000            providers = generateApplicationProvidersLocked(app);
8001            if (providers != null) {
8002                for (int i=providers.size()-1; i>=0; i--) {
8003                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8004                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8005                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8006                                + ": not system .apk");
8007                        providers.remove(i);
8008                    }
8009                }
8010            }
8011        }
8012        if (providers != null) {
8013            mSystemThread.installSystemProviders(providers);
8014        }
8015
8016        mCoreSettingsObserver = new CoreSettingsObserver(this);
8017
8018        mUsageStatsService.monitorPackages();
8019    }
8020
8021    /**
8022     * Allows app to retrieve the MIME type of a URI without having permission
8023     * to access its content provider.
8024     *
8025     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8026     *
8027     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8028     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8029     */
8030    public String getProviderMimeType(Uri uri, int userId) {
8031        enforceNotIsolatedCaller("getProviderMimeType");
8032        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8033                userId, false, true, "getProviderMimeType", null);
8034        final String name = uri.getAuthority();
8035        final long ident = Binder.clearCallingIdentity();
8036        ContentProviderHolder holder = null;
8037
8038        try {
8039            holder = getContentProviderExternalUnchecked(name, null, userId);
8040            if (holder != null) {
8041                return holder.provider.getType(uri);
8042            }
8043        } catch (RemoteException e) {
8044            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8045            return null;
8046        } finally {
8047            if (holder != null) {
8048                removeContentProviderExternalUnchecked(name, null, userId);
8049            }
8050            Binder.restoreCallingIdentity(ident);
8051        }
8052
8053        return null;
8054    }
8055
8056    // =========================================================
8057    // GLOBAL MANAGEMENT
8058    // =========================================================
8059
8060    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8061            boolean isolated) {
8062        String proc = customProcess != null ? customProcess : info.processName;
8063        BatteryStatsImpl.Uid.Proc ps = null;
8064        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8065        int uid = info.uid;
8066        if (isolated) {
8067            int userId = UserHandle.getUserId(uid);
8068            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8069            while (true) {
8070                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8071                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8072                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8073                }
8074                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8075                mNextIsolatedProcessUid++;
8076                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8077                    // No process for this uid, use it.
8078                    break;
8079                }
8080                stepsLeft--;
8081                if (stepsLeft <= 0) {
8082                    return null;
8083                }
8084            }
8085        }
8086        return new ProcessRecord(stats, info, proc, uid);
8087    }
8088
8089    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8090        ProcessRecord app;
8091        if (!isolated) {
8092            app = getProcessRecordLocked(info.processName, info.uid, true);
8093        } else {
8094            app = null;
8095        }
8096
8097        if (app == null) {
8098            app = newProcessRecordLocked(info, null, isolated);
8099            mProcessNames.put(info.processName, app.uid, app);
8100            if (isolated) {
8101                mIsolatedProcesses.put(app.uid, app);
8102            }
8103            updateLruProcessLocked(app, false, null);
8104            updateOomAdjLocked();
8105        }
8106
8107        // This package really, really can not be stopped.
8108        try {
8109            AppGlobals.getPackageManager().setPackageStoppedState(
8110                    info.packageName, false, UserHandle.getUserId(app.uid));
8111        } catch (RemoteException e) {
8112        } catch (IllegalArgumentException e) {
8113            Slog.w(TAG, "Failed trying to unstop package "
8114                    + info.packageName + ": " + e);
8115        }
8116
8117        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8118                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8119            app.persistent = true;
8120            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8121        }
8122        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8123            mPersistentStartingProcesses.add(app);
8124            startProcessLocked(app, "added application", app.processName);
8125        }
8126
8127        return app;
8128    }
8129
8130    public void unhandledBack() {
8131        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8132                "unhandledBack()");
8133
8134        synchronized(this) {
8135            final long origId = Binder.clearCallingIdentity();
8136            try {
8137                getFocusedStack().unhandledBackLocked();
8138            } finally {
8139                Binder.restoreCallingIdentity(origId);
8140            }
8141        }
8142    }
8143
8144    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8145        enforceNotIsolatedCaller("openContentUri");
8146        final int userId = UserHandle.getCallingUserId();
8147        String name = uri.getAuthority();
8148        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8149        ParcelFileDescriptor pfd = null;
8150        if (cph != null) {
8151            // We record the binder invoker's uid in thread-local storage before
8152            // going to the content provider to open the file.  Later, in the code
8153            // that handles all permissions checks, we look for this uid and use
8154            // that rather than the Activity Manager's own uid.  The effect is that
8155            // we do the check against the caller's permissions even though it looks
8156            // to the content provider like the Activity Manager itself is making
8157            // the request.
8158            sCallerIdentity.set(new Identity(
8159                    Binder.getCallingPid(), Binder.getCallingUid()));
8160            try {
8161                pfd = cph.provider.openFile(null, uri, "r", null);
8162            } catch (FileNotFoundException e) {
8163                // do nothing; pfd will be returned null
8164            } finally {
8165                // Ensure that whatever happens, we clean up the identity state
8166                sCallerIdentity.remove();
8167            }
8168
8169            // We've got the fd now, so we're done with the provider.
8170            removeContentProviderExternalUnchecked(name, null, userId);
8171        } else {
8172            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8173        }
8174        return pfd;
8175    }
8176
8177    // Actually is sleeping or shutting down or whatever else in the future
8178    // is an inactive state.
8179    public boolean isSleepingOrShuttingDown() {
8180        return mSleeping || mShuttingDown;
8181    }
8182
8183    public void goingToSleep() {
8184        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8185                != PackageManager.PERMISSION_GRANTED) {
8186            throw new SecurityException("Requires permission "
8187                    + android.Manifest.permission.DEVICE_POWER);
8188        }
8189
8190        synchronized(this) {
8191            mWentToSleep = true;
8192            updateEventDispatchingLocked();
8193
8194            if (!mSleeping) {
8195                mSleeping = true;
8196                mStackSupervisor.goingToSleepLocked();
8197
8198                // Initialize the wake times of all processes.
8199                checkExcessivePowerUsageLocked(false);
8200                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8201                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8202                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8203            }
8204        }
8205    }
8206
8207    @Override
8208    public boolean shutdown(int timeout) {
8209        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8210                != PackageManager.PERMISSION_GRANTED) {
8211            throw new SecurityException("Requires permission "
8212                    + android.Manifest.permission.SHUTDOWN);
8213        }
8214
8215        boolean timedout = false;
8216
8217        synchronized(this) {
8218            mShuttingDown = true;
8219            updateEventDispatchingLocked();
8220            timedout = mStackSupervisor.shutdownLocked(timeout);
8221        }
8222
8223        mAppOpsService.shutdown();
8224        mUsageStatsService.shutdown();
8225        mBatteryStatsService.shutdown();
8226        synchronized (this) {
8227            mProcessStats.shutdownLocked();
8228        }
8229
8230        return timedout;
8231    }
8232
8233    public final void activitySlept(IBinder token) {
8234        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8235
8236        final long origId = Binder.clearCallingIdentity();
8237
8238        synchronized (this) {
8239            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8240            if (r != null) {
8241                mStackSupervisor.activitySleptLocked(r);
8242            }
8243        }
8244
8245        Binder.restoreCallingIdentity(origId);
8246    }
8247
8248    void logLockScreen(String msg) {
8249        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8250                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8251                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8252                mStackSupervisor.mDismissKeyguardOnNextActivity);
8253    }
8254
8255    private void comeOutOfSleepIfNeededLocked() {
8256        if (!mWentToSleep && !mLockScreenShown) {
8257            if (mSleeping) {
8258                mSleeping = false;
8259                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8260            }
8261        }
8262    }
8263
8264    public void wakingUp() {
8265        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8266                != PackageManager.PERMISSION_GRANTED) {
8267            throw new SecurityException("Requires permission "
8268                    + android.Manifest.permission.DEVICE_POWER);
8269        }
8270
8271        synchronized(this) {
8272            mWentToSleep = false;
8273            updateEventDispatchingLocked();
8274            comeOutOfSleepIfNeededLocked();
8275        }
8276    }
8277
8278    private void updateEventDispatchingLocked() {
8279        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8280    }
8281
8282    public void setLockScreenShown(boolean shown) {
8283        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8284                != PackageManager.PERMISSION_GRANTED) {
8285            throw new SecurityException("Requires permission "
8286                    + android.Manifest.permission.DEVICE_POWER);
8287        }
8288
8289        synchronized(this) {
8290            long ident = Binder.clearCallingIdentity();
8291            try {
8292                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8293                mLockScreenShown = shown;
8294                comeOutOfSleepIfNeededLocked();
8295            } finally {
8296                Binder.restoreCallingIdentity(ident);
8297            }
8298        }
8299    }
8300
8301    public void stopAppSwitches() {
8302        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8303                != PackageManager.PERMISSION_GRANTED) {
8304            throw new SecurityException("Requires permission "
8305                    + android.Manifest.permission.STOP_APP_SWITCHES);
8306        }
8307
8308        synchronized(this) {
8309            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8310                    + APP_SWITCH_DELAY_TIME;
8311            mDidAppSwitch = false;
8312            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8313            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8314            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8315        }
8316    }
8317
8318    public void resumeAppSwitches() {
8319        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8320                != PackageManager.PERMISSION_GRANTED) {
8321            throw new SecurityException("Requires permission "
8322                    + android.Manifest.permission.STOP_APP_SWITCHES);
8323        }
8324
8325        synchronized(this) {
8326            // Note that we don't execute any pending app switches... we will
8327            // let those wait until either the timeout, or the next start
8328            // activity request.
8329            mAppSwitchesAllowedTime = 0;
8330        }
8331    }
8332
8333    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8334            String name) {
8335        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8336            return true;
8337        }
8338
8339        final int perm = checkComponentPermission(
8340                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8341                callingUid, -1, true);
8342        if (perm == PackageManager.PERMISSION_GRANTED) {
8343            return true;
8344        }
8345
8346        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8347        return false;
8348    }
8349
8350    public void setDebugApp(String packageName, boolean waitForDebugger,
8351            boolean persistent) {
8352        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8353                "setDebugApp()");
8354
8355        long ident = Binder.clearCallingIdentity();
8356        try {
8357            // Note that this is not really thread safe if there are multiple
8358            // callers into it at the same time, but that's not a situation we
8359            // care about.
8360            if (persistent) {
8361                final ContentResolver resolver = mContext.getContentResolver();
8362                Settings.Global.putString(
8363                    resolver, Settings.Global.DEBUG_APP,
8364                    packageName);
8365                Settings.Global.putInt(
8366                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8367                    waitForDebugger ? 1 : 0);
8368            }
8369
8370            synchronized (this) {
8371                if (!persistent) {
8372                    mOrigDebugApp = mDebugApp;
8373                    mOrigWaitForDebugger = mWaitForDebugger;
8374                }
8375                mDebugApp = packageName;
8376                mWaitForDebugger = waitForDebugger;
8377                mDebugTransient = !persistent;
8378                if (packageName != null) {
8379                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8380                            false, UserHandle.USER_ALL, "set debug app");
8381                }
8382            }
8383        } finally {
8384            Binder.restoreCallingIdentity(ident);
8385        }
8386    }
8387
8388    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8389        synchronized (this) {
8390            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8391            if (!isDebuggable) {
8392                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8393                    throw new SecurityException("Process not debuggable: " + app.packageName);
8394                }
8395            }
8396
8397            mOpenGlTraceApp = processName;
8398        }
8399    }
8400
8401    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8402            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8403        synchronized (this) {
8404            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8405            if (!isDebuggable) {
8406                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8407                    throw new SecurityException("Process not debuggable: " + app.packageName);
8408                }
8409            }
8410            mProfileApp = processName;
8411            mProfileFile = profileFile;
8412            if (mProfileFd != null) {
8413                try {
8414                    mProfileFd.close();
8415                } catch (IOException e) {
8416                }
8417                mProfileFd = null;
8418            }
8419            mProfileFd = profileFd;
8420            mProfileType = 0;
8421            mAutoStopProfiler = autoStopProfiler;
8422        }
8423    }
8424
8425    @Override
8426    public void setAlwaysFinish(boolean enabled) {
8427        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8428                "setAlwaysFinish()");
8429
8430        Settings.Global.putInt(
8431                mContext.getContentResolver(),
8432                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8433
8434        synchronized (this) {
8435            mAlwaysFinishActivities = enabled;
8436        }
8437    }
8438
8439    @Override
8440    public void setActivityController(IActivityController controller) {
8441        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8442                "setActivityController()");
8443        synchronized (this) {
8444            mController = controller;
8445            Watchdog.getInstance().setActivityController(controller);
8446        }
8447    }
8448
8449    @Override
8450    public void setUserIsMonkey(boolean userIsMonkey) {
8451        synchronized (this) {
8452            synchronized (mPidsSelfLocked) {
8453                final int callingPid = Binder.getCallingPid();
8454                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8455                if (precessRecord == null) {
8456                    throw new SecurityException("Unknown process: " + callingPid);
8457                }
8458                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8459                    throw new SecurityException("Only an instrumentation process "
8460                            + "with a UiAutomation can call setUserIsMonkey");
8461                }
8462            }
8463            mUserIsMonkey = userIsMonkey;
8464        }
8465    }
8466
8467    @Override
8468    public boolean isUserAMonkey() {
8469        synchronized (this) {
8470            // If there is a controller also implies the user is a monkey.
8471            return (mUserIsMonkey || mController != null);
8472        }
8473    }
8474
8475    public void requestBugReport() {
8476        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8477        SystemProperties.set("ctl.start", "bugreport");
8478    }
8479
8480    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8481        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8482    }
8483
8484    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8485        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8486            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8487        }
8488        return KEY_DISPATCHING_TIMEOUT;
8489    }
8490
8491    @Override
8492    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8493        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8494                != PackageManager.PERMISSION_GRANTED) {
8495            throw new SecurityException("Requires permission "
8496                    + android.Manifest.permission.FILTER_EVENTS);
8497        }
8498        ProcessRecord proc;
8499        long timeout;
8500        synchronized (this) {
8501            synchronized (mPidsSelfLocked) {
8502                proc = mPidsSelfLocked.get(pid);
8503            }
8504            timeout = getInputDispatchingTimeoutLocked(proc);
8505        }
8506
8507        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8508            return -1;
8509        }
8510
8511        return timeout;
8512    }
8513
8514    /**
8515     * Handle input dispatching timeouts.
8516     * Returns whether input dispatching should be aborted or not.
8517     */
8518    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8519            final ActivityRecord activity, final ActivityRecord parent,
8520            final boolean aboveSystem, String reason) {
8521        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8522                != PackageManager.PERMISSION_GRANTED) {
8523            throw new SecurityException("Requires permission "
8524                    + android.Manifest.permission.FILTER_EVENTS);
8525        }
8526
8527        final String annotation;
8528        if (reason == null) {
8529            annotation = "Input dispatching timed out";
8530        } else {
8531            annotation = "Input dispatching timed out (" + reason + ")";
8532        }
8533
8534        if (proc != null) {
8535            synchronized (this) {
8536                if (proc.debugging) {
8537                    return false;
8538                }
8539
8540                if (mDidDexOpt) {
8541                    // Give more time since we were dexopting.
8542                    mDidDexOpt = false;
8543                    return false;
8544                }
8545
8546                if (proc.instrumentationClass != null) {
8547                    Bundle info = new Bundle();
8548                    info.putString("shortMsg", "keyDispatchingTimedOut");
8549                    info.putString("longMsg", annotation);
8550                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8551                    return true;
8552                }
8553            }
8554            mHandler.post(new Runnable() {
8555                @Override
8556                public void run() {
8557                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8558                }
8559            });
8560        }
8561
8562        return true;
8563    }
8564
8565    public Bundle getAssistContextExtras(int requestType) {
8566        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8567                "getAssistContextExtras()");
8568        PendingAssistExtras pae;
8569        Bundle extras = new Bundle();
8570        synchronized (this) {
8571            ActivityRecord activity = getFocusedStack().mResumedActivity;
8572            if (activity == null) {
8573                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8574                return null;
8575            }
8576            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8577            if (activity.app == null || activity.app.thread == null) {
8578                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8579                return extras;
8580            }
8581            if (activity.app.pid == Binder.getCallingPid()) {
8582                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8583                return extras;
8584            }
8585            pae = new PendingAssistExtras(activity);
8586            try {
8587                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8588                        requestType);
8589                mPendingAssistExtras.add(pae);
8590                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8591            } catch (RemoteException e) {
8592                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8593                return extras;
8594            }
8595        }
8596        synchronized (pae) {
8597            while (!pae.haveResult) {
8598                try {
8599                    pae.wait();
8600                } catch (InterruptedException e) {
8601                }
8602            }
8603            if (pae.result != null) {
8604                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8605            }
8606        }
8607        synchronized (this) {
8608            mPendingAssistExtras.remove(pae);
8609            mHandler.removeCallbacks(pae);
8610        }
8611        return extras;
8612    }
8613
8614    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8615        PendingAssistExtras pae = (PendingAssistExtras)token;
8616        synchronized (pae) {
8617            pae.result = extras;
8618            pae.haveResult = true;
8619            pae.notifyAll();
8620        }
8621    }
8622
8623    public void registerProcessObserver(IProcessObserver observer) {
8624        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8625                "registerProcessObserver()");
8626        synchronized (this) {
8627            mProcessObservers.register(observer);
8628        }
8629    }
8630
8631    @Override
8632    public void unregisterProcessObserver(IProcessObserver observer) {
8633        synchronized (this) {
8634            mProcessObservers.unregister(observer);
8635        }
8636    }
8637
8638    @Override
8639    public boolean convertFromTranslucent(IBinder token) {
8640        final long origId = Binder.clearCallingIdentity();
8641        try {
8642            synchronized (this) {
8643                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8644                if (r == null) {
8645                    return false;
8646                }
8647                if (r.changeWindowTranslucency(true)) {
8648                    mWindowManager.setAppFullscreen(token, true);
8649                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8650                    return true;
8651                }
8652                return false;
8653            }
8654        } finally {
8655            Binder.restoreCallingIdentity(origId);
8656        }
8657    }
8658
8659    @Override
8660    public boolean convertToTranslucent(IBinder token) {
8661        final long origId = Binder.clearCallingIdentity();
8662        try {
8663            synchronized (this) {
8664                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8665                if (r == null) {
8666                    return false;
8667                }
8668                if (r.changeWindowTranslucency(false)) {
8669                    r.task.stack.convertToTranslucent(r);
8670                    mWindowManager.setAppFullscreen(token, false);
8671                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8672                    return true;
8673                }
8674                return false;
8675            }
8676        } finally {
8677            Binder.restoreCallingIdentity(origId);
8678        }
8679    }
8680
8681    @Override
8682    public void setImmersive(IBinder token, boolean immersive) {
8683        synchronized(this) {
8684            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8685            if (r == null) {
8686                throw new IllegalArgumentException();
8687            }
8688            r.immersive = immersive;
8689
8690            // update associated state if we're frontmost
8691            if (r == mFocusedActivity) {
8692                if (DEBUG_IMMERSIVE) {
8693                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8694                }
8695                applyUpdateLockStateLocked(r);
8696            }
8697        }
8698    }
8699
8700    @Override
8701    public boolean isImmersive(IBinder token) {
8702        synchronized (this) {
8703            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8704            if (r == null) {
8705                throw new IllegalArgumentException();
8706            }
8707            return r.immersive;
8708        }
8709    }
8710
8711    public boolean isTopActivityImmersive() {
8712        enforceNotIsolatedCaller("startActivity");
8713        synchronized (this) {
8714            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8715            return (r != null) ? r.immersive : false;
8716        }
8717    }
8718
8719    public final void enterSafeMode() {
8720        synchronized(this) {
8721            // It only makes sense to do this before the system is ready
8722            // and started launching other packages.
8723            if (!mSystemReady) {
8724                try {
8725                    AppGlobals.getPackageManager().enterSafeMode();
8726                } catch (RemoteException e) {
8727                }
8728            }
8729        }
8730    }
8731
8732    public final void showSafeModeOverlay() {
8733        View v = LayoutInflater.from(mContext).inflate(
8734                com.android.internal.R.layout.safe_mode, null);
8735        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8736        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8737        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8738        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8739        lp.gravity = Gravity.BOTTOM | Gravity.START;
8740        lp.format = v.getBackground().getOpacity();
8741        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8742                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8743        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8744        ((WindowManager)mContext.getSystemService(
8745                Context.WINDOW_SERVICE)).addView(v, lp);
8746    }
8747
8748    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8749        if (!(sender instanceof PendingIntentRecord)) {
8750            return;
8751        }
8752        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8753        synchronized (stats) {
8754            if (mBatteryStatsService.isOnBattery()) {
8755                mBatteryStatsService.enforceCallingPermission();
8756                PendingIntentRecord rec = (PendingIntentRecord)sender;
8757                int MY_UID = Binder.getCallingUid();
8758                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8759                BatteryStatsImpl.Uid.Pkg pkg =
8760                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8761                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8762                pkg.incWakeupsLocked();
8763            }
8764        }
8765    }
8766
8767    public boolean killPids(int[] pids, String pReason, boolean secure) {
8768        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8769            throw new SecurityException("killPids only available to the system");
8770        }
8771        String reason = (pReason == null) ? "Unknown" : pReason;
8772        // XXX Note: don't acquire main activity lock here, because the window
8773        // manager calls in with its locks held.
8774
8775        boolean killed = false;
8776        synchronized (mPidsSelfLocked) {
8777            int[] types = new int[pids.length];
8778            int worstType = 0;
8779            for (int i=0; i<pids.length; i++) {
8780                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8781                if (proc != null) {
8782                    int type = proc.setAdj;
8783                    types[i] = type;
8784                    if (type > worstType) {
8785                        worstType = type;
8786                    }
8787                }
8788            }
8789
8790            // If the worst oom_adj is somewhere in the cached proc LRU range,
8791            // then constrain it so we will kill all cached procs.
8792            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8793                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8794                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8795            }
8796
8797            // If this is not a secure call, don't let it kill processes that
8798            // are important.
8799            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8800                worstType = ProcessList.SERVICE_ADJ;
8801            }
8802
8803            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8804            for (int i=0; i<pids.length; i++) {
8805                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8806                if (proc == null) {
8807                    continue;
8808                }
8809                int adj = proc.setAdj;
8810                if (adj >= worstType && !proc.killedByAm) {
8811                    killUnneededProcessLocked(proc, reason);
8812                    killed = true;
8813                }
8814            }
8815        }
8816        return killed;
8817    }
8818
8819    @Override
8820    public void killUid(int uid, String reason) {
8821        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8822            throw new SecurityException("killUid only available to the system");
8823        }
8824        synchronized (this) {
8825            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8826                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8827                    reason != null ? reason : "kill uid");
8828        }
8829    }
8830
8831    @Override
8832    public boolean killProcessesBelowForeground(String reason) {
8833        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8834            throw new SecurityException("killProcessesBelowForeground() only available to system");
8835        }
8836
8837        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8838    }
8839
8840    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8841        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8842            throw new SecurityException("killProcessesBelowAdj() only available to system");
8843        }
8844
8845        boolean killed = false;
8846        synchronized (mPidsSelfLocked) {
8847            final int size = mPidsSelfLocked.size();
8848            for (int i = 0; i < size; i++) {
8849                final int pid = mPidsSelfLocked.keyAt(i);
8850                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8851                if (proc == null) continue;
8852
8853                final int adj = proc.setAdj;
8854                if (adj > belowAdj && !proc.killedByAm) {
8855                    killUnneededProcessLocked(proc, reason);
8856                    killed = true;
8857                }
8858            }
8859        }
8860        return killed;
8861    }
8862
8863    @Override
8864    public void hang(final IBinder who, boolean allowRestart) {
8865        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8866                != PackageManager.PERMISSION_GRANTED) {
8867            throw new SecurityException("Requires permission "
8868                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8869        }
8870
8871        final IBinder.DeathRecipient death = new DeathRecipient() {
8872            @Override
8873            public void binderDied() {
8874                synchronized (this) {
8875                    notifyAll();
8876                }
8877            }
8878        };
8879
8880        try {
8881            who.linkToDeath(death, 0);
8882        } catch (RemoteException e) {
8883            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8884            return;
8885        }
8886
8887        synchronized (this) {
8888            Watchdog.getInstance().setAllowRestart(allowRestart);
8889            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8890            synchronized (death) {
8891                while (who.isBinderAlive()) {
8892                    try {
8893                        death.wait();
8894                    } catch (InterruptedException e) {
8895                    }
8896                }
8897            }
8898            Watchdog.getInstance().setAllowRestart(true);
8899        }
8900    }
8901
8902    @Override
8903    public void restart() {
8904        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8905                != PackageManager.PERMISSION_GRANTED) {
8906            throw new SecurityException("Requires permission "
8907                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8908        }
8909
8910        Log.i(TAG, "Sending shutdown broadcast...");
8911
8912        BroadcastReceiver br = new BroadcastReceiver() {
8913            @Override public void onReceive(Context context, Intent intent) {
8914                // Now the broadcast is done, finish up the low-level shutdown.
8915                Log.i(TAG, "Shutting down activity manager...");
8916                shutdown(10000);
8917                Log.i(TAG, "Shutdown complete, restarting!");
8918                Process.killProcess(Process.myPid());
8919                System.exit(10);
8920            }
8921        };
8922
8923        // First send the high-level shut down broadcast.
8924        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8925        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8926        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8927        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8928        mContext.sendOrderedBroadcastAsUser(intent,
8929                UserHandle.ALL, null, br, mHandler, 0, null, null);
8930        */
8931        br.onReceive(mContext, intent);
8932    }
8933
8934    private long getLowRamTimeSinceIdle(long now) {
8935        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8936    }
8937
8938    @Override
8939    public void performIdleMaintenance() {
8940        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8941                != PackageManager.PERMISSION_GRANTED) {
8942            throw new SecurityException("Requires permission "
8943                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8944        }
8945
8946        synchronized (this) {
8947            final long now = SystemClock.uptimeMillis();
8948            final long timeSinceLastIdle = now - mLastIdleTime;
8949            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8950            mLastIdleTime = now;
8951            mLowRamTimeSinceLastIdle = 0;
8952            if (mLowRamStartTime != 0) {
8953                mLowRamStartTime = now;
8954            }
8955
8956            StringBuilder sb = new StringBuilder(128);
8957            sb.append("Idle maintenance over ");
8958            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8959            sb.append(" low RAM for ");
8960            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8961            Slog.i(TAG, sb.toString());
8962
8963            // If at least 1/3 of our time since the last idle period has been spent
8964            // with RAM low, then we want to kill processes.
8965            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8966
8967            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8968                ProcessRecord proc = mLruProcesses.get(i);
8969                if (proc.notCachedSinceIdle) {
8970                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8971                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8972                        if (doKilling && proc.initialIdlePss != 0
8973                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8974                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8975                                    + " from " + proc.initialIdlePss + ")");
8976                        }
8977                    }
8978                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8979                    proc.notCachedSinceIdle = true;
8980                    proc.initialIdlePss = 0;
8981                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8982                            mSleeping, now);
8983                }
8984            }
8985
8986            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8987            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8988        }
8989    }
8990
8991    public final void startRunning(String pkg, String cls, String action,
8992            String data) {
8993        synchronized(this) {
8994            if (mStartRunning) {
8995                return;
8996            }
8997            mStartRunning = true;
8998            mTopComponent = pkg != null && cls != null
8999                    ? new ComponentName(pkg, cls) : null;
9000            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9001            mTopData = data;
9002            if (!mSystemReady) {
9003                return;
9004            }
9005        }
9006
9007        systemReady(null);
9008    }
9009
9010    private void retrieveSettings() {
9011        final ContentResolver resolver = mContext.getContentResolver();
9012        String debugApp = Settings.Global.getString(
9013            resolver, Settings.Global.DEBUG_APP);
9014        boolean waitForDebugger = Settings.Global.getInt(
9015            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9016        boolean alwaysFinishActivities = Settings.Global.getInt(
9017            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9018        boolean forceRtl = Settings.Global.getInt(
9019                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9020        // Transfer any global setting for forcing RTL layout, into a System Property
9021        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9022
9023        Configuration configuration = new Configuration();
9024        Settings.System.getConfiguration(resolver, configuration);
9025        if (forceRtl) {
9026            // This will take care of setting the correct layout direction flags
9027            configuration.setLayoutDirection(configuration.locale);
9028        }
9029
9030        synchronized (this) {
9031            mDebugApp = mOrigDebugApp = debugApp;
9032            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9033            mAlwaysFinishActivities = alwaysFinishActivities;
9034            // This happens before any activities are started, so we can
9035            // change mConfiguration in-place.
9036            updateConfigurationLocked(configuration, null, false, true);
9037            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9038        }
9039    }
9040
9041    public boolean testIsSystemReady() {
9042        // no need to synchronize(this) just to read & return the value
9043        return mSystemReady;
9044    }
9045
9046    private static File getCalledPreBootReceiversFile() {
9047        File dataDir = Environment.getDataDirectory();
9048        File systemDir = new File(dataDir, "system");
9049        File fname = new File(systemDir, "called_pre_boots.dat");
9050        return fname;
9051    }
9052
9053    static final int LAST_DONE_VERSION = 10000;
9054
9055    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9056        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9057        File file = getCalledPreBootReceiversFile();
9058        FileInputStream fis = null;
9059        try {
9060            fis = new FileInputStream(file);
9061            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9062            int fvers = dis.readInt();
9063            if (fvers == LAST_DONE_VERSION) {
9064                String vers = dis.readUTF();
9065                String codename = dis.readUTF();
9066                String build = dis.readUTF();
9067                if (android.os.Build.VERSION.RELEASE.equals(vers)
9068                        && android.os.Build.VERSION.CODENAME.equals(codename)
9069                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9070                    int num = dis.readInt();
9071                    while (num > 0) {
9072                        num--;
9073                        String pkg = dis.readUTF();
9074                        String cls = dis.readUTF();
9075                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9076                    }
9077                }
9078            }
9079        } catch (FileNotFoundException e) {
9080        } catch (IOException e) {
9081            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9082        } finally {
9083            if (fis != null) {
9084                try {
9085                    fis.close();
9086                } catch (IOException e) {
9087                }
9088            }
9089        }
9090        return lastDoneReceivers;
9091    }
9092
9093    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9094        File file = getCalledPreBootReceiversFile();
9095        FileOutputStream fos = null;
9096        DataOutputStream dos = null;
9097        try {
9098            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9099            fos = new FileOutputStream(file);
9100            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9101            dos.writeInt(LAST_DONE_VERSION);
9102            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9103            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9104            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9105            dos.writeInt(list.size());
9106            for (int i=0; i<list.size(); i++) {
9107                dos.writeUTF(list.get(i).getPackageName());
9108                dos.writeUTF(list.get(i).getClassName());
9109            }
9110        } catch (IOException e) {
9111            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9112            file.delete();
9113        } finally {
9114            FileUtils.sync(fos);
9115            if (dos != null) {
9116                try {
9117                    dos.close();
9118                } catch (IOException e) {
9119                    // TODO Auto-generated catch block
9120                    e.printStackTrace();
9121                }
9122            }
9123        }
9124    }
9125
9126    public void systemReady(final Runnable goingCallback) {
9127        synchronized(this) {
9128            if (mSystemReady) {
9129                if (goingCallback != null) goingCallback.run();
9130                return;
9131            }
9132
9133            // Check to see if there are any update receivers to run.
9134            if (!mDidUpdate) {
9135                if (mWaitingUpdate) {
9136                    return;
9137                }
9138                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9139                List<ResolveInfo> ris = null;
9140                try {
9141                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9142                            intent, null, 0, 0);
9143                } catch (RemoteException e) {
9144                }
9145                if (ris != null) {
9146                    for (int i=ris.size()-1; i>=0; i--) {
9147                        if ((ris.get(i).activityInfo.applicationInfo.flags
9148                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9149                            ris.remove(i);
9150                        }
9151                    }
9152                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9153
9154                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9155
9156                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9157                    for (int i=0; i<ris.size(); i++) {
9158                        ActivityInfo ai = ris.get(i).activityInfo;
9159                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9160                        if (lastDoneReceivers.contains(comp)) {
9161                            ris.remove(i);
9162                            i--;
9163                        }
9164                    }
9165
9166                    final int[] users = getUsersLocked();
9167                    for (int i=0; i<ris.size(); i++) {
9168                        ActivityInfo ai = ris.get(i).activityInfo;
9169                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9170                        doneReceivers.add(comp);
9171                        intent.setComponent(comp);
9172                        for (int j=0; j<users.length; j++) {
9173                            IIntentReceiver finisher = null;
9174                            if (i == ris.size()-1 && j == users.length-1) {
9175                                finisher = new IIntentReceiver.Stub() {
9176                                    public void performReceive(Intent intent, int resultCode,
9177                                            String data, Bundle extras, boolean ordered,
9178                                            boolean sticky, int sendingUser) {
9179                                        // The raw IIntentReceiver interface is called
9180                                        // with the AM lock held, so redispatch to
9181                                        // execute our code without the lock.
9182                                        mHandler.post(new Runnable() {
9183                                            public void run() {
9184                                                synchronized (ActivityManagerService.this) {
9185                                                    mDidUpdate = true;
9186                                                }
9187                                                writeLastDonePreBootReceivers(doneReceivers);
9188                                                showBootMessage(mContext.getText(
9189                                                        R.string.android_upgrading_complete),
9190                                                        false);
9191                                                systemReady(goingCallback);
9192                                            }
9193                                        });
9194                                    }
9195                                };
9196                            }
9197                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9198                                    + " for user " + users[j]);
9199                            broadcastIntentLocked(null, null, intent, null, finisher,
9200                                    0, null, null, null, AppOpsManager.OP_NONE,
9201                                    true, false, MY_PID, Process.SYSTEM_UID,
9202                                    users[j]);
9203                            if (finisher != null) {
9204                                mWaitingUpdate = true;
9205                            }
9206                        }
9207                    }
9208                }
9209                if (mWaitingUpdate) {
9210                    return;
9211                }
9212                mDidUpdate = true;
9213            }
9214
9215            mAppOpsService.systemReady();
9216            mSystemReady = true;
9217            if (!mStartRunning) {
9218                return;
9219            }
9220        }
9221
9222        ArrayList<ProcessRecord> procsToKill = null;
9223        synchronized(mPidsSelfLocked) {
9224            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9225                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9226                if (!isAllowedWhileBooting(proc.info)){
9227                    if (procsToKill == null) {
9228                        procsToKill = new ArrayList<ProcessRecord>();
9229                    }
9230                    procsToKill.add(proc);
9231                }
9232            }
9233        }
9234
9235        synchronized(this) {
9236            if (procsToKill != null) {
9237                for (int i=procsToKill.size()-1; i>=0; i--) {
9238                    ProcessRecord proc = procsToKill.get(i);
9239                    Slog.i(TAG, "Removing system update proc: " + proc);
9240                    removeProcessLocked(proc, true, false, "system update done");
9241                }
9242            }
9243
9244            // Now that we have cleaned up any update processes, we
9245            // are ready to start launching real processes and know that
9246            // we won't trample on them any more.
9247            mProcessesReady = true;
9248        }
9249
9250        Slog.i(TAG, "System now ready");
9251        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9252            SystemClock.uptimeMillis());
9253
9254        synchronized(this) {
9255            // Make sure we have no pre-ready processes sitting around.
9256
9257            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9258                ResolveInfo ri = mContext.getPackageManager()
9259                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9260                                STOCK_PM_FLAGS);
9261                CharSequence errorMsg = null;
9262                if (ri != null) {
9263                    ActivityInfo ai = ri.activityInfo;
9264                    ApplicationInfo app = ai.applicationInfo;
9265                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9266                        mTopAction = Intent.ACTION_FACTORY_TEST;
9267                        mTopData = null;
9268                        mTopComponent = new ComponentName(app.packageName,
9269                                ai.name);
9270                    } else {
9271                        errorMsg = mContext.getResources().getText(
9272                                com.android.internal.R.string.factorytest_not_system);
9273                    }
9274                } else {
9275                    errorMsg = mContext.getResources().getText(
9276                            com.android.internal.R.string.factorytest_no_action);
9277                }
9278                if (errorMsg != null) {
9279                    mTopAction = null;
9280                    mTopData = null;
9281                    mTopComponent = null;
9282                    Message msg = Message.obtain();
9283                    msg.what = SHOW_FACTORY_ERROR_MSG;
9284                    msg.getData().putCharSequence("msg", errorMsg);
9285                    mHandler.sendMessage(msg);
9286                }
9287            }
9288        }
9289
9290        retrieveSettings();
9291
9292        synchronized (this) {
9293            readGrantedUriPermissionsLocked();
9294        }
9295
9296        if (goingCallback != null) goingCallback.run();
9297
9298        synchronized (this) {
9299            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9300                try {
9301                    List apps = AppGlobals.getPackageManager().
9302                        getPersistentApplications(STOCK_PM_FLAGS);
9303                    if (apps != null) {
9304                        int N = apps.size();
9305                        int i;
9306                        for (i=0; i<N; i++) {
9307                            ApplicationInfo info
9308                                = (ApplicationInfo)apps.get(i);
9309                            if (info != null &&
9310                                    !info.packageName.equals("android")) {
9311                                addAppLocked(info, false);
9312                            }
9313                        }
9314                    }
9315                } catch (RemoteException ex) {
9316                    // pm is in same process, this will never happen.
9317                }
9318            }
9319
9320            // Start up initial activity.
9321            mBooting = true;
9322
9323            try {
9324                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9325                    Message msg = Message.obtain();
9326                    msg.what = SHOW_UID_ERROR_MSG;
9327                    mHandler.sendMessage(msg);
9328                }
9329            } catch (RemoteException e) {
9330            }
9331
9332            long ident = Binder.clearCallingIdentity();
9333            try {
9334                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9335                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9336                        | Intent.FLAG_RECEIVER_FOREGROUND);
9337                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9338                broadcastIntentLocked(null, null, intent,
9339                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9340                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9341                intent = new Intent(Intent.ACTION_USER_STARTING);
9342                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9343                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9344                broadcastIntentLocked(null, null, intent,
9345                        null, new IIntentReceiver.Stub() {
9346                            @Override
9347                            public void performReceive(Intent intent, int resultCode, String data,
9348                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9349                                    throws RemoteException {
9350                            }
9351                        }, 0, null, null,
9352                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9353                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9354            } finally {
9355                Binder.restoreCallingIdentity(ident);
9356            }
9357            mStackSupervisor.resumeTopActivitiesLocked();
9358            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9359        }
9360    }
9361
9362    private boolean makeAppCrashingLocked(ProcessRecord app,
9363            String shortMsg, String longMsg, String stackTrace) {
9364        app.crashing = true;
9365        app.crashingReport = generateProcessError(app,
9366                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9367        startAppProblemLocked(app);
9368        app.stopFreezingAllLocked();
9369        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9370    }
9371
9372    private void makeAppNotRespondingLocked(ProcessRecord app,
9373            String activity, String shortMsg, String longMsg) {
9374        app.notResponding = true;
9375        app.notRespondingReport = generateProcessError(app,
9376                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9377                activity, shortMsg, longMsg, null);
9378        startAppProblemLocked(app);
9379        app.stopFreezingAllLocked();
9380    }
9381
9382    /**
9383     * Generate a process error record, suitable for attachment to a ProcessRecord.
9384     *
9385     * @param app The ProcessRecord in which the error occurred.
9386     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9387     *                      ActivityManager.AppErrorStateInfo
9388     * @param activity The activity associated with the crash, if known.
9389     * @param shortMsg Short message describing the crash.
9390     * @param longMsg Long message describing the crash.
9391     * @param stackTrace Full crash stack trace, may be null.
9392     *
9393     * @return Returns a fully-formed AppErrorStateInfo record.
9394     */
9395    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9396            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9397        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9398
9399        report.condition = condition;
9400        report.processName = app.processName;
9401        report.pid = app.pid;
9402        report.uid = app.info.uid;
9403        report.tag = activity;
9404        report.shortMsg = shortMsg;
9405        report.longMsg = longMsg;
9406        report.stackTrace = stackTrace;
9407
9408        return report;
9409    }
9410
9411    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9412        synchronized (this) {
9413            app.crashing = false;
9414            app.crashingReport = null;
9415            app.notResponding = false;
9416            app.notRespondingReport = null;
9417            if (app.anrDialog == fromDialog) {
9418                app.anrDialog = null;
9419            }
9420            if (app.waitDialog == fromDialog) {
9421                app.waitDialog = null;
9422            }
9423            if (app.pid > 0 && app.pid != MY_PID) {
9424                handleAppCrashLocked(app, null, null, null);
9425                killUnneededProcessLocked(app, "user request after error");
9426            }
9427        }
9428    }
9429
9430    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9431            String stackTrace) {
9432        long now = SystemClock.uptimeMillis();
9433
9434        Long crashTime;
9435        if (!app.isolated) {
9436            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9437        } else {
9438            crashTime = null;
9439        }
9440        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9441            // This process loses!
9442            Slog.w(TAG, "Process " + app.info.processName
9443                    + " has crashed too many times: killing!");
9444            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9445                    app.userId, app.info.processName, app.uid);
9446            mStackSupervisor.handleAppCrashLocked(app);
9447            if (!app.persistent) {
9448                // We don't want to start this process again until the user
9449                // explicitly does so...  but for persistent process, we really
9450                // need to keep it running.  If a persistent process is actually
9451                // repeatedly crashing, then badness for everyone.
9452                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9453                        app.info.processName);
9454                if (!app.isolated) {
9455                    // XXX We don't have a way to mark isolated processes
9456                    // as bad, since they don't have a peristent identity.
9457                    mBadProcesses.put(app.info.processName, app.uid,
9458                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9459                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9460                }
9461                app.bad = true;
9462                app.removed = true;
9463                // Don't let services in this process be restarted and potentially
9464                // annoy the user repeatedly.  Unless it is persistent, since those
9465                // processes run critical code.
9466                removeProcessLocked(app, false, false, "crash");
9467                mStackSupervisor.resumeTopActivitiesLocked();
9468                return false;
9469            }
9470            mStackSupervisor.resumeTopActivitiesLocked();
9471        } else {
9472            mStackSupervisor.finishTopRunningActivityLocked(app);
9473        }
9474
9475        // Bump up the crash count of any services currently running in the proc.
9476        for (int i=app.services.size()-1; i>=0; i--) {
9477            // Any services running in the application need to be placed
9478            // back in the pending list.
9479            ServiceRecord sr = app.services.valueAt(i);
9480            sr.crashCount++;
9481        }
9482
9483        // If the crashing process is what we consider to be the "home process" and it has been
9484        // replaced by a third-party app, clear the package preferred activities from packages
9485        // with a home activity running in the process to prevent a repeatedly crashing app
9486        // from blocking the user to manually clear the list.
9487        final ArrayList<ActivityRecord> activities = app.activities;
9488        if (app == mHomeProcess && activities.size() > 0
9489                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9490            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9491                final ActivityRecord r = activities.get(activityNdx);
9492                if (r.isHomeActivity()) {
9493                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9494                    try {
9495                        ActivityThread.getPackageManager()
9496                                .clearPackagePreferredActivities(r.packageName);
9497                    } catch (RemoteException c) {
9498                        // pm is in same process, this will never happen.
9499                    }
9500                }
9501            }
9502        }
9503
9504        if (!app.isolated) {
9505            // XXX Can't keep track of crash times for isolated processes,
9506            // because they don't have a perisistent identity.
9507            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9508        }
9509
9510        return true;
9511    }
9512
9513    void startAppProblemLocked(ProcessRecord app) {
9514        if (app.userId == mCurrentUserId) {
9515            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9516                    mContext, app.info.packageName, app.info.flags);
9517        } else {
9518            // If this app is not running under the current user, then we
9519            // can't give it a report button because that would require
9520            // launching the report UI under a different user.
9521            app.errorReportReceiver = null;
9522        }
9523        skipCurrentReceiverLocked(app);
9524    }
9525
9526    void skipCurrentReceiverLocked(ProcessRecord app) {
9527        for (BroadcastQueue queue : mBroadcastQueues) {
9528            queue.skipCurrentReceiverLocked(app);
9529        }
9530    }
9531
9532    /**
9533     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9534     * The application process will exit immediately after this call returns.
9535     * @param app object of the crashing app, null for the system server
9536     * @param crashInfo describing the exception
9537     */
9538    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9539        ProcessRecord r = findAppProcess(app, "Crash");
9540        final String processName = app == null ? "system_server"
9541                : (r == null ? "unknown" : r.processName);
9542
9543        handleApplicationCrashInner("crash", r, processName, crashInfo);
9544    }
9545
9546    /* Native crash reporting uses this inner version because it needs to be somewhat
9547     * decoupled from the AM-managed cleanup lifecycle
9548     */
9549    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9550            ApplicationErrorReport.CrashInfo crashInfo) {
9551        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9552                UserHandle.getUserId(Binder.getCallingUid()), processName,
9553                r == null ? -1 : r.info.flags,
9554                crashInfo.exceptionClassName,
9555                crashInfo.exceptionMessage,
9556                crashInfo.throwFileName,
9557                crashInfo.throwLineNumber);
9558
9559        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9560
9561        crashApplication(r, crashInfo);
9562    }
9563
9564    public void handleApplicationStrictModeViolation(
9565            IBinder app,
9566            int violationMask,
9567            StrictMode.ViolationInfo info) {
9568        ProcessRecord r = findAppProcess(app, "StrictMode");
9569        if (r == null) {
9570            return;
9571        }
9572
9573        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9574            Integer stackFingerprint = info.hashCode();
9575            boolean logIt = true;
9576            synchronized (mAlreadyLoggedViolatedStacks) {
9577                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9578                    logIt = false;
9579                    // TODO: sub-sample into EventLog for these, with
9580                    // the info.durationMillis?  Then we'd get
9581                    // the relative pain numbers, without logging all
9582                    // the stack traces repeatedly.  We'd want to do
9583                    // likewise in the client code, which also does
9584                    // dup suppression, before the Binder call.
9585                } else {
9586                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9587                        mAlreadyLoggedViolatedStacks.clear();
9588                    }
9589                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9590                }
9591            }
9592            if (logIt) {
9593                logStrictModeViolationToDropBox(r, info);
9594            }
9595        }
9596
9597        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9598            AppErrorResult result = new AppErrorResult();
9599            synchronized (this) {
9600                final long origId = Binder.clearCallingIdentity();
9601
9602                Message msg = Message.obtain();
9603                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9604                HashMap<String, Object> data = new HashMap<String, Object>();
9605                data.put("result", result);
9606                data.put("app", r);
9607                data.put("violationMask", violationMask);
9608                data.put("info", info);
9609                msg.obj = data;
9610                mHandler.sendMessage(msg);
9611
9612                Binder.restoreCallingIdentity(origId);
9613            }
9614            int res = result.get();
9615            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9616        }
9617    }
9618
9619    // Depending on the policy in effect, there could be a bunch of
9620    // these in quick succession so we try to batch these together to
9621    // minimize disk writes, number of dropbox entries, and maximize
9622    // compression, by having more fewer, larger records.
9623    private void logStrictModeViolationToDropBox(
9624            ProcessRecord process,
9625            StrictMode.ViolationInfo info) {
9626        if (info == null) {
9627            return;
9628        }
9629        final boolean isSystemApp = process == null ||
9630                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9631                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9632        final String processName = process == null ? "unknown" : process.processName;
9633        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9634        final DropBoxManager dbox = (DropBoxManager)
9635                mContext.getSystemService(Context.DROPBOX_SERVICE);
9636
9637        // Exit early if the dropbox isn't configured to accept this report type.
9638        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9639
9640        boolean bufferWasEmpty;
9641        boolean needsFlush;
9642        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9643        synchronized (sb) {
9644            bufferWasEmpty = sb.length() == 0;
9645            appendDropBoxProcessHeaders(process, processName, sb);
9646            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9647            sb.append("System-App: ").append(isSystemApp).append("\n");
9648            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9649            if (info.violationNumThisLoop != 0) {
9650                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9651            }
9652            if (info.numAnimationsRunning != 0) {
9653                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9654            }
9655            if (info.broadcastIntentAction != null) {
9656                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9657            }
9658            if (info.durationMillis != -1) {
9659                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9660            }
9661            if (info.numInstances != -1) {
9662                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9663            }
9664            if (info.tags != null) {
9665                for (String tag : info.tags) {
9666                    sb.append("Span-Tag: ").append(tag).append("\n");
9667                }
9668            }
9669            sb.append("\n");
9670            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9671                sb.append(info.crashInfo.stackTrace);
9672            }
9673            sb.append("\n");
9674
9675            // Only buffer up to ~64k.  Various logging bits truncate
9676            // things at 128k.
9677            needsFlush = (sb.length() > 64 * 1024);
9678        }
9679
9680        // Flush immediately if the buffer's grown too large, or this
9681        // is a non-system app.  Non-system apps are isolated with a
9682        // different tag & policy and not batched.
9683        //
9684        // Batching is useful during internal testing with
9685        // StrictMode settings turned up high.  Without batching,
9686        // thousands of separate files could be created on boot.
9687        if (!isSystemApp || needsFlush) {
9688            new Thread("Error dump: " + dropboxTag) {
9689                @Override
9690                public void run() {
9691                    String report;
9692                    synchronized (sb) {
9693                        report = sb.toString();
9694                        sb.delete(0, sb.length());
9695                        sb.trimToSize();
9696                    }
9697                    if (report.length() != 0) {
9698                        dbox.addText(dropboxTag, report);
9699                    }
9700                }
9701            }.start();
9702            return;
9703        }
9704
9705        // System app batching:
9706        if (!bufferWasEmpty) {
9707            // An existing dropbox-writing thread is outstanding, so
9708            // we don't need to start it up.  The existing thread will
9709            // catch the buffer appends we just did.
9710            return;
9711        }
9712
9713        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9714        // (After this point, we shouldn't access AMS internal data structures.)
9715        new Thread("Error dump: " + dropboxTag) {
9716            @Override
9717            public void run() {
9718                // 5 second sleep to let stacks arrive and be batched together
9719                try {
9720                    Thread.sleep(5000);  // 5 seconds
9721                } catch (InterruptedException e) {}
9722
9723                String errorReport;
9724                synchronized (mStrictModeBuffer) {
9725                    errorReport = mStrictModeBuffer.toString();
9726                    if (errorReport.length() == 0) {
9727                        return;
9728                    }
9729                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9730                    mStrictModeBuffer.trimToSize();
9731                }
9732                dbox.addText(dropboxTag, errorReport);
9733            }
9734        }.start();
9735    }
9736
9737    /**
9738     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9739     * @param app object of the crashing app, null for the system server
9740     * @param tag reported by the caller
9741     * @param crashInfo describing the context of the error
9742     * @return true if the process should exit immediately (WTF is fatal)
9743     */
9744    public boolean handleApplicationWtf(IBinder app, String tag,
9745            ApplicationErrorReport.CrashInfo crashInfo) {
9746        ProcessRecord r = findAppProcess(app, "WTF");
9747        final String processName = app == null ? "system_server"
9748                : (r == null ? "unknown" : r.processName);
9749
9750        EventLog.writeEvent(EventLogTags.AM_WTF,
9751                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9752                processName,
9753                r == null ? -1 : r.info.flags,
9754                tag, crashInfo.exceptionMessage);
9755
9756        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9757
9758        if (r != null && r.pid != Process.myPid() &&
9759                Settings.Global.getInt(mContext.getContentResolver(),
9760                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9761            crashApplication(r, crashInfo);
9762            return true;
9763        } else {
9764            return false;
9765        }
9766    }
9767
9768    /**
9769     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9770     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9771     */
9772    private ProcessRecord findAppProcess(IBinder app, String reason) {
9773        if (app == null) {
9774            return null;
9775        }
9776
9777        synchronized (this) {
9778            final int NP = mProcessNames.getMap().size();
9779            for (int ip=0; ip<NP; ip++) {
9780                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9781                final int NA = apps.size();
9782                for (int ia=0; ia<NA; ia++) {
9783                    ProcessRecord p = apps.valueAt(ia);
9784                    if (p.thread != null && p.thread.asBinder() == app) {
9785                        return p;
9786                    }
9787                }
9788            }
9789
9790            Slog.w(TAG, "Can't find mystery application for " + reason
9791                    + " from pid=" + Binder.getCallingPid()
9792                    + " uid=" + Binder.getCallingUid() + ": " + app);
9793            return null;
9794        }
9795    }
9796
9797    /**
9798     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9799     * to append various headers to the dropbox log text.
9800     */
9801    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9802            StringBuilder sb) {
9803        // Watchdog thread ends up invoking this function (with
9804        // a null ProcessRecord) to add the stack file to dropbox.
9805        // Do not acquire a lock on this (am) in such cases, as it
9806        // could cause a potential deadlock, if and when watchdog
9807        // is invoked due to unavailability of lock on am and it
9808        // would prevent watchdog from killing system_server.
9809        if (process == null) {
9810            sb.append("Process: ").append(processName).append("\n");
9811            return;
9812        }
9813        // Note: ProcessRecord 'process' is guarded by the service
9814        // instance.  (notably process.pkgList, which could otherwise change
9815        // concurrently during execution of this method)
9816        synchronized (this) {
9817            sb.append("Process: ").append(processName).append("\n");
9818            int flags = process.info.flags;
9819            IPackageManager pm = AppGlobals.getPackageManager();
9820            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9821            for (int ip=0; ip<process.pkgList.size(); ip++) {
9822                String pkg = process.pkgList.keyAt(ip);
9823                sb.append("Package: ").append(pkg);
9824                try {
9825                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9826                    if (pi != null) {
9827                        sb.append(" v").append(pi.versionCode);
9828                        if (pi.versionName != null) {
9829                            sb.append(" (").append(pi.versionName).append(")");
9830                        }
9831                    }
9832                } catch (RemoteException e) {
9833                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9834                }
9835                sb.append("\n");
9836            }
9837        }
9838    }
9839
9840    private static String processClass(ProcessRecord process) {
9841        if (process == null || process.pid == MY_PID) {
9842            return "system_server";
9843        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9844            return "system_app";
9845        } else {
9846            return "data_app";
9847        }
9848    }
9849
9850    /**
9851     * Write a description of an error (crash, WTF, ANR) to the drop box.
9852     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9853     * @param process which caused the error, null means the system server
9854     * @param activity which triggered the error, null if unknown
9855     * @param parent activity related to the error, null if unknown
9856     * @param subject line related to the error, null if absent
9857     * @param report in long form describing the error, null if absent
9858     * @param logFile to include in the report, null if none
9859     * @param crashInfo giving an application stack trace, null if absent
9860     */
9861    public void addErrorToDropBox(String eventType,
9862            ProcessRecord process, String processName, ActivityRecord activity,
9863            ActivityRecord parent, String subject,
9864            final String report, final File logFile,
9865            final ApplicationErrorReport.CrashInfo crashInfo) {
9866        // NOTE -- this must never acquire the ActivityManagerService lock,
9867        // otherwise the watchdog may be prevented from resetting the system.
9868
9869        final String dropboxTag = processClass(process) + "_" + eventType;
9870        final DropBoxManager dbox = (DropBoxManager)
9871                mContext.getSystemService(Context.DROPBOX_SERVICE);
9872
9873        // Exit early if the dropbox isn't configured to accept this report type.
9874        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9875
9876        final StringBuilder sb = new StringBuilder(1024);
9877        appendDropBoxProcessHeaders(process, processName, sb);
9878        if (activity != null) {
9879            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9880        }
9881        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9882            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9883        }
9884        if (parent != null && parent != activity) {
9885            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9886        }
9887        if (subject != null) {
9888            sb.append("Subject: ").append(subject).append("\n");
9889        }
9890        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9891        if (Debug.isDebuggerConnected()) {
9892            sb.append("Debugger: Connected\n");
9893        }
9894        sb.append("\n");
9895
9896        // Do the rest in a worker thread to avoid blocking the caller on I/O
9897        // (After this point, we shouldn't access AMS internal data structures.)
9898        Thread worker = new Thread("Error dump: " + dropboxTag) {
9899            @Override
9900            public void run() {
9901                if (report != null) {
9902                    sb.append(report);
9903                }
9904                if (logFile != null) {
9905                    try {
9906                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9907                                    "\n\n[[TRUNCATED]]"));
9908                    } catch (IOException e) {
9909                        Slog.e(TAG, "Error reading " + logFile, e);
9910                    }
9911                }
9912                if (crashInfo != null && crashInfo.stackTrace != null) {
9913                    sb.append(crashInfo.stackTrace);
9914                }
9915
9916                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9917                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9918                if (lines > 0) {
9919                    sb.append("\n");
9920
9921                    // Merge several logcat streams, and take the last N lines
9922                    InputStreamReader input = null;
9923                    try {
9924                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9925                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9926                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9927
9928                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9929                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9930                        input = new InputStreamReader(logcat.getInputStream());
9931
9932                        int num;
9933                        char[] buf = new char[8192];
9934                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9935                    } catch (IOException e) {
9936                        Slog.e(TAG, "Error running logcat", e);
9937                    } finally {
9938                        if (input != null) try { input.close(); } catch (IOException e) {}
9939                    }
9940                }
9941
9942                dbox.addText(dropboxTag, sb.toString());
9943            }
9944        };
9945
9946        if (process == null) {
9947            // If process is null, we are being called from some internal code
9948            // and may be about to die -- run this synchronously.
9949            worker.run();
9950        } else {
9951            worker.start();
9952        }
9953    }
9954
9955    /**
9956     * Bring up the "unexpected error" dialog box for a crashing app.
9957     * Deal with edge cases (intercepts from instrumented applications,
9958     * ActivityController, error intent receivers, that sort of thing).
9959     * @param r the application crashing
9960     * @param crashInfo describing the failure
9961     */
9962    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9963        long timeMillis = System.currentTimeMillis();
9964        String shortMsg = crashInfo.exceptionClassName;
9965        String longMsg = crashInfo.exceptionMessage;
9966        String stackTrace = crashInfo.stackTrace;
9967        if (shortMsg != null && longMsg != null) {
9968            longMsg = shortMsg + ": " + longMsg;
9969        } else if (shortMsg != null) {
9970            longMsg = shortMsg;
9971        }
9972
9973        AppErrorResult result = new AppErrorResult();
9974        synchronized (this) {
9975            if (mController != null) {
9976                try {
9977                    String name = r != null ? r.processName : null;
9978                    int pid = r != null ? r.pid : Binder.getCallingPid();
9979                    if (!mController.appCrashed(name, pid,
9980                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9981                        Slog.w(TAG, "Force-killing crashed app " + name
9982                                + " at watcher's request");
9983                        Process.killProcess(pid);
9984                        return;
9985                    }
9986                } catch (RemoteException e) {
9987                    mController = null;
9988                    Watchdog.getInstance().setActivityController(null);
9989                }
9990            }
9991
9992            final long origId = Binder.clearCallingIdentity();
9993
9994            // If this process is running instrumentation, finish it.
9995            if (r != null && r.instrumentationClass != null) {
9996                Slog.w(TAG, "Error in app " + r.processName
9997                      + " running instrumentation " + r.instrumentationClass + ":");
9998                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
9999                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10000                Bundle info = new Bundle();
10001                info.putString("shortMsg", shortMsg);
10002                info.putString("longMsg", longMsg);
10003                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10004                Binder.restoreCallingIdentity(origId);
10005                return;
10006            }
10007
10008            // If we can't identify the process or it's already exceeded its crash quota,
10009            // quit right away without showing a crash dialog.
10010            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10011                Binder.restoreCallingIdentity(origId);
10012                return;
10013            }
10014
10015            Message msg = Message.obtain();
10016            msg.what = SHOW_ERROR_MSG;
10017            HashMap data = new HashMap();
10018            data.put("result", result);
10019            data.put("app", r);
10020            msg.obj = data;
10021            mHandler.sendMessage(msg);
10022
10023            Binder.restoreCallingIdentity(origId);
10024        }
10025
10026        int res = result.get();
10027
10028        Intent appErrorIntent = null;
10029        synchronized (this) {
10030            if (r != null && !r.isolated) {
10031                // XXX Can't keep track of crash time for isolated processes,
10032                // since they don't have a persistent identity.
10033                mProcessCrashTimes.put(r.info.processName, r.uid,
10034                        SystemClock.uptimeMillis());
10035            }
10036            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10037                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10038            }
10039        }
10040
10041        if (appErrorIntent != null) {
10042            try {
10043                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10044            } catch (ActivityNotFoundException e) {
10045                Slog.w(TAG, "bug report receiver dissappeared", e);
10046            }
10047        }
10048    }
10049
10050    Intent createAppErrorIntentLocked(ProcessRecord r,
10051            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10052        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10053        if (report == null) {
10054            return null;
10055        }
10056        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10057        result.setComponent(r.errorReportReceiver);
10058        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10059        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10060        return result;
10061    }
10062
10063    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10064            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10065        if (r.errorReportReceiver == null) {
10066            return null;
10067        }
10068
10069        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10070            return null;
10071        }
10072
10073        ApplicationErrorReport report = new ApplicationErrorReport();
10074        report.packageName = r.info.packageName;
10075        report.installerPackageName = r.errorReportReceiver.getPackageName();
10076        report.processName = r.processName;
10077        report.time = timeMillis;
10078        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10079
10080        if (r.crashing || r.forceCrashReport) {
10081            report.type = ApplicationErrorReport.TYPE_CRASH;
10082            report.crashInfo = crashInfo;
10083        } else if (r.notResponding) {
10084            report.type = ApplicationErrorReport.TYPE_ANR;
10085            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10086
10087            report.anrInfo.activity = r.notRespondingReport.tag;
10088            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10089            report.anrInfo.info = r.notRespondingReport.longMsg;
10090        }
10091
10092        return report;
10093    }
10094
10095    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10096        enforceNotIsolatedCaller("getProcessesInErrorState");
10097        // assume our apps are happy - lazy create the list
10098        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10099
10100        final boolean allUsers = ActivityManager.checkUidPermission(
10101                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10102                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10103        int userId = UserHandle.getUserId(Binder.getCallingUid());
10104
10105        synchronized (this) {
10106
10107            // iterate across all processes
10108            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10109                ProcessRecord app = mLruProcesses.get(i);
10110                if (!allUsers && app.userId != userId) {
10111                    continue;
10112                }
10113                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10114                    // This one's in trouble, so we'll generate a report for it
10115                    // crashes are higher priority (in case there's a crash *and* an anr)
10116                    ActivityManager.ProcessErrorStateInfo report = null;
10117                    if (app.crashing) {
10118                        report = app.crashingReport;
10119                    } else if (app.notResponding) {
10120                        report = app.notRespondingReport;
10121                    }
10122
10123                    if (report != null) {
10124                        if (errList == null) {
10125                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10126                        }
10127                        errList.add(report);
10128                    } else {
10129                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10130                                " crashing = " + app.crashing +
10131                                " notResponding = " + app.notResponding);
10132                    }
10133                }
10134            }
10135        }
10136
10137        return errList;
10138    }
10139
10140    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10141        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10142            if (currApp != null) {
10143                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10144            }
10145            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10146        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10147            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10148        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10149            if (currApp != null) {
10150                currApp.lru = 0;
10151            }
10152            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10153        } else if (adj >= ProcessList.SERVICE_ADJ) {
10154            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10155        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10156            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10157        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10158            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10159        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10160            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10161        } else {
10162            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10163        }
10164    }
10165
10166    private void fillInProcMemInfo(ProcessRecord app,
10167            ActivityManager.RunningAppProcessInfo outInfo) {
10168        outInfo.pid = app.pid;
10169        outInfo.uid = app.info.uid;
10170        if (mHeavyWeightProcess == app) {
10171            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10172        }
10173        if (app.persistent) {
10174            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10175        }
10176        if (app.activities.size() > 0) {
10177            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10178        }
10179        outInfo.lastTrimLevel = app.trimMemoryLevel;
10180        int adj = app.curAdj;
10181        outInfo.importance = oomAdjToImportance(adj, outInfo);
10182        outInfo.importanceReasonCode = app.adjTypeCode;
10183    }
10184
10185    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10186        enforceNotIsolatedCaller("getRunningAppProcesses");
10187        // Lazy instantiation of list
10188        List<ActivityManager.RunningAppProcessInfo> runList = null;
10189        final boolean allUsers = ActivityManager.checkUidPermission(
10190                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10191                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10192        int userId = UserHandle.getUserId(Binder.getCallingUid());
10193        synchronized (this) {
10194            // Iterate across all processes
10195            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10196                ProcessRecord app = mLruProcesses.get(i);
10197                if (!allUsers && app.userId != userId) {
10198                    continue;
10199                }
10200                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10201                    // Generate process state info for running application
10202                    ActivityManager.RunningAppProcessInfo currApp =
10203                        new ActivityManager.RunningAppProcessInfo(app.processName,
10204                                app.pid, app.getPackageList());
10205                    fillInProcMemInfo(app, currApp);
10206                    if (app.adjSource instanceof ProcessRecord) {
10207                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10208                        currApp.importanceReasonImportance = oomAdjToImportance(
10209                                app.adjSourceOom, null);
10210                    } else if (app.adjSource instanceof ActivityRecord) {
10211                        ActivityRecord r = (ActivityRecord)app.adjSource;
10212                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10213                    }
10214                    if (app.adjTarget instanceof ComponentName) {
10215                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10216                    }
10217                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10218                    //        + " lru=" + currApp.lru);
10219                    if (runList == null) {
10220                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10221                    }
10222                    runList.add(currApp);
10223                }
10224            }
10225        }
10226        return runList;
10227    }
10228
10229    public List<ApplicationInfo> getRunningExternalApplications() {
10230        enforceNotIsolatedCaller("getRunningExternalApplications");
10231        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10232        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10233        if (runningApps != null && runningApps.size() > 0) {
10234            Set<String> extList = new HashSet<String>();
10235            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10236                if (app.pkgList != null) {
10237                    for (String pkg : app.pkgList) {
10238                        extList.add(pkg);
10239                    }
10240                }
10241            }
10242            IPackageManager pm = AppGlobals.getPackageManager();
10243            for (String pkg : extList) {
10244                try {
10245                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10246                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10247                        retList.add(info);
10248                    }
10249                } catch (RemoteException e) {
10250                }
10251            }
10252        }
10253        return retList;
10254    }
10255
10256    @Override
10257    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10258        enforceNotIsolatedCaller("getMyMemoryState");
10259        synchronized (this) {
10260            ProcessRecord proc;
10261            synchronized (mPidsSelfLocked) {
10262                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10263            }
10264            fillInProcMemInfo(proc, outInfo);
10265        }
10266    }
10267
10268    @Override
10269    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10270        if (checkCallingPermission(android.Manifest.permission.DUMP)
10271                != PackageManager.PERMISSION_GRANTED) {
10272            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10273                    + Binder.getCallingPid()
10274                    + ", uid=" + Binder.getCallingUid()
10275                    + " without permission "
10276                    + android.Manifest.permission.DUMP);
10277            return;
10278        }
10279
10280        boolean dumpAll = false;
10281        boolean dumpClient = false;
10282        String dumpPackage = null;
10283
10284        int opti = 0;
10285        while (opti < args.length) {
10286            String opt = args[opti];
10287            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10288                break;
10289            }
10290            opti++;
10291            if ("-a".equals(opt)) {
10292                dumpAll = true;
10293            } else if ("-c".equals(opt)) {
10294                dumpClient = true;
10295            } else if ("-h".equals(opt)) {
10296                pw.println("Activity manager dump options:");
10297                pw.println("  [-a] [-c] [-h] [cmd] ...");
10298                pw.println("  cmd may be one of:");
10299                pw.println("    a[ctivities]: activity stack state");
10300                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10301                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10302                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10303                pw.println("    o[om]: out of memory management");
10304                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10305                pw.println("    provider [COMP_SPEC]: provider client-side state");
10306                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10307                pw.println("    service [COMP_SPEC]: service client-side state");
10308                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10309                pw.println("    all: dump all activities");
10310                pw.println("    top: dump the top activity");
10311                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10312                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10313                pw.println("    a partial substring in a component name, a");
10314                pw.println("    hex object identifier.");
10315                pw.println("  -a: include all available server state.");
10316                pw.println("  -c: include client state.");
10317                return;
10318            } else {
10319                pw.println("Unknown argument: " + opt + "; use -h for help");
10320            }
10321        }
10322
10323        long origId = Binder.clearCallingIdentity();
10324        boolean more = false;
10325        // Is the caller requesting to dump a particular piece of data?
10326        if (opti < args.length) {
10327            String cmd = args[opti];
10328            opti++;
10329            if ("activities".equals(cmd) || "a".equals(cmd)) {
10330                synchronized (this) {
10331                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10332                }
10333            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10334                String[] newArgs;
10335                String name;
10336                if (opti >= args.length) {
10337                    name = null;
10338                    newArgs = EMPTY_STRING_ARRAY;
10339                } else {
10340                    name = args[opti];
10341                    opti++;
10342                    newArgs = new String[args.length - opti];
10343                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10344                            args.length - opti);
10345                }
10346                synchronized (this) {
10347                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10348                }
10349            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10350                String[] newArgs;
10351                String name;
10352                if (opti >= args.length) {
10353                    name = null;
10354                    newArgs = EMPTY_STRING_ARRAY;
10355                } else {
10356                    name = args[opti];
10357                    opti++;
10358                    newArgs = new String[args.length - opti];
10359                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10360                            args.length - opti);
10361                }
10362                synchronized (this) {
10363                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10364                }
10365            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10366                String[] newArgs;
10367                String name;
10368                if (opti >= args.length) {
10369                    name = null;
10370                    newArgs = EMPTY_STRING_ARRAY;
10371                } else {
10372                    name = args[opti];
10373                    opti++;
10374                    newArgs = new String[args.length - opti];
10375                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10376                            args.length - opti);
10377                }
10378                synchronized (this) {
10379                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10380                }
10381            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10382                synchronized (this) {
10383                    dumpOomLocked(fd, pw, args, opti, true);
10384                }
10385            } else if ("provider".equals(cmd)) {
10386                String[] newArgs;
10387                String name;
10388                if (opti >= args.length) {
10389                    name = null;
10390                    newArgs = EMPTY_STRING_ARRAY;
10391                } else {
10392                    name = args[opti];
10393                    opti++;
10394                    newArgs = new String[args.length - opti];
10395                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10396                }
10397                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10398                    pw.println("No providers match: " + name);
10399                    pw.println("Use -h for help.");
10400                }
10401            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10402                synchronized (this) {
10403                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10404                }
10405            } else if ("service".equals(cmd)) {
10406                String[] newArgs;
10407                String name;
10408                if (opti >= args.length) {
10409                    name = null;
10410                    newArgs = EMPTY_STRING_ARRAY;
10411                } else {
10412                    name = args[opti];
10413                    opti++;
10414                    newArgs = new String[args.length - opti];
10415                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10416                            args.length - opti);
10417                }
10418                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10419                    pw.println("No services match: " + name);
10420                    pw.println("Use -h for help.");
10421                }
10422            } else if ("package".equals(cmd)) {
10423                String[] newArgs;
10424                if (opti >= args.length) {
10425                    pw.println("package: no package name specified");
10426                    pw.println("Use -h for help.");
10427                } else {
10428                    dumpPackage = args[opti];
10429                    opti++;
10430                    newArgs = new String[args.length - opti];
10431                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10432                            args.length - opti);
10433                    args = newArgs;
10434                    opti = 0;
10435                    more = true;
10436                }
10437            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10438                synchronized (this) {
10439                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10440                }
10441            } else {
10442                // Dumping a single activity?
10443                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10444                    pw.println("Bad activity command, or no activities match: " + cmd);
10445                    pw.println("Use -h for help.");
10446                }
10447            }
10448            if (!more) {
10449                Binder.restoreCallingIdentity(origId);
10450                return;
10451            }
10452        }
10453
10454        // No piece of data specified, dump everything.
10455        synchronized (this) {
10456            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10457            pw.println();
10458            if (dumpAll) {
10459                pw.println("-------------------------------------------------------------------------------");
10460            }
10461            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10462            pw.println();
10463            if (dumpAll) {
10464                pw.println("-------------------------------------------------------------------------------");
10465            }
10466            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10467            pw.println();
10468            if (dumpAll) {
10469                pw.println("-------------------------------------------------------------------------------");
10470            }
10471            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10472            pw.println();
10473            if (dumpAll) {
10474                pw.println("-------------------------------------------------------------------------------");
10475            }
10476            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10477            pw.println();
10478            if (dumpAll) {
10479                pw.println("-------------------------------------------------------------------------------");
10480            }
10481            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10482        }
10483        Binder.restoreCallingIdentity(origId);
10484    }
10485
10486    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10487            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10488        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10489
10490        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10491                dumpPackage);
10492        boolean needSep = printedAnything;
10493
10494        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10495                dumpPackage, needSep, "  mFocusedActivity: ");
10496        if (printed) {
10497            printedAnything = true;
10498            needSep = false;
10499        }
10500
10501        if (dumpPackage == null) {
10502            if (needSep) {
10503                pw.println();
10504            }
10505            needSep = true;
10506            printedAnything = true;
10507            mStackSupervisor.dump(pw, "  ");
10508        }
10509
10510        if (mRecentTasks.size() > 0) {
10511            boolean printedHeader = false;
10512
10513            final int N = mRecentTasks.size();
10514            for (int i=0; i<N; i++) {
10515                TaskRecord tr = mRecentTasks.get(i);
10516                if (dumpPackage != null) {
10517                    if (tr.realActivity == null ||
10518                            !dumpPackage.equals(tr.realActivity)) {
10519                        continue;
10520                    }
10521                }
10522                if (!printedHeader) {
10523                    if (needSep) {
10524                        pw.println();
10525                    }
10526                    pw.println("  Recent tasks:");
10527                    printedHeader = true;
10528                    printedAnything = true;
10529                }
10530                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10531                        pw.println(tr);
10532                if (dumpAll) {
10533                    mRecentTasks.get(i).dump(pw, "    ");
10534                }
10535            }
10536        }
10537
10538        if (!printedAnything) {
10539            pw.println("  (nothing)");
10540        }
10541    }
10542
10543    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10544            int opti, boolean dumpAll, String dumpPackage) {
10545        boolean needSep = false;
10546        boolean printedAnything = false;
10547        int numPers = 0;
10548
10549        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10550
10551        if (dumpAll) {
10552            final int NP = mProcessNames.getMap().size();
10553            for (int ip=0; ip<NP; ip++) {
10554                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10555                final int NA = procs.size();
10556                for (int ia=0; ia<NA; ia++) {
10557                    ProcessRecord r = procs.valueAt(ia);
10558                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10559                        continue;
10560                    }
10561                    if (!needSep) {
10562                        pw.println("  All known processes:");
10563                        needSep = true;
10564                        printedAnything = true;
10565                    }
10566                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10567                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10568                        pw.print(" "); pw.println(r);
10569                    r.dump(pw, "    ");
10570                    if (r.persistent) {
10571                        numPers++;
10572                    }
10573                }
10574            }
10575        }
10576
10577        if (mIsolatedProcesses.size() > 0) {
10578            boolean printed = false;
10579            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10580                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10581                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10582                    continue;
10583                }
10584                if (!printed) {
10585                    if (needSep) {
10586                        pw.println();
10587                    }
10588                    pw.println("  Isolated process list (sorted by uid):");
10589                    printedAnything = true;
10590                    printed = true;
10591                    needSep = true;
10592                }
10593                pw.println(String.format("%sIsolated #%2d: %s",
10594                        "    ", i, r.toString()));
10595            }
10596        }
10597
10598        if (mLruProcesses.size() > 0) {
10599            if (needSep) {
10600                pw.println();
10601            }
10602            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10603                    pw.print(" total, non-act at ");
10604                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10605                    pw.print(", non-svc at ");
10606                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10607                    pw.println("):");
10608            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10609            needSep = true;
10610            printedAnything = true;
10611        }
10612
10613        if (dumpAll || dumpPackage != null) {
10614            synchronized (mPidsSelfLocked) {
10615                boolean printed = false;
10616                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10617                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10618                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10619                        continue;
10620                    }
10621                    if (!printed) {
10622                        if (needSep) pw.println();
10623                        needSep = true;
10624                        pw.println("  PID mappings:");
10625                        printed = true;
10626                        printedAnything = true;
10627                    }
10628                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10629                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10630                }
10631            }
10632        }
10633
10634        if (mForegroundProcesses.size() > 0) {
10635            synchronized (mPidsSelfLocked) {
10636                boolean printed = false;
10637                for (int i=0; i<mForegroundProcesses.size(); i++) {
10638                    ProcessRecord r = mPidsSelfLocked.get(
10639                            mForegroundProcesses.valueAt(i).pid);
10640                    if (dumpPackage != null && (r == null
10641                            || !r.pkgList.containsKey(dumpPackage))) {
10642                        continue;
10643                    }
10644                    if (!printed) {
10645                        if (needSep) pw.println();
10646                        needSep = true;
10647                        pw.println("  Foreground Processes:");
10648                        printed = true;
10649                        printedAnything = true;
10650                    }
10651                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10652                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10653                }
10654            }
10655        }
10656
10657        if (mPersistentStartingProcesses.size() > 0) {
10658            if (needSep) pw.println();
10659            needSep = true;
10660            printedAnything = true;
10661            pw.println("  Persisent processes that are starting:");
10662            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10663                    "Starting Norm", "Restarting PERS", dumpPackage);
10664        }
10665
10666        if (mRemovedProcesses.size() > 0) {
10667            if (needSep) pw.println();
10668            needSep = true;
10669            printedAnything = true;
10670            pw.println("  Processes that are being removed:");
10671            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10672                    "Removed Norm", "Removed PERS", dumpPackage);
10673        }
10674
10675        if (mProcessesOnHold.size() > 0) {
10676            if (needSep) pw.println();
10677            needSep = true;
10678            printedAnything = true;
10679            pw.println("  Processes that are on old until the system is ready:");
10680            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10681                    "OnHold Norm", "OnHold PERS", dumpPackage);
10682        }
10683
10684        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10685
10686        if (mProcessCrashTimes.getMap().size() > 0) {
10687            boolean printed = false;
10688            long now = SystemClock.uptimeMillis();
10689            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10690            final int NP = pmap.size();
10691            for (int ip=0; ip<NP; ip++) {
10692                String pname = pmap.keyAt(ip);
10693                SparseArray<Long> uids = pmap.valueAt(ip);
10694                final int N = uids.size();
10695                for (int i=0; i<N; i++) {
10696                    int puid = uids.keyAt(i);
10697                    ProcessRecord r = mProcessNames.get(pname, puid);
10698                    if (dumpPackage != null && (r == null
10699                            || !r.pkgList.containsKey(dumpPackage))) {
10700                        continue;
10701                    }
10702                    if (!printed) {
10703                        if (needSep) pw.println();
10704                        needSep = true;
10705                        pw.println("  Time since processes crashed:");
10706                        printed = true;
10707                        printedAnything = true;
10708                    }
10709                    pw.print("    Process "); pw.print(pname);
10710                            pw.print(" uid "); pw.print(puid);
10711                            pw.print(": last crashed ");
10712                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10713                            pw.println(" ago");
10714                }
10715            }
10716        }
10717
10718        if (mBadProcesses.getMap().size() > 0) {
10719            boolean printed = false;
10720            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10721            final int NP = pmap.size();
10722            for (int ip=0; ip<NP; ip++) {
10723                String pname = pmap.keyAt(ip);
10724                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10725                final int N = uids.size();
10726                for (int i=0; i<N; i++) {
10727                    int puid = uids.keyAt(i);
10728                    ProcessRecord r = mProcessNames.get(pname, puid);
10729                    if (dumpPackage != null && (r == null
10730                            || !r.pkgList.containsKey(dumpPackage))) {
10731                        continue;
10732                    }
10733                    if (!printed) {
10734                        if (needSep) pw.println();
10735                        needSep = true;
10736                        pw.println("  Bad processes:");
10737                        printedAnything = true;
10738                    }
10739                    BadProcessInfo info = uids.valueAt(i);
10740                    pw.print("    Bad process "); pw.print(pname);
10741                            pw.print(" uid "); pw.print(puid);
10742                            pw.print(": crashed at time "); pw.println(info.time);
10743                    if (info.shortMsg != null) {
10744                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10745                    }
10746                    if (info.longMsg != null) {
10747                        pw.print("      Long msg: "); pw.println(info.longMsg);
10748                    }
10749                    if (info.stack != null) {
10750                        pw.println("      Stack:");
10751                        int lastPos = 0;
10752                        for (int pos=0; pos<info.stack.length(); pos++) {
10753                            if (info.stack.charAt(pos) == '\n') {
10754                                pw.print("        ");
10755                                pw.write(info.stack, lastPos, pos-lastPos);
10756                                pw.println();
10757                                lastPos = pos+1;
10758                            }
10759                        }
10760                        if (lastPos < info.stack.length()) {
10761                            pw.print("        ");
10762                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10763                            pw.println();
10764                        }
10765                    }
10766                }
10767            }
10768        }
10769
10770        if (dumpPackage == null) {
10771            pw.println();
10772            needSep = false;
10773            pw.println("  mStartedUsers:");
10774            for (int i=0; i<mStartedUsers.size(); i++) {
10775                UserStartedState uss = mStartedUsers.valueAt(i);
10776                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10777                        pw.print(": "); uss.dump("", pw);
10778            }
10779            pw.print("  mStartedUserArray: [");
10780            for (int i=0; i<mStartedUserArray.length; i++) {
10781                if (i > 0) pw.print(", ");
10782                pw.print(mStartedUserArray[i]);
10783            }
10784            pw.println("]");
10785            pw.print("  mUserLru: [");
10786            for (int i=0; i<mUserLru.size(); i++) {
10787                if (i > 0) pw.print(", ");
10788                pw.print(mUserLru.get(i));
10789            }
10790            pw.println("]");
10791            if (dumpAll) {
10792                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10793            }
10794        }
10795        if (mHomeProcess != null && (dumpPackage == null
10796                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10797            if (needSep) {
10798                pw.println();
10799                needSep = false;
10800            }
10801            pw.println("  mHomeProcess: " + mHomeProcess);
10802        }
10803        if (mPreviousProcess != null && (dumpPackage == null
10804                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10805            if (needSep) {
10806                pw.println();
10807                needSep = false;
10808            }
10809            pw.println("  mPreviousProcess: " + mPreviousProcess);
10810        }
10811        if (dumpAll) {
10812            StringBuilder sb = new StringBuilder(128);
10813            sb.append("  mPreviousProcessVisibleTime: ");
10814            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10815            pw.println(sb);
10816        }
10817        if (mHeavyWeightProcess != null && (dumpPackage == null
10818                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10819            if (needSep) {
10820                pw.println();
10821                needSep = false;
10822            }
10823            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10824        }
10825        if (dumpPackage == null) {
10826            pw.println("  mConfiguration: " + mConfiguration);
10827        }
10828        if (dumpAll) {
10829            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10830            if (mCompatModePackages.getPackages().size() > 0) {
10831                boolean printed = false;
10832                for (Map.Entry<String, Integer> entry
10833                        : mCompatModePackages.getPackages().entrySet()) {
10834                    String pkg = entry.getKey();
10835                    int mode = entry.getValue();
10836                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10837                        continue;
10838                    }
10839                    if (!printed) {
10840                        pw.println("  mScreenCompatPackages:");
10841                        printed = true;
10842                    }
10843                    pw.print("    "); pw.print(pkg); pw.print(": ");
10844                            pw.print(mode); pw.println();
10845                }
10846            }
10847        }
10848        if (dumpPackage == null) {
10849            if (mSleeping || mWentToSleep || mLockScreenShown) {
10850                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10851                        + " mLockScreenShown " + mLockScreenShown);
10852            }
10853            if (mShuttingDown) {
10854                pw.println("  mShuttingDown=" + mShuttingDown);
10855            }
10856        }
10857        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10858                || mOrigWaitForDebugger) {
10859            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10860                    || dumpPackage.equals(mOrigDebugApp)) {
10861                if (needSep) {
10862                    pw.println();
10863                    needSep = false;
10864                }
10865                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10866                        + " mDebugTransient=" + mDebugTransient
10867                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10868            }
10869        }
10870        if (mOpenGlTraceApp != null) {
10871            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10872                if (needSep) {
10873                    pw.println();
10874                    needSep = false;
10875                }
10876                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10877            }
10878        }
10879        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10880                || mProfileFd != null) {
10881            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10882                if (needSep) {
10883                    pw.println();
10884                    needSep = false;
10885                }
10886                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10887                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10888                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10889                        + mAutoStopProfiler);
10890            }
10891        }
10892        if (dumpPackage == null) {
10893            if (mAlwaysFinishActivities || mController != null) {
10894                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10895                        + " mController=" + mController);
10896            }
10897            if (dumpAll) {
10898                pw.println("  Total persistent processes: " + numPers);
10899                pw.println("  mStartRunning=" + mStartRunning
10900                        + " mProcessesReady=" + mProcessesReady
10901                        + " mSystemReady=" + mSystemReady);
10902                pw.println("  mBooting=" + mBooting
10903                        + " mBooted=" + mBooted
10904                        + " mFactoryTest=" + mFactoryTest);
10905                pw.print("  mLastPowerCheckRealtime=");
10906                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10907                        pw.println("");
10908                pw.print("  mLastPowerCheckUptime=");
10909                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10910                        pw.println("");
10911                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10912                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10913                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10914                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10915                        + " (" + mLruProcesses.size() + " total)"
10916                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10917                        + " mNumServiceProcs=" + mNumServiceProcs
10918                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10919                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10920                        + " mLastMemoryLevel" + mLastMemoryLevel
10921                        + " mLastNumProcesses" + mLastNumProcesses);
10922                long now = SystemClock.uptimeMillis();
10923                pw.print("  mLastIdleTime=");
10924                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10925                        pw.print(" mLowRamSinceLastIdle=");
10926                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10927                        pw.println();
10928            }
10929        }
10930
10931        if (!printedAnything) {
10932            pw.println("  (nothing)");
10933        }
10934    }
10935
10936    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10937            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10938        if (mProcessesToGc.size() > 0) {
10939            boolean printed = false;
10940            long now = SystemClock.uptimeMillis();
10941            for (int i=0; i<mProcessesToGc.size(); i++) {
10942                ProcessRecord proc = mProcessesToGc.get(i);
10943                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10944                    continue;
10945                }
10946                if (!printed) {
10947                    if (needSep) pw.println();
10948                    needSep = true;
10949                    pw.println("  Processes that are waiting to GC:");
10950                    printed = true;
10951                }
10952                pw.print("    Process "); pw.println(proc);
10953                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10954                        pw.print(", last gced=");
10955                        pw.print(now-proc.lastRequestedGc);
10956                        pw.print(" ms ago, last lowMem=");
10957                        pw.print(now-proc.lastLowMemory);
10958                        pw.println(" ms ago");
10959
10960            }
10961        }
10962        return needSep;
10963    }
10964
10965    void printOomLevel(PrintWriter pw, String name, int adj) {
10966        pw.print("    ");
10967        if (adj >= 0) {
10968            pw.print(' ');
10969            if (adj < 10) pw.print(' ');
10970        } else {
10971            if (adj > -10) pw.print(' ');
10972        }
10973        pw.print(adj);
10974        pw.print(": ");
10975        pw.print(name);
10976        pw.print(" (");
10977        pw.print(mProcessList.getMemLevel(adj)/1024);
10978        pw.println(" kB)");
10979    }
10980
10981    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10982            int opti, boolean dumpAll) {
10983        boolean needSep = false;
10984
10985        if (mLruProcesses.size() > 0) {
10986            if (needSep) pw.println();
10987            needSep = true;
10988            pw.println("  OOM levels:");
10989            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10990            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10991            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10992            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10993            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10994            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10995            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10996            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10997            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
10998            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
10999            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11000            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11001            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11002
11003            if (needSep) pw.println();
11004            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11005                    pw.print(" total, non-act at ");
11006                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11007                    pw.print(", non-svc at ");
11008                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11009                    pw.println("):");
11010            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11011            needSep = true;
11012        }
11013
11014        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11015
11016        pw.println();
11017        pw.println("  mHomeProcess: " + mHomeProcess);
11018        pw.println("  mPreviousProcess: " + mPreviousProcess);
11019        if (mHeavyWeightProcess != null) {
11020            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11021        }
11022
11023        return true;
11024    }
11025
11026    /**
11027     * There are three ways to call this:
11028     *  - no provider specified: dump all the providers
11029     *  - a flattened component name that matched an existing provider was specified as the
11030     *    first arg: dump that one provider
11031     *  - the first arg isn't the flattened component name of an existing provider:
11032     *    dump all providers whose component contains the first arg as a substring
11033     */
11034    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11035            int opti, boolean dumpAll) {
11036        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11037    }
11038
11039    static class ItemMatcher {
11040        ArrayList<ComponentName> components;
11041        ArrayList<String> strings;
11042        ArrayList<Integer> objects;
11043        boolean all;
11044
11045        ItemMatcher() {
11046            all = true;
11047        }
11048
11049        void build(String name) {
11050            ComponentName componentName = ComponentName.unflattenFromString(name);
11051            if (componentName != null) {
11052                if (components == null) {
11053                    components = new ArrayList<ComponentName>();
11054                }
11055                components.add(componentName);
11056                all = false;
11057            } else {
11058                int objectId = 0;
11059                // Not a '/' separated full component name; maybe an object ID?
11060                try {
11061                    objectId = Integer.parseInt(name, 16);
11062                    if (objects == null) {
11063                        objects = new ArrayList<Integer>();
11064                    }
11065                    objects.add(objectId);
11066                    all = false;
11067                } catch (RuntimeException e) {
11068                    // Not an integer; just do string match.
11069                    if (strings == null) {
11070                        strings = new ArrayList<String>();
11071                    }
11072                    strings.add(name);
11073                    all = false;
11074                }
11075            }
11076        }
11077
11078        int build(String[] args, int opti) {
11079            for (; opti<args.length; opti++) {
11080                String name = args[opti];
11081                if ("--".equals(name)) {
11082                    return opti+1;
11083                }
11084                build(name);
11085            }
11086            return opti;
11087        }
11088
11089        boolean match(Object object, ComponentName comp) {
11090            if (all) {
11091                return true;
11092            }
11093            if (components != null) {
11094                for (int i=0; i<components.size(); i++) {
11095                    if (components.get(i).equals(comp)) {
11096                        return true;
11097                    }
11098                }
11099            }
11100            if (objects != null) {
11101                for (int i=0; i<objects.size(); i++) {
11102                    if (System.identityHashCode(object) == objects.get(i)) {
11103                        return true;
11104                    }
11105                }
11106            }
11107            if (strings != null) {
11108                String flat = comp.flattenToString();
11109                for (int i=0; i<strings.size(); i++) {
11110                    if (flat.contains(strings.get(i))) {
11111                        return true;
11112                    }
11113                }
11114            }
11115            return false;
11116        }
11117    }
11118
11119    /**
11120     * There are three things that cmd can be:
11121     *  - a flattened component name that matches an existing activity
11122     *  - the cmd arg isn't the flattened component name of an existing activity:
11123     *    dump all activity whose component contains the cmd as a substring
11124     *  - A hex number of the ActivityRecord object instance.
11125     */
11126    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11127            int opti, boolean dumpAll) {
11128        ArrayList<ActivityRecord> activities;
11129
11130        synchronized (this) {
11131            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11132        }
11133
11134        if (activities.size() <= 0) {
11135            return false;
11136        }
11137
11138        String[] newArgs = new String[args.length - opti];
11139        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11140
11141        TaskRecord lastTask = null;
11142        boolean needSep = false;
11143        for (int i=activities.size()-1; i>=0; i--) {
11144            ActivityRecord r = activities.get(i);
11145            if (needSep) {
11146                pw.println();
11147            }
11148            needSep = true;
11149            synchronized (this) {
11150                if (lastTask != r.task) {
11151                    lastTask = r.task;
11152                    pw.print("TASK "); pw.print(lastTask.affinity);
11153                            pw.print(" id="); pw.println(lastTask.taskId);
11154                    if (dumpAll) {
11155                        lastTask.dump(pw, "  ");
11156                    }
11157                }
11158            }
11159            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11160        }
11161        return true;
11162    }
11163
11164    /**
11165     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11166     * there is a thread associated with the activity.
11167     */
11168    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11169            final ActivityRecord r, String[] args, boolean dumpAll) {
11170        String innerPrefix = prefix + "  ";
11171        synchronized (this) {
11172            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11173                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11174                    pw.print(" pid=");
11175                    if (r.app != null) pw.println(r.app.pid);
11176                    else pw.println("(not running)");
11177            if (dumpAll) {
11178                r.dump(pw, innerPrefix);
11179            }
11180        }
11181        if (r.app != null && r.app.thread != null) {
11182            // flush anything that is already in the PrintWriter since the thread is going
11183            // to write to the file descriptor directly
11184            pw.flush();
11185            try {
11186                TransferPipe tp = new TransferPipe();
11187                try {
11188                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11189                            r.appToken, innerPrefix, args);
11190                    tp.go(fd);
11191                } finally {
11192                    tp.kill();
11193                }
11194            } catch (IOException e) {
11195                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11196            } catch (RemoteException e) {
11197                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11198            }
11199        }
11200    }
11201
11202    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11203            int opti, boolean dumpAll, String dumpPackage) {
11204        boolean needSep = false;
11205        boolean onlyHistory = false;
11206        boolean printedAnything = false;
11207
11208        if ("history".equals(dumpPackage)) {
11209            if (opti < args.length && "-s".equals(args[opti])) {
11210                dumpAll = false;
11211            }
11212            onlyHistory = true;
11213            dumpPackage = null;
11214        }
11215
11216        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11217        if (!onlyHistory && dumpAll) {
11218            if (mRegisteredReceivers.size() > 0) {
11219                boolean printed = false;
11220                Iterator it = mRegisteredReceivers.values().iterator();
11221                while (it.hasNext()) {
11222                    ReceiverList r = (ReceiverList)it.next();
11223                    if (dumpPackage != null && (r.app == null ||
11224                            !dumpPackage.equals(r.app.info.packageName))) {
11225                        continue;
11226                    }
11227                    if (!printed) {
11228                        pw.println("  Registered Receivers:");
11229                        needSep = true;
11230                        printed = true;
11231                        printedAnything = true;
11232                    }
11233                    pw.print("  * "); pw.println(r);
11234                    r.dump(pw, "    ");
11235                }
11236            }
11237
11238            if (mReceiverResolver.dump(pw, needSep ?
11239                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11240                    "    ", dumpPackage, false)) {
11241                needSep = true;
11242                printedAnything = true;
11243            }
11244        }
11245
11246        for (BroadcastQueue q : mBroadcastQueues) {
11247            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11248            printedAnything |= needSep;
11249        }
11250
11251        needSep = true;
11252
11253        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11254            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11255                if (needSep) {
11256                    pw.println();
11257                }
11258                needSep = true;
11259                printedAnything = true;
11260                pw.print("  Sticky broadcasts for user ");
11261                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11262                StringBuilder sb = new StringBuilder(128);
11263                for (Map.Entry<String, ArrayList<Intent>> ent
11264                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11265                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11266                    if (dumpAll) {
11267                        pw.println(":");
11268                        ArrayList<Intent> intents = ent.getValue();
11269                        final int N = intents.size();
11270                        for (int i=0; i<N; i++) {
11271                            sb.setLength(0);
11272                            sb.append("    Intent: ");
11273                            intents.get(i).toShortString(sb, false, true, false, false);
11274                            pw.println(sb.toString());
11275                            Bundle bundle = intents.get(i).getExtras();
11276                            if (bundle != null) {
11277                                pw.print("      ");
11278                                pw.println(bundle.toString());
11279                            }
11280                        }
11281                    } else {
11282                        pw.println("");
11283                    }
11284                }
11285            }
11286        }
11287
11288        if (!onlyHistory && dumpAll) {
11289            pw.println();
11290            for (BroadcastQueue queue : mBroadcastQueues) {
11291                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11292                        + queue.mBroadcastsScheduled);
11293            }
11294            pw.println("  mHandler:");
11295            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11296            needSep = true;
11297            printedAnything = true;
11298        }
11299
11300        if (!printedAnything) {
11301            pw.println("  (nothing)");
11302        }
11303    }
11304
11305    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11306            int opti, boolean dumpAll, String dumpPackage) {
11307        boolean needSep;
11308        boolean printedAnything = false;
11309
11310        ItemMatcher matcher = new ItemMatcher();
11311        matcher.build(args, opti);
11312
11313        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11314
11315        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11316        printedAnything |= needSep;
11317
11318        if (mLaunchingProviders.size() > 0) {
11319            boolean printed = false;
11320            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11321                ContentProviderRecord r = mLaunchingProviders.get(i);
11322                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11323                    continue;
11324                }
11325                if (!printed) {
11326                    if (needSep) pw.println();
11327                    needSep = true;
11328                    pw.println("  Launching content providers:");
11329                    printed = true;
11330                    printedAnything = true;
11331                }
11332                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11333                        pw.println(r);
11334            }
11335        }
11336
11337        if (mGrantedUriPermissions.size() > 0) {
11338            boolean printed = false;
11339            int dumpUid = -2;
11340            if (dumpPackage != null) {
11341                try {
11342                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11343                } catch (NameNotFoundException e) {
11344                    dumpUid = -1;
11345                }
11346            }
11347            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11348                int uid = mGrantedUriPermissions.keyAt(i);
11349                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11350                    continue;
11351                }
11352                ArrayMap<Uri, UriPermission> perms
11353                        = mGrantedUriPermissions.valueAt(i);
11354                if (!printed) {
11355                    if (needSep) pw.println();
11356                    needSep = true;
11357                    pw.println("  Granted Uri Permissions:");
11358                    printed = true;
11359                    printedAnything = true;
11360                }
11361                pw.print("  * UID "); pw.print(uid);
11362                        pw.println(" holds:");
11363                for (UriPermission perm : perms.values()) {
11364                    pw.print("    "); pw.println(perm);
11365                    if (dumpAll) {
11366                        perm.dump(pw, "      ");
11367                    }
11368                }
11369            }
11370        }
11371
11372        if (!printedAnything) {
11373            pw.println("  (nothing)");
11374        }
11375    }
11376
11377    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11378            int opti, boolean dumpAll, String dumpPackage) {
11379        boolean printed = false;
11380
11381        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11382
11383        if (mIntentSenderRecords.size() > 0) {
11384            Iterator<WeakReference<PendingIntentRecord>> it
11385                    = mIntentSenderRecords.values().iterator();
11386            while (it.hasNext()) {
11387                WeakReference<PendingIntentRecord> ref = it.next();
11388                PendingIntentRecord rec = ref != null ? ref.get(): null;
11389                if (dumpPackage != null && (rec == null
11390                        || !dumpPackage.equals(rec.key.packageName))) {
11391                    continue;
11392                }
11393                printed = true;
11394                if (rec != null) {
11395                    pw.print("  * "); pw.println(rec);
11396                    if (dumpAll) {
11397                        rec.dump(pw, "    ");
11398                    }
11399                } else {
11400                    pw.print("  * "); pw.println(ref);
11401                }
11402            }
11403        }
11404
11405        if (!printed) {
11406            pw.println("  (nothing)");
11407        }
11408    }
11409
11410    private static final int dumpProcessList(PrintWriter pw,
11411            ActivityManagerService service, List list,
11412            String prefix, String normalLabel, String persistentLabel,
11413            String dumpPackage) {
11414        int numPers = 0;
11415        final int N = list.size()-1;
11416        for (int i=N; i>=0; i--) {
11417            ProcessRecord r = (ProcessRecord)list.get(i);
11418            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11419                continue;
11420            }
11421            pw.println(String.format("%s%s #%2d: %s",
11422                    prefix, (r.persistent ? persistentLabel : normalLabel),
11423                    i, r.toString()));
11424            if (r.persistent) {
11425                numPers++;
11426            }
11427        }
11428        return numPers;
11429    }
11430
11431    private static final boolean dumpProcessOomList(PrintWriter pw,
11432            ActivityManagerService service, List<ProcessRecord> origList,
11433            String prefix, String normalLabel, String persistentLabel,
11434            boolean inclDetails, String dumpPackage) {
11435
11436        ArrayList<Pair<ProcessRecord, Integer>> list
11437                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11438        for (int i=0; i<origList.size(); i++) {
11439            ProcessRecord r = origList.get(i);
11440            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11441                continue;
11442            }
11443            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11444        }
11445
11446        if (list.size() <= 0) {
11447            return false;
11448        }
11449
11450        Comparator<Pair<ProcessRecord, Integer>> comparator
11451                = new Comparator<Pair<ProcessRecord, Integer>>() {
11452            @Override
11453            public int compare(Pair<ProcessRecord, Integer> object1,
11454                    Pair<ProcessRecord, Integer> object2) {
11455                if (object1.first.setAdj != object2.first.setAdj) {
11456                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11457                }
11458                if (object1.second.intValue() != object2.second.intValue()) {
11459                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11460                }
11461                return 0;
11462            }
11463        };
11464
11465        Collections.sort(list, comparator);
11466
11467        final long curRealtime = SystemClock.elapsedRealtime();
11468        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11469        final long curUptime = SystemClock.uptimeMillis();
11470        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11471
11472        for (int i=list.size()-1; i>=0; i--) {
11473            ProcessRecord r = list.get(i).first;
11474            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11475            char schedGroup;
11476            switch (r.setSchedGroup) {
11477                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11478                    schedGroup = 'B';
11479                    break;
11480                case Process.THREAD_GROUP_DEFAULT:
11481                    schedGroup = 'F';
11482                    break;
11483                default:
11484                    schedGroup = '?';
11485                    break;
11486            }
11487            char foreground;
11488            if (r.foregroundActivities) {
11489                foreground = 'A';
11490            } else if (r.foregroundServices) {
11491                foreground = 'S';
11492            } else {
11493                foreground = ' ';
11494            }
11495            String procState = ProcessList.makeProcStateString(r.curProcState);
11496            pw.print(prefix);
11497            pw.print(r.persistent ? persistentLabel : normalLabel);
11498            pw.print(" #");
11499            int num = (origList.size()-1)-list.get(i).second;
11500            if (num < 10) pw.print(' ');
11501            pw.print(num);
11502            pw.print(": ");
11503            pw.print(oomAdj);
11504            pw.print(' ');
11505            pw.print(schedGroup);
11506            pw.print('/');
11507            pw.print(foreground);
11508            pw.print('/');
11509            pw.print(procState);
11510            pw.print(" trm:");
11511            if (r.trimMemoryLevel < 10) pw.print(' ');
11512            pw.print(r.trimMemoryLevel);
11513            pw.print(' ');
11514            pw.print(r.toShortString());
11515            pw.print(" (");
11516            pw.print(r.adjType);
11517            pw.println(')');
11518            if (r.adjSource != null || r.adjTarget != null) {
11519                pw.print(prefix);
11520                pw.print("    ");
11521                if (r.adjTarget instanceof ComponentName) {
11522                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11523                } else if (r.adjTarget != null) {
11524                    pw.print(r.adjTarget.toString());
11525                } else {
11526                    pw.print("{null}");
11527                }
11528                pw.print("<=");
11529                if (r.adjSource instanceof ProcessRecord) {
11530                    pw.print("Proc{");
11531                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11532                    pw.println("}");
11533                } else if (r.adjSource != null) {
11534                    pw.println(r.adjSource.toString());
11535                } else {
11536                    pw.println("{null}");
11537                }
11538            }
11539            if (inclDetails) {
11540                pw.print(prefix);
11541                pw.print("    ");
11542                pw.print("oom: max="); pw.print(r.maxAdj);
11543                pw.print(" curRaw="); pw.print(r.curRawAdj);
11544                pw.print(" setRaw="); pw.print(r.setRawAdj);
11545                pw.print(" cur="); pw.print(r.curAdj);
11546                pw.print(" set="); pw.println(r.setAdj);
11547                pw.print(prefix);
11548                pw.print("    ");
11549                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11550                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11551                pw.print(" lastPss="); pw.print(r.lastPss);
11552                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11553                pw.print(prefix);
11554                pw.print("    ");
11555                pw.print("keeping="); pw.print(r.keeping);
11556                pw.print(" cached="); pw.print(r.cached);
11557                pw.print(" empty="); pw.print(r.empty);
11558                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11559
11560                if (!r.keeping) {
11561                    if (r.lastWakeTime != 0) {
11562                        long wtime;
11563                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11564                        synchronized (stats) {
11565                            wtime = stats.getProcessWakeTime(r.info.uid,
11566                                    r.pid, curRealtime);
11567                        }
11568                        long timeUsed = wtime - r.lastWakeTime;
11569                        pw.print(prefix);
11570                        pw.print("    ");
11571                        pw.print("keep awake over ");
11572                        TimeUtils.formatDuration(realtimeSince, pw);
11573                        pw.print(" used ");
11574                        TimeUtils.formatDuration(timeUsed, pw);
11575                        pw.print(" (");
11576                        pw.print((timeUsed*100)/realtimeSince);
11577                        pw.println("%)");
11578                    }
11579                    if (r.lastCpuTime != 0) {
11580                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11581                        pw.print(prefix);
11582                        pw.print("    ");
11583                        pw.print("run cpu over ");
11584                        TimeUtils.formatDuration(uptimeSince, pw);
11585                        pw.print(" used ");
11586                        TimeUtils.formatDuration(timeUsed, pw);
11587                        pw.print(" (");
11588                        pw.print((timeUsed*100)/uptimeSince);
11589                        pw.println("%)");
11590                    }
11591                }
11592            }
11593        }
11594        return true;
11595    }
11596
11597    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11598        ArrayList<ProcessRecord> procs;
11599        synchronized (this) {
11600            if (args != null && args.length > start
11601                    && args[start].charAt(0) != '-') {
11602                procs = new ArrayList<ProcessRecord>();
11603                int pid = -1;
11604                try {
11605                    pid = Integer.parseInt(args[start]);
11606                } catch (NumberFormatException e) {
11607                }
11608                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11609                    ProcessRecord proc = mLruProcesses.get(i);
11610                    if (proc.pid == pid) {
11611                        procs.add(proc);
11612                    } else if (proc.processName.equals(args[start])) {
11613                        procs.add(proc);
11614                    }
11615                }
11616                if (procs.size() <= 0) {
11617                    return null;
11618                }
11619            } else {
11620                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11621            }
11622        }
11623        return procs;
11624    }
11625
11626    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11627            PrintWriter pw, String[] args) {
11628        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11629        if (procs == null) {
11630            pw.println("No process found for: " + args[0]);
11631            return;
11632        }
11633
11634        long uptime = SystemClock.uptimeMillis();
11635        long realtime = SystemClock.elapsedRealtime();
11636        pw.println("Applications Graphics Acceleration Info:");
11637        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11638
11639        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11640            ProcessRecord r = procs.get(i);
11641            if (r.thread != null) {
11642                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11643                pw.flush();
11644                try {
11645                    TransferPipe tp = new TransferPipe();
11646                    try {
11647                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11648                        tp.go(fd);
11649                    } finally {
11650                        tp.kill();
11651                    }
11652                } catch (IOException e) {
11653                    pw.println("Failure while dumping the app: " + r);
11654                    pw.flush();
11655                } catch (RemoteException e) {
11656                    pw.println("Got a RemoteException while dumping the app " + r);
11657                    pw.flush();
11658                }
11659            }
11660        }
11661    }
11662
11663    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11664        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11665        if (procs == null) {
11666            pw.println("No process found for: " + args[0]);
11667            return;
11668        }
11669
11670        pw.println("Applications Database Info:");
11671
11672        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11673            ProcessRecord r = procs.get(i);
11674            if (r.thread != null) {
11675                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11676                pw.flush();
11677                try {
11678                    TransferPipe tp = new TransferPipe();
11679                    try {
11680                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11681                        tp.go(fd);
11682                    } finally {
11683                        tp.kill();
11684                    }
11685                } catch (IOException e) {
11686                    pw.println("Failure while dumping the app: " + r);
11687                    pw.flush();
11688                } catch (RemoteException e) {
11689                    pw.println("Got a RemoteException while dumping the app " + r);
11690                    pw.flush();
11691                }
11692            }
11693        }
11694    }
11695
11696    final static class MemItem {
11697        final boolean isProc;
11698        final String label;
11699        final String shortLabel;
11700        final long pss;
11701        final int id;
11702        final boolean hasActivities;
11703        ArrayList<MemItem> subitems;
11704
11705        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11706                boolean _hasActivities) {
11707            isProc = true;
11708            label = _label;
11709            shortLabel = _shortLabel;
11710            pss = _pss;
11711            id = _id;
11712            hasActivities = _hasActivities;
11713        }
11714
11715        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11716            isProc = false;
11717            label = _label;
11718            shortLabel = _shortLabel;
11719            pss = _pss;
11720            id = _id;
11721            hasActivities = false;
11722        }
11723    }
11724
11725    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11726            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11727        if (sort && !isCompact) {
11728            Collections.sort(items, new Comparator<MemItem>() {
11729                @Override
11730                public int compare(MemItem lhs, MemItem rhs) {
11731                    if (lhs.pss < rhs.pss) {
11732                        return 1;
11733                    } else if (lhs.pss > rhs.pss) {
11734                        return -1;
11735                    }
11736                    return 0;
11737                }
11738            });
11739        }
11740
11741        for (int i=0; i<items.size(); i++) {
11742            MemItem mi = items.get(i);
11743            if (!isCompact) {
11744                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11745            } else if (mi.isProc) {
11746                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11747                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11748                pw.println(mi.hasActivities ? ",a" : ",e");
11749            } else {
11750                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11751                pw.println(mi.pss);
11752            }
11753            if (mi.subitems != null) {
11754                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11755                        true, isCompact);
11756            }
11757        }
11758    }
11759
11760    // These are in KB.
11761    static final long[] DUMP_MEM_BUCKETS = new long[] {
11762        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11763        120*1024, 160*1024, 200*1024,
11764        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11765        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11766    };
11767
11768    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11769            boolean stackLike) {
11770        int start = label.lastIndexOf('.');
11771        if (start >= 0) start++;
11772        else start = 0;
11773        int end = label.length();
11774        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11775            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11776                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11777                out.append(bucket);
11778                out.append(stackLike ? "MB." : "MB ");
11779                out.append(label, start, end);
11780                return;
11781            }
11782        }
11783        out.append(memKB/1024);
11784        out.append(stackLike ? "MB." : "MB ");
11785        out.append(label, start, end);
11786    }
11787
11788    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11789            ProcessList.NATIVE_ADJ,
11790            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11791            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11792            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11793            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11794            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11795    };
11796    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11797            "Native",
11798            "System", "Persistent", "Foreground",
11799            "Visible", "Perceptible",
11800            "Heavy Weight", "Backup",
11801            "A Services", "Home",
11802            "Previous", "B Services", "Cached"
11803    };
11804    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11805            "native",
11806            "sys", "pers", "fore",
11807            "vis", "percept",
11808            "heavy", "backup",
11809            "servicea", "home",
11810            "prev", "serviceb", "cached"
11811    };
11812
11813    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11814            long realtime, boolean isCheckinRequest, boolean isCompact) {
11815        if (isCheckinRequest || isCompact) {
11816            // short checkin version
11817            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11818        } else {
11819            pw.println("Applications Memory Usage (kB):");
11820            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11821        }
11822    }
11823
11824    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11825            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11826        boolean dumpDetails = false;
11827        boolean dumpFullDetails = false;
11828        boolean dumpDalvik = false;
11829        boolean oomOnly = false;
11830        boolean isCompact = false;
11831        boolean localOnly = false;
11832
11833        int opti = 0;
11834        while (opti < args.length) {
11835            String opt = args[opti];
11836            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11837                break;
11838            }
11839            opti++;
11840            if ("-a".equals(opt)) {
11841                dumpDetails = true;
11842                dumpFullDetails = true;
11843                dumpDalvik = true;
11844            } else if ("-d".equals(opt)) {
11845                dumpDalvik = true;
11846            } else if ("-c".equals(opt)) {
11847                isCompact = true;
11848            } else if ("--oom".equals(opt)) {
11849                oomOnly = true;
11850            } else if ("--local".equals(opt)) {
11851                localOnly = true;
11852            } else if ("-h".equals(opt)) {
11853                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11854                pw.println("  -a: include all available information for each process.");
11855                pw.println("  -d: include dalvik details when dumping process details.");
11856                pw.println("  -c: dump in a compact machine-parseable representation.");
11857                pw.println("  --oom: only show processes organized by oom adj.");
11858                pw.println("  --local: only collect details locally, don't call process.");
11859                pw.println("If [process] is specified it can be the name or ");
11860                pw.println("pid of a specific process to dump.");
11861                return;
11862            } else {
11863                pw.println("Unknown argument: " + opt + "; use -h for help");
11864            }
11865        }
11866
11867        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11868        long uptime = SystemClock.uptimeMillis();
11869        long realtime = SystemClock.elapsedRealtime();
11870        final long[] tmpLong = new long[1];
11871
11872        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11873        if (procs == null) {
11874            // No Java processes.  Maybe they want to print a native process.
11875            if (args != null && args.length > opti
11876                    && args[opti].charAt(0) != '-') {
11877                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11878                        = new ArrayList<ProcessCpuTracker.Stats>();
11879                updateCpuStatsNow();
11880                int findPid = -1;
11881                try {
11882                    findPid = Integer.parseInt(args[opti]);
11883                } catch (NumberFormatException e) {
11884                }
11885                synchronized (mProcessCpuThread) {
11886                    final int N = mProcessCpuTracker.countStats();
11887                    for (int i=0; i<N; i++) {
11888                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11889                        if (st.pid == findPid || (st.baseName != null
11890                                && st.baseName.equals(args[opti]))) {
11891                            nativeProcs.add(st);
11892                        }
11893                    }
11894                }
11895                if (nativeProcs.size() > 0) {
11896                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11897                            isCompact);
11898                    Debug.MemoryInfo mi = null;
11899                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11900                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11901                        final int pid = r.pid;
11902                        if (!isCheckinRequest && dumpDetails) {
11903                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11904                        }
11905                        if (mi == null) {
11906                            mi = new Debug.MemoryInfo();
11907                        }
11908                        if (dumpDetails || (!brief && !oomOnly)) {
11909                            Debug.getMemoryInfo(pid, mi);
11910                        } else {
11911                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11912                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11913                        }
11914                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11915                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11916                        if (isCheckinRequest) {
11917                            pw.println();
11918                        }
11919                    }
11920                    return;
11921                }
11922            }
11923            pw.println("No process found for: " + args[opti]);
11924            return;
11925        }
11926
11927        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11928            dumpDetails = true;
11929        }
11930
11931        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11932
11933        String[] innerArgs = new String[args.length-opti];
11934        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11935
11936        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11937        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11938        long nativePss=0, dalvikPss=0, otherPss=0;
11939        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11940
11941        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11942        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11943                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11944
11945        long totalPss = 0;
11946        long cachedPss = 0;
11947
11948        Debug.MemoryInfo mi = null;
11949        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11950            final ProcessRecord r = procs.get(i);
11951            final IApplicationThread thread;
11952            final int pid;
11953            final int oomAdj;
11954            final boolean hasActivities;
11955            synchronized (this) {
11956                thread = r.thread;
11957                pid = r.pid;
11958                oomAdj = r.getSetAdjWithServices();
11959                hasActivities = r.activities.size() > 0;
11960            }
11961            if (thread != null) {
11962                if (!isCheckinRequest && dumpDetails) {
11963                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11964                }
11965                if (mi == null) {
11966                    mi = new Debug.MemoryInfo();
11967                }
11968                if (dumpDetails || (!brief && !oomOnly)) {
11969                    Debug.getMemoryInfo(pid, mi);
11970                } else {
11971                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11972                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11973                }
11974                if (dumpDetails) {
11975                    if (localOnly) {
11976                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11977                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11978                        if (isCheckinRequest) {
11979                            pw.println();
11980                        }
11981                    } else {
11982                        try {
11983                            pw.flush();
11984                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11985                                    dumpDalvik, innerArgs);
11986                        } catch (RemoteException e) {
11987                            if (!isCheckinRequest) {
11988                                pw.println("Got RemoteException!");
11989                                pw.flush();
11990                            }
11991                        }
11992                    }
11993                }
11994
11995                final long myTotalPss = mi.getTotalPss();
11996                final long myTotalUss = mi.getTotalUss();
11997
11998                synchronized (this) {
11999                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12000                        // Record this for posterity if the process has been stable.
12001                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12002                    }
12003                }
12004
12005                if (!isCheckinRequest && mi != null) {
12006                    totalPss += myTotalPss;
12007                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12008                            (hasActivities ? " / activities)" : ")"),
12009                            r.processName, myTotalPss, pid, hasActivities);
12010                    procMems.add(pssItem);
12011                    procMemsMap.put(pid, pssItem);
12012
12013                    nativePss += mi.nativePss;
12014                    dalvikPss += mi.dalvikPss;
12015                    otherPss += mi.otherPss;
12016                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12017                        long mem = mi.getOtherPss(j);
12018                        miscPss[j] += mem;
12019                        otherPss -= mem;
12020                    }
12021
12022                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12023                        cachedPss += myTotalPss;
12024                    }
12025
12026                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12027                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12028                                || oomIndex == (oomPss.length-1)) {
12029                            oomPss[oomIndex] += myTotalPss;
12030                            if (oomProcs[oomIndex] == null) {
12031                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12032                            }
12033                            oomProcs[oomIndex].add(pssItem);
12034                            break;
12035                        }
12036                    }
12037                }
12038            }
12039        }
12040
12041        if (!isCheckinRequest && procs.size() > 1) {
12042            // If we are showing aggregations, also look for native processes to
12043            // include so that our aggregations are more accurate.
12044            updateCpuStatsNow();
12045            synchronized (mProcessCpuThread) {
12046                final int N = mProcessCpuTracker.countStats();
12047                for (int i=0; i<N; i++) {
12048                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12049                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12050                        if (mi == null) {
12051                            mi = new Debug.MemoryInfo();
12052                        }
12053                        if (!brief && !oomOnly) {
12054                            Debug.getMemoryInfo(st.pid, mi);
12055                        } else {
12056                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12057                            mi.nativePrivateDirty = (int)tmpLong[0];
12058                        }
12059
12060                        final long myTotalPss = mi.getTotalPss();
12061                        totalPss += myTotalPss;
12062
12063                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12064                                st.name, myTotalPss, st.pid, false);
12065                        procMems.add(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                        oomPss[0] += myTotalPss;
12076                        if (oomProcs[0] == null) {
12077                            oomProcs[0] = new ArrayList<MemItem>();
12078                        }
12079                        oomProcs[0].add(pssItem);
12080                    }
12081                }
12082            }
12083
12084            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12085
12086            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12087            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12088            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12089            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12090                String label = Debug.MemoryInfo.getOtherLabel(j);
12091                catMems.add(new MemItem(label, label, miscPss[j], j));
12092            }
12093
12094            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12095            for (int j=0; j<oomPss.length; j++) {
12096                if (oomPss[j] != 0) {
12097                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12098                            : DUMP_MEM_OOM_LABEL[j];
12099                    MemItem item = new MemItem(label, label, oomPss[j],
12100                            DUMP_MEM_OOM_ADJ[j]);
12101                    item.subitems = oomProcs[j];
12102                    oomMems.add(item);
12103                }
12104            }
12105
12106            if (!brief && !oomOnly && !isCompact) {
12107                pw.println();
12108                pw.println("Total PSS by process:");
12109                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12110                pw.println();
12111            }
12112            if (!isCompact) {
12113                pw.println("Total PSS by OOM adjustment:");
12114            }
12115            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12116            if (!brief && !oomOnly) {
12117                PrintWriter out = categoryPw != null ? categoryPw : pw;
12118                if (!isCompact) {
12119                    out.println();
12120                    out.println("Total PSS by category:");
12121                }
12122                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12123            }
12124            if (!isCompact) {
12125                pw.println();
12126            }
12127            MemInfoReader memInfo = new MemInfoReader();
12128            memInfo.readMemInfo();
12129            if (!brief) {
12130                if (!isCompact) {
12131                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12132                    pw.print(" kB (status ");
12133                    switch (mLastMemoryLevel) {
12134                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12135                            pw.println("normal)");
12136                            break;
12137                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12138                            pw.println("moderate)");
12139                            break;
12140                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12141                            pw.println("low)");
12142                            break;
12143                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12144                            pw.println("critical)");
12145                            break;
12146                        default:
12147                            pw.print(mLastMemoryLevel);
12148                            pw.println(")");
12149                            break;
12150                    }
12151                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12152                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12153                            pw.print(cachedPss); pw.print(" cached pss + ");
12154                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12155                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12156                } else {
12157                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12158                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12159                            + memInfo.getFreeSizeKb()); pw.print(",");
12160                    pw.println(totalPss - cachedPss);
12161                }
12162            }
12163            if (!isCompact) {
12164                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12165                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12166                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12167                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12168                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12169                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12170                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12171                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12172                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12173                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12174                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12175            }
12176            if (!brief) {
12177                if (memInfo.getZramTotalSizeKb() != 0) {
12178                    if (!isCompact) {
12179                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12180                                pw.print(" kB physical used for ");
12181                                pw.print(memInfo.getSwapTotalSizeKb()
12182                                        - memInfo.getSwapFreeSizeKb());
12183                                pw.print(" kB in swap (");
12184                                pw.print(memInfo.getSwapTotalSizeKb());
12185                                pw.println(" kB total swap)");
12186                    } else {
12187                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12188                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12189                                pw.println(memInfo.getSwapFreeSizeKb());
12190                    }
12191                }
12192                final int[] SINGLE_LONG_FORMAT = new int[] {
12193                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12194                };
12195                long[] longOut = new long[1];
12196                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12197                        SINGLE_LONG_FORMAT, null, longOut, null);
12198                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12199                longOut[0] = 0;
12200                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12201                        SINGLE_LONG_FORMAT, null, longOut, null);
12202                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12203                longOut[0] = 0;
12204                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12205                        SINGLE_LONG_FORMAT, null, longOut, null);
12206                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12207                longOut[0] = 0;
12208                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12209                        SINGLE_LONG_FORMAT, null, longOut, null);
12210                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12211                if (!isCompact) {
12212                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12213                        pw.print("      KSM: "); pw.print(sharing);
12214                                pw.print(" kB saved from shared ");
12215                                pw.print(shared); pw.println(" kB");
12216                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12217                                pw.print(voltile); pw.println(" kB volatile");
12218                    }
12219                    pw.print("   Tuning: ");
12220                    pw.print(ActivityManager.staticGetMemoryClass());
12221                    pw.print(" (large ");
12222                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12223                    pw.print("), oom ");
12224                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12225                    pw.print(" kB");
12226                    pw.print(", restore limit ");
12227                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12228                    pw.print(" kB");
12229                    if (ActivityManager.isLowRamDeviceStatic()) {
12230                        pw.print(" (low-ram)");
12231                    }
12232                    if (ActivityManager.isHighEndGfx()) {
12233                        pw.print(" (high-end-gfx)");
12234                    }
12235                    pw.println();
12236                } else {
12237                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12238                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12239                    pw.println(voltile);
12240                    pw.print("tuning,");
12241                    pw.print(ActivityManager.staticGetMemoryClass());
12242                    pw.print(',');
12243                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12244                    pw.print(',');
12245                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12246                    if (ActivityManager.isLowRamDeviceStatic()) {
12247                        pw.print(",low-ram");
12248                    }
12249                    if (ActivityManager.isHighEndGfx()) {
12250                        pw.print(",high-end-gfx");
12251                    }
12252                    pw.println();
12253                }
12254            }
12255        }
12256    }
12257
12258    /**
12259     * Searches array of arguments for the specified string
12260     * @param args array of argument strings
12261     * @param value value to search for
12262     * @return true if the value is contained in the array
12263     */
12264    private static boolean scanArgs(String[] args, String value) {
12265        if (args != null) {
12266            for (String arg : args) {
12267                if (value.equals(arg)) {
12268                    return true;
12269                }
12270            }
12271        }
12272        return false;
12273    }
12274
12275    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12276            ContentProviderRecord cpr, boolean always) {
12277        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12278
12279        if (!inLaunching || always) {
12280            synchronized (cpr) {
12281                cpr.launchingApp = null;
12282                cpr.notifyAll();
12283            }
12284            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12285            String names[] = cpr.info.authority.split(";");
12286            for (int j = 0; j < names.length; j++) {
12287                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12288            }
12289        }
12290
12291        for (int i=0; i<cpr.connections.size(); i++) {
12292            ContentProviderConnection conn = cpr.connections.get(i);
12293            if (conn.waiting) {
12294                // If this connection is waiting for the provider, then we don't
12295                // need to mess with its process unless we are always removing
12296                // or for some reason the provider is not currently launching.
12297                if (inLaunching && !always) {
12298                    continue;
12299                }
12300            }
12301            ProcessRecord capp = conn.client;
12302            conn.dead = true;
12303            if (conn.stableCount > 0) {
12304                if (!capp.persistent && capp.thread != null
12305                        && capp.pid != 0
12306                        && capp.pid != MY_PID) {
12307                    killUnneededProcessLocked(capp, "depends on provider "
12308                            + cpr.name.flattenToShortString()
12309                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12310                }
12311            } else if (capp.thread != null && conn.provider.provider != null) {
12312                try {
12313                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12314                } catch (RemoteException e) {
12315                }
12316                // In the protocol here, we don't expect the client to correctly
12317                // clean up this connection, we'll just remove it.
12318                cpr.connections.remove(i);
12319                conn.client.conProviders.remove(conn);
12320            }
12321        }
12322
12323        if (inLaunching && always) {
12324            mLaunchingProviders.remove(cpr);
12325        }
12326        return inLaunching;
12327    }
12328
12329    /**
12330     * Main code for cleaning up a process when it has gone away.  This is
12331     * called both as a result of the process dying, or directly when stopping
12332     * a process when running in single process mode.
12333     */
12334    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12335            boolean restarting, boolean allowRestart, int index) {
12336        if (index >= 0) {
12337            removeLruProcessLocked(app);
12338            ProcessList.remove(app.pid);
12339        }
12340
12341        mProcessesToGc.remove(app);
12342        mPendingPssProcesses.remove(app);
12343
12344        // Dismiss any open dialogs.
12345        if (app.crashDialog != null && !app.forceCrashReport) {
12346            app.crashDialog.dismiss();
12347            app.crashDialog = null;
12348        }
12349        if (app.anrDialog != null) {
12350            app.anrDialog.dismiss();
12351            app.anrDialog = null;
12352        }
12353        if (app.waitDialog != null) {
12354            app.waitDialog.dismiss();
12355            app.waitDialog = null;
12356        }
12357
12358        app.crashing = false;
12359        app.notResponding = false;
12360
12361        app.resetPackageList(mProcessStats);
12362        app.unlinkDeathRecipient();
12363        app.makeInactive(mProcessStats);
12364        app.forcingToForeground = null;
12365        updateProcessForegroundLocked(app, false, false);
12366        app.foregroundActivities = false;
12367        app.hasShownUi = false;
12368        app.hasAboveClient = false;
12369
12370        mServices.killServicesLocked(app, allowRestart);
12371
12372        boolean restart = false;
12373
12374        // Remove published content providers.
12375        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12376            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12377            final boolean always = app.bad || !allowRestart;
12378            if (removeDyingProviderLocked(app, cpr, always) || always) {
12379                // We left the provider in the launching list, need to
12380                // restart it.
12381                restart = true;
12382            }
12383
12384            cpr.provider = null;
12385            cpr.proc = null;
12386        }
12387        app.pubProviders.clear();
12388
12389        // Take care of any launching providers waiting for this process.
12390        if (checkAppInLaunchingProvidersLocked(app, false)) {
12391            restart = true;
12392        }
12393
12394        // Unregister from connected content providers.
12395        if (!app.conProviders.isEmpty()) {
12396            for (int i=0; i<app.conProviders.size(); i++) {
12397                ContentProviderConnection conn = app.conProviders.get(i);
12398                conn.provider.connections.remove(conn);
12399            }
12400            app.conProviders.clear();
12401        }
12402
12403        // At this point there may be remaining entries in mLaunchingProviders
12404        // where we were the only one waiting, so they are no longer of use.
12405        // Look for these and clean up if found.
12406        // XXX Commented out for now.  Trying to figure out a way to reproduce
12407        // the actual situation to identify what is actually going on.
12408        if (false) {
12409            for (int i=0; i<mLaunchingProviders.size(); i++) {
12410                ContentProviderRecord cpr = (ContentProviderRecord)
12411                        mLaunchingProviders.get(i);
12412                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12413                    synchronized (cpr) {
12414                        cpr.launchingApp = null;
12415                        cpr.notifyAll();
12416                    }
12417                }
12418            }
12419        }
12420
12421        skipCurrentReceiverLocked(app);
12422
12423        // Unregister any receivers.
12424        for (int i=app.receivers.size()-1; i>=0; i--) {
12425            removeReceiverLocked(app.receivers.valueAt(i));
12426        }
12427        app.receivers.clear();
12428
12429        // If the app is undergoing backup, tell the backup manager about it
12430        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12431            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12432                    + mBackupTarget.appInfo + " died during backup");
12433            try {
12434                IBackupManager bm = IBackupManager.Stub.asInterface(
12435                        ServiceManager.getService(Context.BACKUP_SERVICE));
12436                bm.agentDisconnected(app.info.packageName);
12437            } catch (RemoteException e) {
12438                // can't happen; backup manager is local
12439            }
12440        }
12441
12442        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12443            ProcessChangeItem item = mPendingProcessChanges.get(i);
12444            if (item.pid == app.pid) {
12445                mPendingProcessChanges.remove(i);
12446                mAvailProcessChanges.add(item);
12447            }
12448        }
12449        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12450
12451        // If the caller is restarting this app, then leave it in its
12452        // current lists and let the caller take care of it.
12453        if (restarting) {
12454            return;
12455        }
12456
12457        if (!app.persistent || app.isolated) {
12458            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12459                    "Removing non-persistent process during cleanup: " + app);
12460            mProcessNames.remove(app.processName, app.uid);
12461            mIsolatedProcesses.remove(app.uid);
12462            if (mHeavyWeightProcess == app) {
12463                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12464                        mHeavyWeightProcess.userId, 0));
12465                mHeavyWeightProcess = null;
12466            }
12467        } else if (!app.removed) {
12468            // This app is persistent, so we need to keep its record around.
12469            // If it is not already on the pending app list, add it there
12470            // and start a new process for it.
12471            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12472                mPersistentStartingProcesses.add(app);
12473                restart = true;
12474            }
12475        }
12476        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12477                "Clean-up removing on hold: " + app);
12478        mProcessesOnHold.remove(app);
12479
12480        if (app == mHomeProcess) {
12481            mHomeProcess = null;
12482        }
12483        if (app == mPreviousProcess) {
12484            mPreviousProcess = null;
12485        }
12486
12487        if (restart && !app.isolated) {
12488            // We have components that still need to be running in the
12489            // process, so re-launch it.
12490            mProcessNames.put(app.processName, app.uid, app);
12491            startProcessLocked(app, "restart", app.processName);
12492        } else if (app.pid > 0 && app.pid != MY_PID) {
12493            // Goodbye!
12494            boolean removed;
12495            synchronized (mPidsSelfLocked) {
12496                mPidsSelfLocked.remove(app.pid);
12497                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12498            }
12499            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12500                    app.processName, app.info.uid);
12501            if (app.isolated) {
12502                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12503            }
12504            app.setPid(0);
12505        }
12506    }
12507
12508    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12509        // Look through the content providers we are waiting to have launched,
12510        // and if any run in this process then either schedule a restart of
12511        // the process or kill the client waiting for it if this process has
12512        // gone bad.
12513        int NL = mLaunchingProviders.size();
12514        boolean restart = false;
12515        for (int i=0; i<NL; i++) {
12516            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12517            if (cpr.launchingApp == app) {
12518                if (!alwaysBad && !app.bad) {
12519                    restart = true;
12520                } else {
12521                    removeDyingProviderLocked(app, cpr, true);
12522                    // cpr should have been removed from mLaunchingProviders
12523                    NL = mLaunchingProviders.size();
12524                    i--;
12525                }
12526            }
12527        }
12528        return restart;
12529    }
12530
12531    // =========================================================
12532    // SERVICES
12533    // =========================================================
12534
12535    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12536            int flags) {
12537        enforceNotIsolatedCaller("getServices");
12538        synchronized (this) {
12539            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12540        }
12541    }
12542
12543    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12544        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12545        synchronized (this) {
12546            return mServices.getRunningServiceControlPanelLocked(name);
12547        }
12548    }
12549
12550    public ComponentName startService(IApplicationThread caller, Intent service,
12551            String resolvedType, int userId) {
12552        enforceNotIsolatedCaller("startService");
12553        // Refuse possible leaked file descriptors
12554        if (service != null && service.hasFileDescriptors() == true) {
12555            throw new IllegalArgumentException("File descriptors passed in Intent");
12556        }
12557
12558        if (DEBUG_SERVICE)
12559            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12560        synchronized(this) {
12561            final int callingPid = Binder.getCallingPid();
12562            final int callingUid = Binder.getCallingUid();
12563            final long origId = Binder.clearCallingIdentity();
12564            ComponentName res = mServices.startServiceLocked(caller, service,
12565                    resolvedType, callingPid, callingUid, userId);
12566            Binder.restoreCallingIdentity(origId);
12567            return res;
12568        }
12569    }
12570
12571    ComponentName startServiceInPackage(int uid,
12572            Intent service, String resolvedType, int userId) {
12573        synchronized(this) {
12574            if (DEBUG_SERVICE)
12575                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12576            final long origId = Binder.clearCallingIdentity();
12577            ComponentName res = mServices.startServiceLocked(null, service,
12578                    resolvedType, -1, uid, userId);
12579            Binder.restoreCallingIdentity(origId);
12580            return res;
12581        }
12582    }
12583
12584    public int stopService(IApplicationThread caller, Intent service,
12585            String resolvedType, int userId) {
12586        enforceNotIsolatedCaller("stopService");
12587        // Refuse possible leaked file descriptors
12588        if (service != null && service.hasFileDescriptors() == true) {
12589            throw new IllegalArgumentException("File descriptors passed in Intent");
12590        }
12591
12592        synchronized(this) {
12593            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12594        }
12595    }
12596
12597    public IBinder peekService(Intent service, String resolvedType) {
12598        enforceNotIsolatedCaller("peekService");
12599        // Refuse possible leaked file descriptors
12600        if (service != null && service.hasFileDescriptors() == true) {
12601            throw new IllegalArgumentException("File descriptors passed in Intent");
12602        }
12603        synchronized(this) {
12604            return mServices.peekServiceLocked(service, resolvedType);
12605        }
12606    }
12607
12608    public boolean stopServiceToken(ComponentName className, IBinder token,
12609            int startId) {
12610        synchronized(this) {
12611            return mServices.stopServiceTokenLocked(className, token, startId);
12612        }
12613    }
12614
12615    public void setServiceForeground(ComponentName className, IBinder token,
12616            int id, Notification notification, boolean removeNotification) {
12617        synchronized(this) {
12618            mServices.setServiceForegroundLocked(className, token, id, notification,
12619                    removeNotification);
12620        }
12621    }
12622
12623    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12624            boolean requireFull, String name, String callerPackage) {
12625        final int callingUserId = UserHandle.getUserId(callingUid);
12626        if (callingUserId != userId) {
12627            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12628                if ((requireFull || checkComponentPermission(
12629                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12630                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12631                        && checkComponentPermission(
12632                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12633                                callingPid, callingUid, -1, true)
12634                                != PackageManager.PERMISSION_GRANTED) {
12635                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12636                        // In this case, they would like to just execute as their
12637                        // owner user instead of failing.
12638                        userId = callingUserId;
12639                    } else {
12640                        StringBuilder builder = new StringBuilder(128);
12641                        builder.append("Permission Denial: ");
12642                        builder.append(name);
12643                        if (callerPackage != null) {
12644                            builder.append(" from ");
12645                            builder.append(callerPackage);
12646                        }
12647                        builder.append(" asks to run as user ");
12648                        builder.append(userId);
12649                        builder.append(" but is calling from user ");
12650                        builder.append(UserHandle.getUserId(callingUid));
12651                        builder.append("; this requires ");
12652                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12653                        if (!requireFull) {
12654                            builder.append(" or ");
12655                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12656                        }
12657                        String msg = builder.toString();
12658                        Slog.w(TAG, msg);
12659                        throw new SecurityException(msg);
12660                    }
12661                }
12662            }
12663            if (userId == UserHandle.USER_CURRENT
12664                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12665                // Note that we may be accessing this outside of a lock...
12666                // shouldn't be a big deal, if this is being called outside
12667                // of a locked context there is intrinsically a race with
12668                // the value the caller will receive and someone else changing it.
12669                userId = mCurrentUserId;
12670            }
12671            if (!allowAll && userId < 0) {
12672                throw new IllegalArgumentException(
12673                        "Call does not support special user #" + userId);
12674            }
12675        }
12676        return userId;
12677    }
12678
12679    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12680            String className, int flags) {
12681        boolean result = false;
12682        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12683            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12684                if (ActivityManager.checkUidPermission(
12685                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12686                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12687                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12688                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12689                            + " requests FLAG_SINGLE_USER, but app does not hold "
12690                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12691                    Slog.w(TAG, msg);
12692                    throw new SecurityException(msg);
12693                }
12694                result = true;
12695            }
12696        } else if (componentProcessName == aInfo.packageName) {
12697            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12698        } else if ("system".equals(componentProcessName)) {
12699            result = true;
12700        }
12701        if (DEBUG_MU) {
12702            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12703                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12704        }
12705        return result;
12706    }
12707
12708    public int bindService(IApplicationThread caller, IBinder token,
12709            Intent service, String resolvedType,
12710            IServiceConnection connection, int flags, int userId) {
12711        enforceNotIsolatedCaller("bindService");
12712        // Refuse possible leaked file descriptors
12713        if (service != null && service.hasFileDescriptors() == true) {
12714            throw new IllegalArgumentException("File descriptors passed in Intent");
12715        }
12716
12717        synchronized(this) {
12718            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12719                    connection, flags, userId);
12720        }
12721    }
12722
12723    public boolean unbindService(IServiceConnection connection) {
12724        synchronized (this) {
12725            return mServices.unbindServiceLocked(connection);
12726        }
12727    }
12728
12729    public void publishService(IBinder token, Intent intent, IBinder service) {
12730        // Refuse possible leaked file descriptors
12731        if (intent != null && intent.hasFileDescriptors() == true) {
12732            throw new IllegalArgumentException("File descriptors passed in Intent");
12733        }
12734
12735        synchronized(this) {
12736            if (!(token instanceof ServiceRecord)) {
12737                throw new IllegalArgumentException("Invalid service token");
12738            }
12739            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12740        }
12741    }
12742
12743    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12744        // Refuse possible leaked file descriptors
12745        if (intent != null && intent.hasFileDescriptors() == true) {
12746            throw new IllegalArgumentException("File descriptors passed in Intent");
12747        }
12748
12749        synchronized(this) {
12750            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12751        }
12752    }
12753
12754    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12755        synchronized(this) {
12756            if (!(token instanceof ServiceRecord)) {
12757                throw new IllegalArgumentException("Invalid service token");
12758            }
12759            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12760        }
12761    }
12762
12763    // =========================================================
12764    // BACKUP AND RESTORE
12765    // =========================================================
12766
12767    // Cause the target app to be launched if necessary and its backup agent
12768    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12769    // activity manager to announce its creation.
12770    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12771        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12772        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12773
12774        synchronized(this) {
12775            // !!! TODO: currently no check here that we're already bound
12776            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12777            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12778            synchronized (stats) {
12779                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12780            }
12781
12782            // Backup agent is now in use, its package can't be stopped.
12783            try {
12784                AppGlobals.getPackageManager().setPackageStoppedState(
12785                        app.packageName, false, UserHandle.getUserId(app.uid));
12786            } catch (RemoteException e) {
12787            } catch (IllegalArgumentException e) {
12788                Slog.w(TAG, "Failed trying to unstop package "
12789                        + app.packageName + ": " + e);
12790            }
12791
12792            BackupRecord r = new BackupRecord(ss, app, backupMode);
12793            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12794                    ? new ComponentName(app.packageName, app.backupAgentName)
12795                    : new ComponentName("android", "FullBackupAgent");
12796            // startProcessLocked() returns existing proc's record if it's already running
12797            ProcessRecord proc = startProcessLocked(app.processName, app,
12798                    false, 0, "backup", hostingName, false, false, false);
12799            if (proc == null) {
12800                Slog.e(TAG, "Unable to start backup agent process " + r);
12801                return false;
12802            }
12803
12804            r.app = proc;
12805            mBackupTarget = r;
12806            mBackupAppName = app.packageName;
12807
12808            // Try not to kill the process during backup
12809            updateOomAdjLocked(proc);
12810
12811            // If the process is already attached, schedule the creation of the backup agent now.
12812            // If it is not yet live, this will be done when it attaches to the framework.
12813            if (proc.thread != null) {
12814                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12815                try {
12816                    proc.thread.scheduleCreateBackupAgent(app,
12817                            compatibilityInfoForPackageLocked(app), backupMode);
12818                } catch (RemoteException e) {
12819                    // Will time out on the backup manager side
12820                }
12821            } else {
12822                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12823            }
12824            // Invariants: at this point, the target app process exists and the application
12825            // is either already running or in the process of coming up.  mBackupTarget and
12826            // mBackupAppName describe the app, so that when it binds back to the AM we
12827            // know that it's scheduled for a backup-agent operation.
12828        }
12829
12830        return true;
12831    }
12832
12833    @Override
12834    public void clearPendingBackup() {
12835        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12836        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12837
12838        synchronized (this) {
12839            mBackupTarget = null;
12840            mBackupAppName = null;
12841        }
12842    }
12843
12844    // A backup agent has just come up
12845    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12846        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12847                + " = " + agent);
12848
12849        synchronized(this) {
12850            if (!agentPackageName.equals(mBackupAppName)) {
12851                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12852                return;
12853            }
12854        }
12855
12856        long oldIdent = Binder.clearCallingIdentity();
12857        try {
12858            IBackupManager bm = IBackupManager.Stub.asInterface(
12859                    ServiceManager.getService(Context.BACKUP_SERVICE));
12860            bm.agentConnected(agentPackageName, agent);
12861        } catch (RemoteException e) {
12862            // can't happen; the backup manager service is local
12863        } catch (Exception e) {
12864            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12865            e.printStackTrace();
12866        } finally {
12867            Binder.restoreCallingIdentity(oldIdent);
12868        }
12869    }
12870
12871    // done with this agent
12872    public void unbindBackupAgent(ApplicationInfo appInfo) {
12873        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12874        if (appInfo == null) {
12875            Slog.w(TAG, "unbind backup agent for null app");
12876            return;
12877        }
12878
12879        synchronized(this) {
12880            try {
12881                if (mBackupAppName == null) {
12882                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12883                    return;
12884                }
12885
12886                if (!mBackupAppName.equals(appInfo.packageName)) {
12887                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12888                    return;
12889                }
12890
12891                // Not backing this app up any more; reset its OOM adjustment
12892                final ProcessRecord proc = mBackupTarget.app;
12893                updateOomAdjLocked(proc);
12894
12895                // If the app crashed during backup, 'thread' will be null here
12896                if (proc.thread != null) {
12897                    try {
12898                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12899                                compatibilityInfoForPackageLocked(appInfo));
12900                    } catch (Exception e) {
12901                        Slog.e(TAG, "Exception when unbinding backup agent:");
12902                        e.printStackTrace();
12903                    }
12904                }
12905            } finally {
12906                mBackupTarget = null;
12907                mBackupAppName = null;
12908            }
12909        }
12910    }
12911    // =========================================================
12912    // BROADCASTS
12913    // =========================================================
12914
12915    private final List getStickiesLocked(String action, IntentFilter filter,
12916            List cur, int userId) {
12917        final ContentResolver resolver = mContext.getContentResolver();
12918        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12919        if (stickies == null) {
12920            return cur;
12921        }
12922        final ArrayList<Intent> list = stickies.get(action);
12923        if (list == null) {
12924            return cur;
12925        }
12926        int N = list.size();
12927        for (int i=0; i<N; i++) {
12928            Intent intent = list.get(i);
12929            if (filter.match(resolver, intent, true, TAG) >= 0) {
12930                if (cur == null) {
12931                    cur = new ArrayList<Intent>();
12932                }
12933                cur.add(intent);
12934            }
12935        }
12936        return cur;
12937    }
12938
12939    boolean isPendingBroadcastProcessLocked(int pid) {
12940        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12941                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12942    }
12943
12944    void skipPendingBroadcastLocked(int pid) {
12945            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12946            for (BroadcastQueue queue : mBroadcastQueues) {
12947                queue.skipPendingBroadcastLocked(pid);
12948            }
12949    }
12950
12951    // The app just attached; send any pending broadcasts that it should receive
12952    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12953        boolean didSomething = false;
12954        for (BroadcastQueue queue : mBroadcastQueues) {
12955            didSomething |= queue.sendPendingBroadcastsLocked(app);
12956        }
12957        return didSomething;
12958    }
12959
12960    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12961            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12962        enforceNotIsolatedCaller("registerReceiver");
12963        int callingUid;
12964        int callingPid;
12965        synchronized(this) {
12966            ProcessRecord callerApp = null;
12967            if (caller != null) {
12968                callerApp = getRecordForAppLocked(caller);
12969                if (callerApp == null) {
12970                    throw new SecurityException(
12971                            "Unable to find app for caller " + caller
12972                            + " (pid=" + Binder.getCallingPid()
12973                            + ") when registering receiver " + receiver);
12974                }
12975                if (callerApp.info.uid != Process.SYSTEM_UID &&
12976                        !callerApp.pkgList.containsKey(callerPackage) &&
12977                        !"android".equals(callerPackage)) {
12978                    throw new SecurityException("Given caller package " + callerPackage
12979                            + " is not running in process " + callerApp);
12980                }
12981                callingUid = callerApp.info.uid;
12982                callingPid = callerApp.pid;
12983            } else {
12984                callerPackage = null;
12985                callingUid = Binder.getCallingUid();
12986                callingPid = Binder.getCallingPid();
12987            }
12988
12989            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12990                    true, true, "registerReceiver", callerPackage);
12991
12992            List allSticky = null;
12993
12994            // Look for any matching sticky broadcasts...
12995            Iterator actions = filter.actionsIterator();
12996            if (actions != null) {
12997                while (actions.hasNext()) {
12998                    String action = (String)actions.next();
12999                    allSticky = getStickiesLocked(action, filter, allSticky,
13000                            UserHandle.USER_ALL);
13001                    allSticky = getStickiesLocked(action, filter, allSticky,
13002                            UserHandle.getUserId(callingUid));
13003                }
13004            } else {
13005                allSticky = getStickiesLocked(null, filter, allSticky,
13006                        UserHandle.USER_ALL);
13007                allSticky = getStickiesLocked(null, filter, allSticky,
13008                        UserHandle.getUserId(callingUid));
13009            }
13010
13011            // The first sticky in the list is returned directly back to
13012            // the client.
13013            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13014
13015            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13016                    + ": " + sticky);
13017
13018            if (receiver == null) {
13019                return sticky;
13020            }
13021
13022            ReceiverList rl
13023                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13024            if (rl == null) {
13025                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13026                        userId, receiver);
13027                if (rl.app != null) {
13028                    rl.app.receivers.add(rl);
13029                } else {
13030                    try {
13031                        receiver.asBinder().linkToDeath(rl, 0);
13032                    } catch (RemoteException e) {
13033                        return sticky;
13034                    }
13035                    rl.linkedToDeath = true;
13036                }
13037                mRegisteredReceivers.put(receiver.asBinder(), rl);
13038            } else if (rl.uid != callingUid) {
13039                throw new IllegalArgumentException(
13040                        "Receiver requested to register for uid " + callingUid
13041                        + " was previously registered for uid " + rl.uid);
13042            } else if (rl.pid != callingPid) {
13043                throw new IllegalArgumentException(
13044                        "Receiver requested to register for pid " + callingPid
13045                        + " was previously registered for pid " + rl.pid);
13046            } else if (rl.userId != userId) {
13047                throw new IllegalArgumentException(
13048                        "Receiver requested to register for user " + userId
13049                        + " was previously registered for user " + rl.userId);
13050            }
13051            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13052                    permission, callingUid, userId);
13053            rl.add(bf);
13054            if (!bf.debugCheck()) {
13055                Slog.w(TAG, "==> For Dynamic broadast");
13056            }
13057            mReceiverResolver.addFilter(bf);
13058
13059            // Enqueue broadcasts for all existing stickies that match
13060            // this filter.
13061            if (allSticky != null) {
13062                ArrayList receivers = new ArrayList();
13063                receivers.add(bf);
13064
13065                int N = allSticky.size();
13066                for (int i=0; i<N; i++) {
13067                    Intent intent = (Intent)allSticky.get(i);
13068                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13069                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13070                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13071                            null, null, false, true, true, -1);
13072                    queue.enqueueParallelBroadcastLocked(r);
13073                    queue.scheduleBroadcastsLocked();
13074                }
13075            }
13076
13077            return sticky;
13078        }
13079    }
13080
13081    public void unregisterReceiver(IIntentReceiver receiver) {
13082        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13083
13084        final long origId = Binder.clearCallingIdentity();
13085        try {
13086            boolean doTrim = false;
13087
13088            synchronized(this) {
13089                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13090                if (rl != null) {
13091                    if (rl.curBroadcast != null) {
13092                        BroadcastRecord r = rl.curBroadcast;
13093                        final boolean doNext = finishReceiverLocked(
13094                                receiver.asBinder(), r.resultCode, r.resultData,
13095                                r.resultExtras, r.resultAbort);
13096                        if (doNext) {
13097                            doTrim = true;
13098                            r.queue.processNextBroadcast(false);
13099                        }
13100                    }
13101
13102                    if (rl.app != null) {
13103                        rl.app.receivers.remove(rl);
13104                    }
13105                    removeReceiverLocked(rl);
13106                    if (rl.linkedToDeath) {
13107                        rl.linkedToDeath = false;
13108                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13109                    }
13110                }
13111            }
13112
13113            // If we actually concluded any broadcasts, we might now be able
13114            // to trim the recipients' apps from our working set
13115            if (doTrim) {
13116                trimApplications();
13117                return;
13118            }
13119
13120        } finally {
13121            Binder.restoreCallingIdentity(origId);
13122        }
13123    }
13124
13125    void removeReceiverLocked(ReceiverList rl) {
13126        mRegisteredReceivers.remove(rl.receiver.asBinder());
13127        int N = rl.size();
13128        for (int i=0; i<N; i++) {
13129            mReceiverResolver.removeFilter(rl.get(i));
13130        }
13131    }
13132
13133    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13134        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13135            ProcessRecord r = mLruProcesses.get(i);
13136            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13137                try {
13138                    r.thread.dispatchPackageBroadcast(cmd, packages);
13139                } catch (RemoteException ex) {
13140                }
13141            }
13142        }
13143    }
13144
13145    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13146            int[] users) {
13147        List<ResolveInfo> receivers = null;
13148        try {
13149            HashSet<ComponentName> singleUserReceivers = null;
13150            boolean scannedFirstReceivers = false;
13151            for (int user : users) {
13152                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13153                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13154                if (user != 0 && newReceivers != null) {
13155                    // If this is not the primary user, we need to check for
13156                    // any receivers that should be filtered out.
13157                    for (int i=0; i<newReceivers.size(); i++) {
13158                        ResolveInfo ri = newReceivers.get(i);
13159                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13160                            newReceivers.remove(i);
13161                            i--;
13162                        }
13163                    }
13164                }
13165                if (newReceivers != null && newReceivers.size() == 0) {
13166                    newReceivers = null;
13167                }
13168                if (receivers == null) {
13169                    receivers = newReceivers;
13170                } else if (newReceivers != null) {
13171                    // We need to concatenate the additional receivers
13172                    // found with what we have do far.  This would be easy,
13173                    // but we also need to de-dup any receivers that are
13174                    // singleUser.
13175                    if (!scannedFirstReceivers) {
13176                        // Collect any single user receivers we had already retrieved.
13177                        scannedFirstReceivers = true;
13178                        for (int i=0; i<receivers.size(); i++) {
13179                            ResolveInfo ri = receivers.get(i);
13180                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13181                                ComponentName cn = new ComponentName(
13182                                        ri.activityInfo.packageName, ri.activityInfo.name);
13183                                if (singleUserReceivers == null) {
13184                                    singleUserReceivers = new HashSet<ComponentName>();
13185                                }
13186                                singleUserReceivers.add(cn);
13187                            }
13188                        }
13189                    }
13190                    // Add the new results to the existing results, tracking
13191                    // and de-dupping single user receivers.
13192                    for (int i=0; i<newReceivers.size(); i++) {
13193                        ResolveInfo ri = newReceivers.get(i);
13194                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13195                            ComponentName cn = new ComponentName(
13196                                    ri.activityInfo.packageName, ri.activityInfo.name);
13197                            if (singleUserReceivers == null) {
13198                                singleUserReceivers = new HashSet<ComponentName>();
13199                            }
13200                            if (!singleUserReceivers.contains(cn)) {
13201                                singleUserReceivers.add(cn);
13202                                receivers.add(ri);
13203                            }
13204                        } else {
13205                            receivers.add(ri);
13206                        }
13207                    }
13208                }
13209            }
13210        } catch (RemoteException ex) {
13211            // pm is in same process, this will never happen.
13212        }
13213        return receivers;
13214    }
13215
13216    private final int broadcastIntentLocked(ProcessRecord callerApp,
13217            String callerPackage, Intent intent, String resolvedType,
13218            IIntentReceiver resultTo, int resultCode, String resultData,
13219            Bundle map, String requiredPermission, int appOp,
13220            boolean ordered, boolean sticky, int callingPid, int callingUid,
13221            int userId) {
13222        intent = new Intent(intent);
13223
13224        // By default broadcasts do not go to stopped apps.
13225        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13226
13227        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13228            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13229            + " ordered=" + ordered + " userid=" + userId);
13230        if ((resultTo != null) && !ordered) {
13231            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13232        }
13233
13234        userId = handleIncomingUser(callingPid, callingUid, userId,
13235                true, false, "broadcast", callerPackage);
13236
13237        // Make sure that the user who is receiving this broadcast is started.
13238        // If not, we will just skip it.
13239        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13240            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13241                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13242                Slog.w(TAG, "Skipping broadcast of " + intent
13243                        + ": user " + userId + " is stopped");
13244                return ActivityManager.BROADCAST_SUCCESS;
13245            }
13246        }
13247
13248        /*
13249         * Prevent non-system code (defined here to be non-persistent
13250         * processes) from sending protected broadcasts.
13251         */
13252        int callingAppId = UserHandle.getAppId(callingUid);
13253        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13254            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13255            callingUid == 0) {
13256            // Always okay.
13257        } else if (callerApp == null || !callerApp.persistent) {
13258            try {
13259                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13260                        intent.getAction())) {
13261                    String msg = "Permission Denial: not allowed to send broadcast "
13262                            + intent.getAction() + " from pid="
13263                            + callingPid + ", uid=" + callingUid;
13264                    Slog.w(TAG, msg);
13265                    throw new SecurityException(msg);
13266                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13267                    // Special case for compatibility: we don't want apps to send this,
13268                    // but historically it has not been protected and apps may be using it
13269                    // to poke their own app widget.  So, instead of making it protected,
13270                    // just limit it to the caller.
13271                    if (callerApp == null) {
13272                        String msg = "Permission Denial: not allowed to send broadcast "
13273                                + intent.getAction() + " from unknown caller.";
13274                        Slog.w(TAG, msg);
13275                        throw new SecurityException(msg);
13276                    } else if (intent.getComponent() != null) {
13277                        // They are good enough to send to an explicit component...  verify
13278                        // it is being sent to the calling app.
13279                        if (!intent.getComponent().getPackageName().equals(
13280                                callerApp.info.packageName)) {
13281                            String msg = "Permission Denial: not allowed to send broadcast "
13282                                    + intent.getAction() + " to "
13283                                    + intent.getComponent().getPackageName() + " from "
13284                                    + callerApp.info.packageName;
13285                            Slog.w(TAG, msg);
13286                            throw new SecurityException(msg);
13287                        }
13288                    } else {
13289                        // Limit broadcast to their own package.
13290                        intent.setPackage(callerApp.info.packageName);
13291                    }
13292                }
13293            } catch (RemoteException e) {
13294                Slog.w(TAG, "Remote exception", e);
13295                return ActivityManager.BROADCAST_SUCCESS;
13296            }
13297        }
13298
13299        // Handle special intents: if this broadcast is from the package
13300        // manager about a package being removed, we need to remove all of
13301        // its activities from the history stack.
13302        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13303                intent.getAction());
13304        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13305                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13306                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13307                || uidRemoved) {
13308            if (checkComponentPermission(
13309                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13310                    callingPid, callingUid, -1, true)
13311                    == PackageManager.PERMISSION_GRANTED) {
13312                if (uidRemoved) {
13313                    final Bundle intentExtras = intent.getExtras();
13314                    final int uid = intentExtras != null
13315                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13316                    if (uid >= 0) {
13317                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13318                        synchronized (bs) {
13319                            bs.removeUidStatsLocked(uid);
13320                        }
13321                        mAppOpsService.uidRemoved(uid);
13322                    }
13323                } else {
13324                    // If resources are unavailable just force stop all
13325                    // those packages and flush the attribute cache as well.
13326                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13327                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13328                        if (list != null && (list.length > 0)) {
13329                            for (String pkg : list) {
13330                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13331                                        "storage unmount");
13332                            }
13333                            sendPackageBroadcastLocked(
13334                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13335                        }
13336                    } else {
13337                        Uri data = intent.getData();
13338                        String ssp;
13339                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13340                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13341                                    intent.getAction());
13342                            boolean fullUninstall = removed &&
13343                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13344                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13345                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13346                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13347                                        false, fullUninstall, userId,
13348                                        removed ? "pkg removed" : "pkg changed");
13349                            }
13350                            if (removed) {
13351                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13352                                        new String[] {ssp}, userId);
13353                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13354                                    mAppOpsService.packageRemoved(
13355                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13356
13357                                    // Remove all permissions granted from/to this package
13358                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13359                                }
13360                            }
13361                        }
13362                    }
13363                }
13364            } else {
13365                String msg = "Permission Denial: " + intent.getAction()
13366                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13367                        + ", uid=" + callingUid + ")"
13368                        + " requires "
13369                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13370                Slog.w(TAG, msg);
13371                throw new SecurityException(msg);
13372            }
13373
13374        // Special case for adding a package: by default turn on compatibility
13375        // mode.
13376        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13377            Uri data = intent.getData();
13378            String ssp;
13379            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13380                mCompatModePackages.handlePackageAddedLocked(ssp,
13381                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13382            }
13383        }
13384
13385        /*
13386         * If this is the time zone changed action, queue up a message that will reset the timezone
13387         * of all currently running processes. This message will get queued up before the broadcast
13388         * happens.
13389         */
13390        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13391            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13392        }
13393
13394        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13395            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13396        }
13397
13398        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13399            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13400            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13401        }
13402
13403        // Add to the sticky list if requested.
13404        if (sticky) {
13405            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13406                    callingPid, callingUid)
13407                    != PackageManager.PERMISSION_GRANTED) {
13408                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13409                        + callingPid + ", uid=" + callingUid
13410                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13411                Slog.w(TAG, msg);
13412                throw new SecurityException(msg);
13413            }
13414            if (requiredPermission != null) {
13415                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13416                        + " and enforce permission " + requiredPermission);
13417                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13418            }
13419            if (intent.getComponent() != null) {
13420                throw new SecurityException(
13421                        "Sticky broadcasts can't target a specific component");
13422            }
13423            // We use userId directly here, since the "all" target is maintained
13424            // as a separate set of sticky broadcasts.
13425            if (userId != UserHandle.USER_ALL) {
13426                // But first, if this is not a broadcast to all users, then
13427                // make sure it doesn't conflict with an existing broadcast to
13428                // all users.
13429                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13430                        UserHandle.USER_ALL);
13431                if (stickies != null) {
13432                    ArrayList<Intent> list = stickies.get(intent.getAction());
13433                    if (list != null) {
13434                        int N = list.size();
13435                        int i;
13436                        for (i=0; i<N; i++) {
13437                            if (intent.filterEquals(list.get(i))) {
13438                                throw new IllegalArgumentException(
13439                                        "Sticky broadcast " + intent + " for user "
13440                                        + userId + " conflicts with existing global broadcast");
13441                            }
13442                        }
13443                    }
13444                }
13445            }
13446            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13447            if (stickies == null) {
13448                stickies = new ArrayMap<String, ArrayList<Intent>>();
13449                mStickyBroadcasts.put(userId, stickies);
13450            }
13451            ArrayList<Intent> list = stickies.get(intent.getAction());
13452            if (list == null) {
13453                list = new ArrayList<Intent>();
13454                stickies.put(intent.getAction(), list);
13455            }
13456            int N = list.size();
13457            int i;
13458            for (i=0; i<N; i++) {
13459                if (intent.filterEquals(list.get(i))) {
13460                    // This sticky already exists, replace it.
13461                    list.set(i, new Intent(intent));
13462                    break;
13463                }
13464            }
13465            if (i >= N) {
13466                list.add(new Intent(intent));
13467            }
13468        }
13469
13470        int[] users;
13471        if (userId == UserHandle.USER_ALL) {
13472            // Caller wants broadcast to go to all started users.
13473            users = mStartedUserArray;
13474        } else {
13475            // Caller wants broadcast to go to one specific user.
13476            users = new int[] {userId};
13477        }
13478
13479        // Figure out who all will receive this broadcast.
13480        List receivers = null;
13481        List<BroadcastFilter> registeredReceivers = null;
13482        // Need to resolve the intent to interested receivers...
13483        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13484                 == 0) {
13485            receivers = collectReceiverComponents(intent, resolvedType, users);
13486        }
13487        if (intent.getComponent() == null) {
13488            registeredReceivers = mReceiverResolver.queryIntent(intent,
13489                    resolvedType, false, userId);
13490        }
13491
13492        final boolean replacePending =
13493                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13494
13495        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13496                + " replacePending=" + replacePending);
13497
13498        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13499        if (!ordered && NR > 0) {
13500            // If we are not serializing this broadcast, then send the
13501            // registered receivers separately so they don't wait for the
13502            // components to be launched.
13503            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13504            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13505                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13506                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13507                    ordered, sticky, false, userId);
13508            if (DEBUG_BROADCAST) Slog.v(
13509                    TAG, "Enqueueing parallel broadcast " + r);
13510            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13511            if (!replaced) {
13512                queue.enqueueParallelBroadcastLocked(r);
13513                queue.scheduleBroadcastsLocked();
13514            }
13515            registeredReceivers = null;
13516            NR = 0;
13517        }
13518
13519        // Merge into one list.
13520        int ir = 0;
13521        if (receivers != null) {
13522            // A special case for PACKAGE_ADDED: do not allow the package
13523            // being added to see this broadcast.  This prevents them from
13524            // using this as a back door to get run as soon as they are
13525            // installed.  Maybe in the future we want to have a special install
13526            // broadcast or such for apps, but we'd like to deliberately make
13527            // this decision.
13528            String skipPackages[] = null;
13529            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13530                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13531                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13532                Uri data = intent.getData();
13533                if (data != null) {
13534                    String pkgName = data.getSchemeSpecificPart();
13535                    if (pkgName != null) {
13536                        skipPackages = new String[] { pkgName };
13537                    }
13538                }
13539            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13540                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13541            }
13542            if (skipPackages != null && (skipPackages.length > 0)) {
13543                for (String skipPackage : skipPackages) {
13544                    if (skipPackage != null) {
13545                        int NT = receivers.size();
13546                        for (int it=0; it<NT; it++) {
13547                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13548                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13549                                receivers.remove(it);
13550                                it--;
13551                                NT--;
13552                            }
13553                        }
13554                    }
13555                }
13556            }
13557
13558            int NT = receivers != null ? receivers.size() : 0;
13559            int it = 0;
13560            ResolveInfo curt = null;
13561            BroadcastFilter curr = null;
13562            while (it < NT && ir < NR) {
13563                if (curt == null) {
13564                    curt = (ResolveInfo)receivers.get(it);
13565                }
13566                if (curr == null) {
13567                    curr = registeredReceivers.get(ir);
13568                }
13569                if (curr.getPriority() >= curt.priority) {
13570                    // Insert this broadcast record into the final list.
13571                    receivers.add(it, curr);
13572                    ir++;
13573                    curr = null;
13574                    it++;
13575                    NT++;
13576                } else {
13577                    // Skip to the next ResolveInfo in the final list.
13578                    it++;
13579                    curt = null;
13580                }
13581            }
13582        }
13583        while (ir < NR) {
13584            if (receivers == null) {
13585                receivers = new ArrayList();
13586            }
13587            receivers.add(registeredReceivers.get(ir));
13588            ir++;
13589        }
13590
13591        if ((receivers != null && receivers.size() > 0)
13592                || resultTo != null) {
13593            BroadcastQueue queue = broadcastQueueForIntent(intent);
13594            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13595                    callerPackage, callingPid, callingUid, resolvedType,
13596                    requiredPermission, appOp, receivers, resultTo, resultCode,
13597                    resultData, map, ordered, sticky, false, userId);
13598            if (DEBUG_BROADCAST) Slog.v(
13599                    TAG, "Enqueueing ordered broadcast " + r
13600                    + ": prev had " + queue.mOrderedBroadcasts.size());
13601            if (DEBUG_BROADCAST) {
13602                int seq = r.intent.getIntExtra("seq", -1);
13603                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13604            }
13605            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13606            if (!replaced) {
13607                queue.enqueueOrderedBroadcastLocked(r);
13608                queue.scheduleBroadcastsLocked();
13609            }
13610        }
13611
13612        return ActivityManager.BROADCAST_SUCCESS;
13613    }
13614
13615    final Intent verifyBroadcastLocked(Intent intent) {
13616        // Refuse possible leaked file descriptors
13617        if (intent != null && intent.hasFileDescriptors() == true) {
13618            throw new IllegalArgumentException("File descriptors passed in Intent");
13619        }
13620
13621        int flags = intent.getFlags();
13622
13623        if (!mProcessesReady) {
13624            // if the caller really truly claims to know what they're doing, go
13625            // ahead and allow the broadcast without launching any receivers
13626            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13627                intent = new Intent(intent);
13628                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13629            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13630                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13631                        + " before boot completion");
13632                throw new IllegalStateException("Cannot broadcast before boot completed");
13633            }
13634        }
13635
13636        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13637            throw new IllegalArgumentException(
13638                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13639        }
13640
13641        return intent;
13642    }
13643
13644    public final int broadcastIntent(IApplicationThread caller,
13645            Intent intent, String resolvedType, IIntentReceiver resultTo,
13646            int resultCode, String resultData, Bundle map,
13647            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13648        enforceNotIsolatedCaller("broadcastIntent");
13649        synchronized(this) {
13650            intent = verifyBroadcastLocked(intent);
13651
13652            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13653            final int callingPid = Binder.getCallingPid();
13654            final int callingUid = Binder.getCallingUid();
13655            final long origId = Binder.clearCallingIdentity();
13656            int res = broadcastIntentLocked(callerApp,
13657                    callerApp != null ? callerApp.info.packageName : null,
13658                    intent, resolvedType, resultTo,
13659                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13660                    callingPid, callingUid, userId);
13661            Binder.restoreCallingIdentity(origId);
13662            return res;
13663        }
13664    }
13665
13666    int broadcastIntentInPackage(String packageName, int uid,
13667            Intent intent, String resolvedType, IIntentReceiver resultTo,
13668            int resultCode, String resultData, Bundle map,
13669            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13670        synchronized(this) {
13671            intent = verifyBroadcastLocked(intent);
13672
13673            final long origId = Binder.clearCallingIdentity();
13674            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13675                    resultTo, resultCode, resultData, map, requiredPermission,
13676                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13677            Binder.restoreCallingIdentity(origId);
13678            return res;
13679        }
13680    }
13681
13682    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13683        // Refuse possible leaked file descriptors
13684        if (intent != null && intent.hasFileDescriptors() == true) {
13685            throw new IllegalArgumentException("File descriptors passed in Intent");
13686        }
13687
13688        userId = handleIncomingUser(Binder.getCallingPid(),
13689                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13690
13691        synchronized(this) {
13692            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13693                    != PackageManager.PERMISSION_GRANTED) {
13694                String msg = "Permission Denial: unbroadcastIntent() from pid="
13695                        + Binder.getCallingPid()
13696                        + ", uid=" + Binder.getCallingUid()
13697                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13698                Slog.w(TAG, msg);
13699                throw new SecurityException(msg);
13700            }
13701            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13702            if (stickies != null) {
13703                ArrayList<Intent> list = stickies.get(intent.getAction());
13704                if (list != null) {
13705                    int N = list.size();
13706                    int i;
13707                    for (i=0; i<N; i++) {
13708                        if (intent.filterEquals(list.get(i))) {
13709                            list.remove(i);
13710                            break;
13711                        }
13712                    }
13713                    if (list.size() <= 0) {
13714                        stickies.remove(intent.getAction());
13715                    }
13716                }
13717                if (stickies.size() <= 0) {
13718                    mStickyBroadcasts.remove(userId);
13719                }
13720            }
13721        }
13722    }
13723
13724    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13725            String resultData, Bundle resultExtras, boolean resultAbort) {
13726        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13727        if (r == null) {
13728            Slog.w(TAG, "finishReceiver called but not found on queue");
13729            return false;
13730        }
13731
13732        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13733    }
13734
13735    void backgroundServicesFinishedLocked(int userId) {
13736        for (BroadcastQueue queue : mBroadcastQueues) {
13737            queue.backgroundServicesFinishedLocked(userId);
13738        }
13739    }
13740
13741    public void finishReceiver(IBinder who, int resultCode, String resultData,
13742            Bundle resultExtras, boolean resultAbort) {
13743        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13744
13745        // Refuse possible leaked file descriptors
13746        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13747            throw new IllegalArgumentException("File descriptors passed in Bundle");
13748        }
13749
13750        final long origId = Binder.clearCallingIdentity();
13751        try {
13752            boolean doNext = false;
13753            BroadcastRecord r;
13754
13755            synchronized(this) {
13756                r = broadcastRecordForReceiverLocked(who);
13757                if (r != null) {
13758                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13759                        resultData, resultExtras, resultAbort, true);
13760                }
13761            }
13762
13763            if (doNext) {
13764                r.queue.processNextBroadcast(false);
13765            }
13766            trimApplications();
13767        } finally {
13768            Binder.restoreCallingIdentity(origId);
13769        }
13770    }
13771
13772    // =========================================================
13773    // INSTRUMENTATION
13774    // =========================================================
13775
13776    public boolean startInstrumentation(ComponentName className,
13777            String profileFile, int flags, Bundle arguments,
13778            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13779            int userId) {
13780        enforceNotIsolatedCaller("startInstrumentation");
13781        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13782                userId, false, true, "startInstrumentation", null);
13783        // Refuse possible leaked file descriptors
13784        if (arguments != null && arguments.hasFileDescriptors()) {
13785            throw new IllegalArgumentException("File descriptors passed in Bundle");
13786        }
13787
13788        synchronized(this) {
13789            InstrumentationInfo ii = null;
13790            ApplicationInfo ai = null;
13791            try {
13792                ii = mContext.getPackageManager().getInstrumentationInfo(
13793                    className, STOCK_PM_FLAGS);
13794                ai = AppGlobals.getPackageManager().getApplicationInfo(
13795                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13796            } catch (PackageManager.NameNotFoundException e) {
13797            } catch (RemoteException e) {
13798            }
13799            if (ii == null) {
13800                reportStartInstrumentationFailure(watcher, className,
13801                        "Unable to find instrumentation info for: " + className);
13802                return false;
13803            }
13804            if (ai == null) {
13805                reportStartInstrumentationFailure(watcher, className,
13806                        "Unable to find instrumentation target package: " + ii.targetPackage);
13807                return false;
13808            }
13809
13810            int match = mContext.getPackageManager().checkSignatures(
13811                    ii.targetPackage, ii.packageName);
13812            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13813                String msg = "Permission Denial: starting instrumentation "
13814                        + className + " from pid="
13815                        + Binder.getCallingPid()
13816                        + ", uid=" + Binder.getCallingPid()
13817                        + " not allowed because package " + ii.packageName
13818                        + " does not have a signature matching the target "
13819                        + ii.targetPackage;
13820                reportStartInstrumentationFailure(watcher, className, msg);
13821                throw new SecurityException(msg);
13822            }
13823
13824            final long origId = Binder.clearCallingIdentity();
13825            // Instrumentation can kill and relaunch even persistent processes
13826            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
13827                    "start instr");
13828            ProcessRecord app = addAppLocked(ai, false);
13829            app.instrumentationClass = className;
13830            app.instrumentationInfo = ai;
13831            app.instrumentationProfileFile = profileFile;
13832            app.instrumentationArguments = arguments;
13833            app.instrumentationWatcher = watcher;
13834            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13835            app.instrumentationResultClass = className;
13836            Binder.restoreCallingIdentity(origId);
13837        }
13838
13839        return true;
13840    }
13841
13842    /**
13843     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13844     * error to the logs, but if somebody is watching, send the report there too.  This enables
13845     * the "am" command to report errors with more information.
13846     *
13847     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13848     * @param cn The component name of the instrumentation.
13849     * @param report The error report.
13850     */
13851    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13852            ComponentName cn, String report) {
13853        Slog.w(TAG, report);
13854        try {
13855            if (watcher != null) {
13856                Bundle results = new Bundle();
13857                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13858                results.putString("Error", report);
13859                watcher.instrumentationStatus(cn, -1, results);
13860            }
13861        } catch (RemoteException e) {
13862            Slog.w(TAG, e);
13863        }
13864    }
13865
13866    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13867        if (app.instrumentationWatcher != null) {
13868            try {
13869                // NOTE:  IInstrumentationWatcher *must* be oneway here
13870                app.instrumentationWatcher.instrumentationFinished(
13871                    app.instrumentationClass,
13872                    resultCode,
13873                    results);
13874            } catch (RemoteException e) {
13875            }
13876        }
13877        if (app.instrumentationUiAutomationConnection != null) {
13878            try {
13879                app.instrumentationUiAutomationConnection.shutdown();
13880            } catch (RemoteException re) {
13881                /* ignore */
13882            }
13883            // Only a UiAutomation can set this flag and now that
13884            // it is finished we make sure it is reset to its default.
13885            mUserIsMonkey = false;
13886        }
13887        app.instrumentationWatcher = null;
13888        app.instrumentationUiAutomationConnection = null;
13889        app.instrumentationClass = null;
13890        app.instrumentationInfo = null;
13891        app.instrumentationProfileFile = null;
13892        app.instrumentationArguments = null;
13893
13894        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
13895                "finished inst");
13896    }
13897
13898    public void finishInstrumentation(IApplicationThread target,
13899            int resultCode, Bundle results) {
13900        int userId = UserHandle.getCallingUserId();
13901        // Refuse possible leaked file descriptors
13902        if (results != null && results.hasFileDescriptors()) {
13903            throw new IllegalArgumentException("File descriptors passed in Intent");
13904        }
13905
13906        synchronized(this) {
13907            ProcessRecord app = getRecordForAppLocked(target);
13908            if (app == null) {
13909                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13910                return;
13911            }
13912            final long origId = Binder.clearCallingIdentity();
13913            finishInstrumentationLocked(app, resultCode, results);
13914            Binder.restoreCallingIdentity(origId);
13915        }
13916    }
13917
13918    // =========================================================
13919    // CONFIGURATION
13920    // =========================================================
13921
13922    public ConfigurationInfo getDeviceConfigurationInfo() {
13923        ConfigurationInfo config = new ConfigurationInfo();
13924        synchronized (this) {
13925            config.reqTouchScreen = mConfiguration.touchscreen;
13926            config.reqKeyboardType = mConfiguration.keyboard;
13927            config.reqNavigation = mConfiguration.navigation;
13928            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13929                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13930                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13931            }
13932            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13933                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13934                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13935            }
13936            config.reqGlEsVersion = GL_ES_VERSION;
13937        }
13938        return config;
13939    }
13940
13941    ActivityStack getFocusedStack() {
13942        return mStackSupervisor.getFocusedStack();
13943    }
13944
13945    public Configuration getConfiguration() {
13946        Configuration ci;
13947        synchronized(this) {
13948            ci = new Configuration(mConfiguration);
13949        }
13950        return ci;
13951    }
13952
13953    public void updatePersistentConfiguration(Configuration values) {
13954        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13955                "updateConfiguration()");
13956        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13957                "updateConfiguration()");
13958        if (values == null) {
13959            throw new NullPointerException("Configuration must not be null");
13960        }
13961
13962        synchronized(this) {
13963            final long origId = Binder.clearCallingIdentity();
13964            updateConfigurationLocked(values, null, true, false);
13965            Binder.restoreCallingIdentity(origId);
13966        }
13967    }
13968
13969    public void updateConfiguration(Configuration values) {
13970        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13971                "updateConfiguration()");
13972
13973        synchronized(this) {
13974            if (values == null && mWindowManager != null) {
13975                // sentinel: fetch the current configuration from the window manager
13976                values = mWindowManager.computeNewConfiguration();
13977            }
13978
13979            if (mWindowManager != null) {
13980                mProcessList.applyDisplaySize(mWindowManager);
13981            }
13982
13983            final long origId = Binder.clearCallingIdentity();
13984            if (values != null) {
13985                Settings.System.clearConfiguration(values);
13986            }
13987            updateConfigurationLocked(values, null, false, false);
13988            Binder.restoreCallingIdentity(origId);
13989        }
13990    }
13991
13992    /**
13993     * Do either or both things: (1) change the current configuration, and (2)
13994     * make sure the given activity is running with the (now) current
13995     * configuration.  Returns true if the activity has been left running, or
13996     * false if <var>starting</var> is being destroyed to match the new
13997     * configuration.
13998     * @param persistent TODO
13999     */
14000    boolean updateConfigurationLocked(Configuration values,
14001            ActivityRecord starting, boolean persistent, boolean initLocale) {
14002        int changes = 0;
14003
14004        if (values != null) {
14005            Configuration newConfig = new Configuration(mConfiguration);
14006            changes = newConfig.updateFrom(values);
14007            if (changes != 0) {
14008                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14009                    Slog.i(TAG, "Updating configuration to: " + values);
14010                }
14011
14012                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14013
14014                if (values.locale != null && !initLocale) {
14015                    saveLocaleLocked(values.locale,
14016                                     !values.locale.equals(mConfiguration.locale),
14017                                     values.userSetLocale);
14018                }
14019
14020                mConfigurationSeq++;
14021                if (mConfigurationSeq <= 0) {
14022                    mConfigurationSeq = 1;
14023                }
14024                newConfig.seq = mConfigurationSeq;
14025                mConfiguration = newConfig;
14026                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14027
14028                final Configuration configCopy = new Configuration(mConfiguration);
14029
14030                // TODO: If our config changes, should we auto dismiss any currently
14031                // showing dialogs?
14032                mShowDialogs = shouldShowDialogs(newConfig);
14033
14034                AttributeCache ac = AttributeCache.instance();
14035                if (ac != null) {
14036                    ac.updateConfiguration(configCopy);
14037                }
14038
14039                // Make sure all resources in our process are updated
14040                // right now, so that anyone who is going to retrieve
14041                // resource values after we return will be sure to get
14042                // the new ones.  This is especially important during
14043                // boot, where the first config change needs to guarantee
14044                // all resources have that config before following boot
14045                // code is executed.
14046                mSystemThread.applyConfigurationToResources(configCopy);
14047
14048                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14049                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14050                    msg.obj = new Configuration(configCopy);
14051                    mHandler.sendMessage(msg);
14052                }
14053
14054                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14055                    ProcessRecord app = mLruProcesses.get(i);
14056                    try {
14057                        if (app.thread != null) {
14058                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14059                                    + app.processName + " new config " + mConfiguration);
14060                            app.thread.scheduleConfigurationChanged(configCopy);
14061                        }
14062                    } catch (Exception e) {
14063                    }
14064                }
14065                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14066                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14067                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14068                        | Intent.FLAG_RECEIVER_FOREGROUND);
14069                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14070                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14071                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14072                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14073                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14074                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14075                    broadcastIntentLocked(null, null, intent,
14076                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14077                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14078                }
14079            }
14080        }
14081
14082        boolean kept = true;
14083        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14084        // mainStack is null during startup.
14085        if (mainStack != null) {
14086            if (changes != 0 && starting == null) {
14087                // If the configuration changed, and the caller is not already
14088                // in the process of starting an activity, then find the top
14089                // activity to check if its configuration needs to change.
14090                starting = mainStack.topRunningActivityLocked(null);
14091            }
14092
14093            if (starting != null) {
14094                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14095                // And we need to make sure at this point that all other activities
14096                // are made visible with the correct configuration.
14097                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14098            }
14099        }
14100
14101        if (values != null && mWindowManager != null) {
14102            mWindowManager.setNewConfiguration(mConfiguration);
14103        }
14104
14105        return kept;
14106    }
14107
14108    /**
14109     * Decide based on the configuration whether we should shouw the ANR,
14110     * crash, etc dialogs.  The idea is that if there is no affordnace to
14111     * press the on-screen buttons, we shouldn't show the dialog.
14112     *
14113     * A thought: SystemUI might also want to get told about this, the Power
14114     * dialog / global actions also might want different behaviors.
14115     */
14116    private static final boolean shouldShowDialogs(Configuration config) {
14117        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14118                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14119    }
14120
14121    /**
14122     * Save the locale.  You must be inside a synchronized (this) block.
14123     */
14124    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14125        if(isDiff) {
14126            SystemProperties.set("user.language", l.getLanguage());
14127            SystemProperties.set("user.region", l.getCountry());
14128        }
14129
14130        if(isPersist) {
14131            SystemProperties.set("persist.sys.language", l.getLanguage());
14132            SystemProperties.set("persist.sys.country", l.getCountry());
14133            SystemProperties.set("persist.sys.localevar", l.getVariant());
14134        }
14135    }
14136
14137    @Override
14138    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14139        ActivityRecord srec = ActivityRecord.forToken(token);
14140        return srec != null && srec.task.affinity != null &&
14141                srec.task.affinity.equals(destAffinity);
14142    }
14143
14144    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14145            Intent resultData) {
14146
14147        synchronized (this) {
14148            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14149            if (stack != null) {
14150                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14151            }
14152            return false;
14153        }
14154    }
14155
14156    public int getLaunchedFromUid(IBinder activityToken) {
14157        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14158        if (srec == null) {
14159            return -1;
14160        }
14161        return srec.launchedFromUid;
14162    }
14163
14164    public String getLaunchedFromPackage(IBinder activityToken) {
14165        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14166        if (srec == null) {
14167            return null;
14168        }
14169        return srec.launchedFromPackage;
14170    }
14171
14172    // =========================================================
14173    // LIFETIME MANAGEMENT
14174    // =========================================================
14175
14176    // Returns which broadcast queue the app is the current [or imminent] receiver
14177    // on, or 'null' if the app is not an active broadcast recipient.
14178    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14179        BroadcastRecord r = app.curReceiver;
14180        if (r != null) {
14181            return r.queue;
14182        }
14183
14184        // It's not the current receiver, but it might be starting up to become one
14185        synchronized (this) {
14186            for (BroadcastQueue queue : mBroadcastQueues) {
14187                r = queue.mPendingBroadcast;
14188                if (r != null && r.curApp == app) {
14189                    // found it; report which queue it's in
14190                    return queue;
14191                }
14192            }
14193        }
14194
14195        return null;
14196    }
14197
14198    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14199            boolean doingAll, long now) {
14200        if (mAdjSeq == app.adjSeq) {
14201            // This adjustment has already been computed.
14202            return app.curRawAdj;
14203        }
14204
14205        if (app.thread == null) {
14206            app.adjSeq = mAdjSeq;
14207            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14208            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14209            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14210        }
14211
14212        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14213        app.adjSource = null;
14214        app.adjTarget = null;
14215        app.empty = false;
14216        app.cached = false;
14217
14218        final int activitiesSize = app.activities.size();
14219
14220        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14221            // The max adjustment doesn't allow this app to be anything
14222            // below foreground, so it is not worth doing work for it.
14223            app.adjType = "fixed";
14224            app.adjSeq = mAdjSeq;
14225            app.curRawAdj = app.maxAdj;
14226            app.foregroundActivities = false;
14227            app.keeping = true;
14228            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14229            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14230            // System process can do UI, and when they do we want to have
14231            // them trim their memory after the user leaves the UI.  To
14232            // facilitate this, here we need to determine whether or not it
14233            // is currently showing UI.
14234            app.systemNoUi = true;
14235            if (app == TOP_APP) {
14236                app.systemNoUi = false;
14237            } else if (activitiesSize > 0) {
14238                for (int j = 0; j < activitiesSize; j++) {
14239                    final ActivityRecord r = app.activities.get(j);
14240                    if (r.visible) {
14241                        app.systemNoUi = false;
14242                    }
14243                }
14244            }
14245            if (!app.systemNoUi) {
14246                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14247            }
14248            return (app.curAdj=app.maxAdj);
14249        }
14250
14251        app.keeping = false;
14252        app.systemNoUi = false;
14253
14254        // Determine the importance of the process, starting with most
14255        // important to least, and assign an appropriate OOM adjustment.
14256        int adj;
14257        int schedGroup;
14258        int procState;
14259        boolean foregroundActivities = false;
14260        boolean interesting = false;
14261        BroadcastQueue queue;
14262        if (app == TOP_APP) {
14263            // The last app on the list is the foreground app.
14264            adj = ProcessList.FOREGROUND_APP_ADJ;
14265            schedGroup = Process.THREAD_GROUP_DEFAULT;
14266            app.adjType = "top-activity";
14267            foregroundActivities = true;
14268            interesting = true;
14269            procState = ActivityManager.PROCESS_STATE_TOP;
14270        } else if (app.instrumentationClass != null) {
14271            // Don't want to kill running instrumentation.
14272            adj = ProcessList.FOREGROUND_APP_ADJ;
14273            schedGroup = Process.THREAD_GROUP_DEFAULT;
14274            app.adjType = "instrumentation";
14275            interesting = true;
14276            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14277        } else if ((queue = isReceivingBroadcast(app)) != null) {
14278            // An app that is currently receiving a broadcast also
14279            // counts as being in the foreground for OOM killer purposes.
14280            // It's placed in a sched group based on the nature of the
14281            // broadcast as reflected by which queue it's active in.
14282            adj = ProcessList.FOREGROUND_APP_ADJ;
14283            schedGroup = (queue == mFgBroadcastQueue)
14284                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14285            app.adjType = "broadcast";
14286            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14287        } else if (app.executingServices.size() > 0) {
14288            // An app that is currently executing a service callback also
14289            // counts as being in the foreground.
14290            adj = ProcessList.FOREGROUND_APP_ADJ;
14291            schedGroup = app.execServicesFg ?
14292                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14293            app.adjType = "exec-service";
14294            procState = ActivityManager.PROCESS_STATE_SERVICE;
14295            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14296        } else {
14297            // As far as we know the process is empty.  We may change our mind later.
14298            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14299            // At this point we don't actually know the adjustment.  Use the cached adj
14300            // value that the caller wants us to.
14301            adj = cachedAdj;
14302            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14303            app.cached = true;
14304            app.empty = true;
14305            app.adjType = "cch-empty";
14306        }
14307
14308        // Examine all activities if not already foreground.
14309        if (!foregroundActivities && activitiesSize > 0) {
14310            for (int j = 0; j < activitiesSize; j++) {
14311                final ActivityRecord r = app.activities.get(j);
14312                if (r.app != app) {
14313                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14314                            + app + "?!?");
14315                    continue;
14316                }
14317                if (r.visible) {
14318                    // App has a visible activity; only upgrade adjustment.
14319                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14320                        adj = ProcessList.VISIBLE_APP_ADJ;
14321                        app.adjType = "visible";
14322                    }
14323                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14324                        procState = ActivityManager.PROCESS_STATE_TOP;
14325                    }
14326                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14327                    app.cached = false;
14328                    app.empty = false;
14329                    foregroundActivities = true;
14330                    break;
14331                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14332                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14333                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14334                        app.adjType = "pausing";
14335                    }
14336                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14337                        procState = ActivityManager.PROCESS_STATE_TOP;
14338                    }
14339                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14340                    app.cached = false;
14341                    app.empty = false;
14342                    foregroundActivities = true;
14343                } else if (r.state == ActivityState.STOPPING) {
14344                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14345                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14346                        app.adjType = "stopping";
14347                    }
14348                    // For the process state, we will at this point consider the
14349                    // process to be cached.  It will be cached either as an activity
14350                    // or empty depending on whether the activity is finishing.  We do
14351                    // this so that we can treat the process as cached for purposes of
14352                    // memory trimming (determing current memory level, trim command to
14353                    // send to process) since there can be an arbitrary number of stopping
14354                    // processes and they should soon all go into the cached state.
14355                    if (!r.finishing) {
14356                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14357                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14358                        }
14359                    }
14360                    app.cached = false;
14361                    app.empty = false;
14362                    foregroundActivities = true;
14363                } else {
14364                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14365                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14366                        app.adjType = "cch-act";
14367                    }
14368                }
14369            }
14370        }
14371
14372        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14373            if (app.foregroundServices) {
14374                // The user is aware of this app, so make it visible.
14375                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14376                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14377                app.cached = false;
14378                app.adjType = "fg-service";
14379                schedGroup = Process.THREAD_GROUP_DEFAULT;
14380            } else if (app.forcingToForeground != null) {
14381                // The user is aware of this app, so make it visible.
14382                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14383                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14384                app.cached = false;
14385                app.adjType = "force-fg";
14386                app.adjSource = app.forcingToForeground;
14387                schedGroup = Process.THREAD_GROUP_DEFAULT;
14388            }
14389        }
14390
14391        if (app.foregroundServices) {
14392            interesting = true;
14393        }
14394
14395        if (app == mHeavyWeightProcess) {
14396            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14397                // We don't want to kill the current heavy-weight process.
14398                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14399                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14400                app.cached = false;
14401                app.adjType = "heavy";
14402            }
14403            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14404                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14405            }
14406        }
14407
14408        if (app == mHomeProcess) {
14409            if (adj > ProcessList.HOME_APP_ADJ) {
14410                // This process is hosting what we currently consider to be the
14411                // home app, so we don't want to let it go into the background.
14412                adj = ProcessList.HOME_APP_ADJ;
14413                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14414                app.cached = false;
14415                app.adjType = "home";
14416            }
14417            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14418                procState = ActivityManager.PROCESS_STATE_HOME;
14419            }
14420        }
14421
14422        if (app == mPreviousProcess && app.activities.size() > 0) {
14423            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14424                // This was the previous process that showed UI to the user.
14425                // We want to try to keep it around more aggressively, to give
14426                // a good experience around switching between two apps.
14427                adj = ProcessList.PREVIOUS_APP_ADJ;
14428                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14429                app.cached = false;
14430                app.adjType = "previous";
14431            }
14432            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14433                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14434            }
14435        }
14436
14437        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14438                + " reason=" + app.adjType);
14439
14440        // By default, we use the computed adjustment.  It may be changed if
14441        // there are applications dependent on our services or providers, but
14442        // this gives us a baseline and makes sure we don't get into an
14443        // infinite recursion.
14444        app.adjSeq = mAdjSeq;
14445        app.curRawAdj = adj;
14446        app.hasStartedServices = false;
14447
14448        if (mBackupTarget != null && app == mBackupTarget.app) {
14449            // If possible we want to avoid killing apps while they're being backed up
14450            if (adj > ProcessList.BACKUP_APP_ADJ) {
14451                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14452                adj = ProcessList.BACKUP_APP_ADJ;
14453                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14454                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14455                }
14456                app.adjType = "backup";
14457                app.cached = false;
14458            }
14459            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14460                procState = ActivityManager.PROCESS_STATE_BACKUP;
14461            }
14462        }
14463
14464        boolean mayBeTop = false;
14465
14466        for (int is = app.services.size()-1;
14467                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14468                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14469                        || procState > ActivityManager.PROCESS_STATE_TOP);
14470                is--) {
14471            ServiceRecord s = app.services.valueAt(is);
14472            if (s.startRequested) {
14473                app.hasStartedServices = true;
14474                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14475                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14476                }
14477                if (app.hasShownUi && app != mHomeProcess) {
14478                    // If this process has shown some UI, let it immediately
14479                    // go to the LRU list because it may be pretty heavy with
14480                    // UI stuff.  We'll tag it with a label just to help
14481                    // debug and understand what is going on.
14482                    if (adj > ProcessList.SERVICE_ADJ) {
14483                        app.adjType = "cch-started-ui-services";
14484                    }
14485                } else {
14486                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14487                        // This service has seen some activity within
14488                        // recent memory, so we will keep its process ahead
14489                        // of the background processes.
14490                        if (adj > ProcessList.SERVICE_ADJ) {
14491                            adj = ProcessList.SERVICE_ADJ;
14492                            app.adjType = "started-services";
14493                            app.cached = false;
14494                        }
14495                    }
14496                    // If we have let the service slide into the background
14497                    // state, still have some text describing what it is doing
14498                    // even though the service no longer has an impact.
14499                    if (adj > ProcessList.SERVICE_ADJ) {
14500                        app.adjType = "cch-started-services";
14501                    }
14502                }
14503                // Don't kill this process because it is doing work; it
14504                // has said it is doing work.
14505                app.keeping = true;
14506            }
14507            for (int conni = s.connections.size()-1;
14508                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14509                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14510                            || procState > ActivityManager.PROCESS_STATE_TOP);
14511                    conni--) {
14512                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14513                for (int i = 0;
14514                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14515                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14516                                || procState > ActivityManager.PROCESS_STATE_TOP);
14517                        i++) {
14518                    // XXX should compute this based on the max of
14519                    // all connected clients.
14520                    ConnectionRecord cr = clist.get(i);
14521                    if (cr.binding.client == app) {
14522                        // Binding to ourself is not interesting.
14523                        continue;
14524                    }
14525                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14526                        ProcessRecord client = cr.binding.client;
14527                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14528                                TOP_APP, doingAll, now);
14529                        int clientProcState = client.curProcState;
14530                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14531                            // If the other app is cached for any reason, for purposes here
14532                            // we are going to consider it empty.  The specific cached state
14533                            // doesn't propagate except under certain conditions.
14534                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14535                        }
14536                        String adjType = null;
14537                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14538                            // Not doing bind OOM management, so treat
14539                            // this guy more like a started service.
14540                            if (app.hasShownUi && app != mHomeProcess) {
14541                                // If this process has shown some UI, let it immediately
14542                                // go to the LRU list because it may be pretty heavy with
14543                                // UI stuff.  We'll tag it with a label just to help
14544                                // debug and understand what is going on.
14545                                if (adj > clientAdj) {
14546                                    adjType = "cch-bound-ui-services";
14547                                }
14548                                app.cached = false;
14549                                clientAdj = adj;
14550                                clientProcState = procState;
14551                            } else {
14552                                if (now >= (s.lastActivity
14553                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14554                                    // This service has not seen activity within
14555                                    // recent memory, so allow it to drop to the
14556                                    // LRU list if there is no other reason to keep
14557                                    // it around.  We'll also tag it with a label just
14558                                    // to help debug and undertand what is going on.
14559                                    if (adj > clientAdj) {
14560                                        adjType = "cch-bound-services";
14561                                    }
14562                                    clientAdj = adj;
14563                                }
14564                            }
14565                        }
14566                        if (adj > clientAdj) {
14567                            // If this process has recently shown UI, and
14568                            // the process that is binding to it is less
14569                            // important than being visible, then we don't
14570                            // care about the binding as much as we care
14571                            // about letting this process get into the LRU
14572                            // list to be killed and restarted if needed for
14573                            // memory.
14574                            if (app.hasShownUi && app != mHomeProcess
14575                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14576                                adjType = "cch-bound-ui-services";
14577                            } else {
14578                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14579                                        |Context.BIND_IMPORTANT)) != 0) {
14580                                    adj = clientAdj;
14581                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14582                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14583                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14584                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14585                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14586                                    adj = clientAdj;
14587                                } else {
14588                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14589                                        adj = ProcessList.VISIBLE_APP_ADJ;
14590                                    }
14591                                }
14592                                if (!client.cached) {
14593                                    app.cached = false;
14594                                }
14595                                if (client.keeping) {
14596                                    app.keeping = true;
14597                                }
14598                                adjType = "service";
14599                            }
14600                        }
14601                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14602                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14603                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14604                            }
14605                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14606                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14607                                    // Special handling of clients who are in the top state.
14608                                    // We *may* want to consider this process to be in the
14609                                    // top state as well, but only if there is not another
14610                                    // reason for it to be running.  Being on the top is a
14611                                    // special state, meaning you are specifically running
14612                                    // for the current top app.  If the process is already
14613                                    // running in the background for some other reason, it
14614                                    // is more important to continue considering it to be
14615                                    // in the background state.
14616                                    mayBeTop = true;
14617                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14618                                } else {
14619                                    // Special handling for above-top states (persistent
14620                                    // processes).  These should not bring the current process
14621                                    // into the top state, since they are not on top.  Instead
14622                                    // give them the best state after that.
14623                                    clientProcState =
14624                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14625                                }
14626                            }
14627                        } else {
14628                            if (clientProcState <
14629                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14630                                clientProcState =
14631                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14632                            }
14633                        }
14634                        if (procState > clientProcState) {
14635                            procState = clientProcState;
14636                        }
14637                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14638                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14639                            app.pendingUiClean = true;
14640                        }
14641                        if (adjType != null) {
14642                            app.adjType = adjType;
14643                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14644                                    .REASON_SERVICE_IN_USE;
14645                            app.adjSource = cr.binding.client;
14646                            app.adjSourceOom = clientAdj;
14647                            app.adjTarget = s.name;
14648                        }
14649                    }
14650                    final ActivityRecord a = cr.activity;
14651                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14652                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14653                                (a.visible || a.state == ActivityState.RESUMED
14654                                 || a.state == ActivityState.PAUSING)) {
14655                            adj = ProcessList.FOREGROUND_APP_ADJ;
14656                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14657                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14658                            }
14659                            app.cached = false;
14660                            app.adjType = "service";
14661                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14662                                    .REASON_SERVICE_IN_USE;
14663                            app.adjSource = a;
14664                            app.adjSourceOom = adj;
14665                            app.adjTarget = s.name;
14666                        }
14667                    }
14668                }
14669            }
14670        }
14671
14672        for (int provi = app.pubProviders.size()-1;
14673                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14674                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14675                        || procState > ActivityManager.PROCESS_STATE_TOP);
14676                provi--) {
14677            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14678            for (int i = cpr.connections.size()-1;
14679                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14680                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14681                            || procState > ActivityManager.PROCESS_STATE_TOP);
14682                    i--) {
14683                ContentProviderConnection conn = cpr.connections.get(i);
14684                ProcessRecord client = conn.client;
14685                if (client == app) {
14686                    // Being our own client is not interesting.
14687                    continue;
14688                }
14689                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14690                int clientProcState = client.curProcState;
14691                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14692                    // If the other app is cached for any reason, for purposes here
14693                    // we are going to consider it empty.
14694                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14695                }
14696                if (adj > clientAdj) {
14697                    if (app.hasShownUi && app != mHomeProcess
14698                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14699                        app.adjType = "cch-ui-provider";
14700                    } else {
14701                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14702                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14703                        app.adjType = "provider";
14704                    }
14705                    app.cached &= client.cached;
14706                    app.keeping |= client.keeping;
14707                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14708                            .REASON_PROVIDER_IN_USE;
14709                    app.adjSource = client;
14710                    app.adjSourceOom = clientAdj;
14711                    app.adjTarget = cpr.name;
14712                }
14713                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14714                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14715                        // Special handling of clients who are in the top state.
14716                        // We *may* want to consider this process to be in the
14717                        // top state as well, but only if there is not another
14718                        // reason for it to be running.  Being on the top is a
14719                        // special state, meaning you are specifically running
14720                        // for the current top app.  If the process is already
14721                        // running in the background for some other reason, it
14722                        // is more important to continue considering it to be
14723                        // in the background state.
14724                        mayBeTop = true;
14725                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14726                    } else {
14727                        // Special handling for above-top states (persistent
14728                        // processes).  These should not bring the current process
14729                        // into the top state, since they are not on top.  Instead
14730                        // give them the best state after that.
14731                        clientProcState =
14732                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14733                    }
14734                }
14735                if (procState > clientProcState) {
14736                    procState = clientProcState;
14737                }
14738                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14739                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14740                }
14741            }
14742            // If the provider has external (non-framework) process
14743            // dependencies, ensure that its adjustment is at least
14744            // FOREGROUND_APP_ADJ.
14745            if (cpr.hasExternalProcessHandles()) {
14746                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14747                    adj = ProcessList.FOREGROUND_APP_ADJ;
14748                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14749                    app.cached = false;
14750                    app.keeping = true;
14751                    app.adjType = "provider";
14752                    app.adjTarget = cpr.name;
14753                }
14754                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14755                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14756                }
14757            }
14758        }
14759
14760        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14761            // A client of one of our services or providers is in the top state.  We
14762            // *may* want to be in the top state, but not if we are already running in
14763            // the background for some other reason.  For the decision here, we are going
14764            // to pick out a few specific states that we want to remain in when a client
14765            // is top (states that tend to be longer-term) and otherwise allow it to go
14766            // to the top state.
14767            switch (procState) {
14768                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14769                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14770                case ActivityManager.PROCESS_STATE_SERVICE:
14771                    // These all are longer-term states, so pull them up to the top
14772                    // of the background states, but not all the way to the top state.
14773                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14774                    break;
14775                default:
14776                    // Otherwise, top is a better choice, so take it.
14777                    procState = ActivityManager.PROCESS_STATE_TOP;
14778                    break;
14779            }
14780        }
14781
14782        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14783            // This is a cached process, but with client activities.  Mark it so.
14784            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14785            app.adjType = "cch-client-act";
14786        }
14787
14788        if (adj == ProcessList.SERVICE_ADJ) {
14789            if (doingAll) {
14790                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14791                mNewNumServiceProcs++;
14792                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14793                if (!app.serviceb) {
14794                    // This service isn't far enough down on the LRU list to
14795                    // normally be a B service, but if we are low on RAM and it
14796                    // is large we want to force it down since we would prefer to
14797                    // keep launcher over it.
14798                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14799                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14800                        app.serviceHighRam = true;
14801                        app.serviceb = true;
14802                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14803                    } else {
14804                        mNewNumAServiceProcs++;
14805                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14806                    }
14807                } else {
14808                    app.serviceHighRam = false;
14809                }
14810            }
14811            if (app.serviceb) {
14812                adj = ProcessList.SERVICE_B_ADJ;
14813            }
14814        }
14815
14816        app.curRawAdj = adj;
14817
14818        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14819        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14820        if (adj > app.maxAdj) {
14821            adj = app.maxAdj;
14822            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14823                schedGroup = Process.THREAD_GROUP_DEFAULT;
14824            }
14825        }
14826        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14827            app.keeping = true;
14828        }
14829
14830        // Do final modification to adj.  Everything we do between here and applying
14831        // the final setAdj must be done in this function, because we will also use
14832        // it when computing the final cached adj later.  Note that we don't need to
14833        // worry about this for max adj above, since max adj will always be used to
14834        // keep it out of the cached vaues.
14835        adj = app.modifyRawOomAdj(adj);
14836
14837        app.curProcState = procState;
14838
14839        int importance = app.memImportance;
14840        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14841            app.curAdj = adj;
14842            app.curSchedGroup = schedGroup;
14843            if (!interesting) {
14844                // For this reporting, if there is not something explicitly
14845                // interesting in this process then we will push it to the
14846                // background importance.
14847                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14848            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14849                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14850            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14851                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14852            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14853                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14854            } else if (adj >= ProcessList.SERVICE_ADJ) {
14855                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14856            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14857                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14858            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14859                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14860            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14861                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14862            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14863                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14864            } else {
14865                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14866            }
14867        }
14868
14869        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14870        if (foregroundActivities != app.foregroundActivities) {
14871            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14872        }
14873        if (changes != 0) {
14874            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14875            app.memImportance = importance;
14876            app.foregroundActivities = foregroundActivities;
14877            int i = mPendingProcessChanges.size()-1;
14878            ProcessChangeItem item = null;
14879            while (i >= 0) {
14880                item = mPendingProcessChanges.get(i);
14881                if (item.pid == app.pid) {
14882                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14883                    break;
14884                }
14885                i--;
14886            }
14887            if (i < 0) {
14888                // No existing item in pending changes; need a new one.
14889                final int NA = mAvailProcessChanges.size();
14890                if (NA > 0) {
14891                    item = mAvailProcessChanges.remove(NA-1);
14892                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14893                } else {
14894                    item = new ProcessChangeItem();
14895                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14896                }
14897                item.changes = 0;
14898                item.pid = app.pid;
14899                item.uid = app.info.uid;
14900                if (mPendingProcessChanges.size() == 0) {
14901                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14902                            "*** Enqueueing dispatch processes changed!");
14903                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14904                }
14905                mPendingProcessChanges.add(item);
14906            }
14907            item.changes |= changes;
14908            item.importance = importance;
14909            item.foregroundActivities = foregroundActivities;
14910            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14911                    + Integer.toHexString(System.identityHashCode(item))
14912                    + " " + app.toShortString() + ": changes=" + item.changes
14913                    + " importance=" + item.importance
14914                    + " foreground=" + item.foregroundActivities
14915                    + " type=" + app.adjType + " source=" + app.adjSource
14916                    + " target=" + app.adjTarget);
14917        }
14918
14919        return app.curRawAdj;
14920    }
14921
14922    /**
14923     * Schedule PSS collection of a process.
14924     */
14925    void requestPssLocked(ProcessRecord proc, int procState) {
14926        if (mPendingPssProcesses.contains(proc)) {
14927            return;
14928        }
14929        if (mPendingPssProcesses.size() == 0) {
14930            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14931        }
14932        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14933        proc.pssProcState = procState;
14934        mPendingPssProcesses.add(proc);
14935    }
14936
14937    /**
14938     * Schedule PSS collection of all processes.
14939     */
14940    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14941        if (!always) {
14942            if (now < (mLastFullPssTime +
14943                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14944                return;
14945            }
14946        }
14947        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14948        mLastFullPssTime = now;
14949        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14950        mPendingPssProcesses.clear();
14951        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14952            ProcessRecord app = mLruProcesses.get(i);
14953            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14954                app.pssProcState = app.setProcState;
14955                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14956                        mSleeping, now);
14957                mPendingPssProcesses.add(app);
14958            }
14959        }
14960        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14961    }
14962
14963    /**
14964     * Ask a given process to GC right now.
14965     */
14966    final void performAppGcLocked(ProcessRecord app) {
14967        try {
14968            app.lastRequestedGc = SystemClock.uptimeMillis();
14969            if (app.thread != null) {
14970                if (app.reportLowMemory) {
14971                    app.reportLowMemory = false;
14972                    app.thread.scheduleLowMemory();
14973                } else {
14974                    app.thread.processInBackground();
14975                }
14976            }
14977        } catch (Exception e) {
14978            // whatever.
14979        }
14980    }
14981
14982    /**
14983     * Returns true if things are idle enough to perform GCs.
14984     */
14985    private final boolean canGcNowLocked() {
14986        boolean processingBroadcasts = false;
14987        for (BroadcastQueue q : mBroadcastQueues) {
14988            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14989                processingBroadcasts = true;
14990            }
14991        }
14992        return !processingBroadcasts
14993                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14994    }
14995
14996    /**
14997     * Perform GCs on all processes that are waiting for it, but only
14998     * if things are idle.
14999     */
15000    final void performAppGcsLocked() {
15001        final int N = mProcessesToGc.size();
15002        if (N <= 0) {
15003            return;
15004        }
15005        if (canGcNowLocked()) {
15006            while (mProcessesToGc.size() > 0) {
15007                ProcessRecord proc = mProcessesToGc.remove(0);
15008                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15009                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15010                            <= SystemClock.uptimeMillis()) {
15011                        // To avoid spamming the system, we will GC processes one
15012                        // at a time, waiting a few seconds between each.
15013                        performAppGcLocked(proc);
15014                        scheduleAppGcsLocked();
15015                        return;
15016                    } else {
15017                        // It hasn't been long enough since we last GCed this
15018                        // process...  put it in the list to wait for its time.
15019                        addProcessToGcListLocked(proc);
15020                        break;
15021                    }
15022                }
15023            }
15024
15025            scheduleAppGcsLocked();
15026        }
15027    }
15028
15029    /**
15030     * If all looks good, perform GCs on all processes waiting for them.
15031     */
15032    final void performAppGcsIfAppropriateLocked() {
15033        if (canGcNowLocked()) {
15034            performAppGcsLocked();
15035            return;
15036        }
15037        // Still not idle, wait some more.
15038        scheduleAppGcsLocked();
15039    }
15040
15041    /**
15042     * Schedule the execution of all pending app GCs.
15043     */
15044    final void scheduleAppGcsLocked() {
15045        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15046
15047        if (mProcessesToGc.size() > 0) {
15048            // Schedule a GC for the time to the next process.
15049            ProcessRecord proc = mProcessesToGc.get(0);
15050            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15051
15052            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15053            long now = SystemClock.uptimeMillis();
15054            if (when < (now+GC_TIMEOUT)) {
15055                when = now + GC_TIMEOUT;
15056            }
15057            mHandler.sendMessageAtTime(msg, when);
15058        }
15059    }
15060
15061    /**
15062     * Add a process to the array of processes waiting to be GCed.  Keeps the
15063     * list in sorted order by the last GC time.  The process can't already be
15064     * on the list.
15065     */
15066    final void addProcessToGcListLocked(ProcessRecord proc) {
15067        boolean added = false;
15068        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15069            if (mProcessesToGc.get(i).lastRequestedGc <
15070                    proc.lastRequestedGc) {
15071                added = true;
15072                mProcessesToGc.add(i+1, proc);
15073                break;
15074            }
15075        }
15076        if (!added) {
15077            mProcessesToGc.add(0, proc);
15078        }
15079    }
15080
15081    /**
15082     * Set up to ask a process to GC itself.  This will either do it
15083     * immediately, or put it on the list of processes to gc the next
15084     * time things are idle.
15085     */
15086    final void scheduleAppGcLocked(ProcessRecord app) {
15087        long now = SystemClock.uptimeMillis();
15088        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15089            return;
15090        }
15091        if (!mProcessesToGc.contains(app)) {
15092            addProcessToGcListLocked(app);
15093            scheduleAppGcsLocked();
15094        }
15095    }
15096
15097    final void checkExcessivePowerUsageLocked(boolean doKills) {
15098        updateCpuStatsNow();
15099
15100        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15101        boolean doWakeKills = doKills;
15102        boolean doCpuKills = doKills;
15103        if (mLastPowerCheckRealtime == 0) {
15104            doWakeKills = false;
15105        }
15106        if (mLastPowerCheckUptime == 0) {
15107            doCpuKills = false;
15108        }
15109        if (stats.isScreenOn()) {
15110            doWakeKills = false;
15111        }
15112        final long curRealtime = SystemClock.elapsedRealtime();
15113        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15114        final long curUptime = SystemClock.uptimeMillis();
15115        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15116        mLastPowerCheckRealtime = curRealtime;
15117        mLastPowerCheckUptime = curUptime;
15118        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15119            doWakeKills = false;
15120        }
15121        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15122            doCpuKills = false;
15123        }
15124        int i = mLruProcesses.size();
15125        while (i > 0) {
15126            i--;
15127            ProcessRecord app = mLruProcesses.get(i);
15128            if (!app.keeping) {
15129                long wtime;
15130                synchronized (stats) {
15131                    wtime = stats.getProcessWakeTime(app.info.uid,
15132                            app.pid, curRealtime);
15133                }
15134                long wtimeUsed = wtime - app.lastWakeTime;
15135                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15136                if (DEBUG_POWER) {
15137                    StringBuilder sb = new StringBuilder(128);
15138                    sb.append("Wake for ");
15139                    app.toShortString(sb);
15140                    sb.append(": over ");
15141                    TimeUtils.formatDuration(realtimeSince, sb);
15142                    sb.append(" used ");
15143                    TimeUtils.formatDuration(wtimeUsed, sb);
15144                    sb.append(" (");
15145                    sb.append((wtimeUsed*100)/realtimeSince);
15146                    sb.append("%)");
15147                    Slog.i(TAG, sb.toString());
15148                    sb.setLength(0);
15149                    sb.append("CPU for ");
15150                    app.toShortString(sb);
15151                    sb.append(": over ");
15152                    TimeUtils.formatDuration(uptimeSince, sb);
15153                    sb.append(" used ");
15154                    TimeUtils.formatDuration(cputimeUsed, sb);
15155                    sb.append(" (");
15156                    sb.append((cputimeUsed*100)/uptimeSince);
15157                    sb.append("%)");
15158                    Slog.i(TAG, sb.toString());
15159                }
15160                // If a process has held a wake lock for more
15161                // than 50% of the time during this period,
15162                // that sounds bad.  Kill!
15163                if (doWakeKills && realtimeSince > 0
15164                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15165                    synchronized (stats) {
15166                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15167                                realtimeSince, wtimeUsed);
15168                    }
15169                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15170                            + " during " + realtimeSince);
15171                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15172                } else if (doCpuKills && uptimeSince > 0
15173                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15174                    synchronized (stats) {
15175                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15176                                uptimeSince, cputimeUsed);
15177                    }
15178                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15179                            + " during " + uptimeSince);
15180                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15181                } else {
15182                    app.lastWakeTime = wtime;
15183                    app.lastCpuTime = app.curCpuTime;
15184                }
15185            }
15186        }
15187    }
15188
15189    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15190            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15191        boolean success = true;
15192
15193        if (app.curRawAdj != app.setRawAdj) {
15194            if (wasKeeping && !app.keeping) {
15195                // This app is no longer something we want to keep.  Note
15196                // its current wake lock time to later know to kill it if
15197                // it is not behaving well.
15198                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15199                synchronized (stats) {
15200                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15201                            app.pid, SystemClock.elapsedRealtime());
15202                }
15203                app.lastCpuTime = app.curCpuTime;
15204            }
15205
15206            app.setRawAdj = app.curRawAdj;
15207        }
15208
15209        if (app.curAdj != app.setAdj) {
15210            ProcessList.setOomAdj(app.pid, app.curAdj);
15211            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15212                TAG, "Set " + app.pid + " " + app.processName +
15213                " adj " + app.curAdj + ": " + app.adjType);
15214            app.setAdj = app.curAdj;
15215        }
15216
15217        if (app.setSchedGroup != app.curSchedGroup) {
15218            app.setSchedGroup = app.curSchedGroup;
15219            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15220                    "Setting process group of " + app.processName
15221                    + " to " + app.curSchedGroup);
15222            if (app.waitingToKill != null &&
15223                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15224                killUnneededProcessLocked(app, app.waitingToKill);
15225                success = false;
15226            } else {
15227                if (true) {
15228                    long oldId = Binder.clearCallingIdentity();
15229                    try {
15230                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15231                    } catch (Exception e) {
15232                        Slog.w(TAG, "Failed setting process group of " + app.pid
15233                                + " to " + app.curSchedGroup);
15234                        e.printStackTrace();
15235                    } finally {
15236                        Binder.restoreCallingIdentity(oldId);
15237                    }
15238                } else {
15239                    if (app.thread != null) {
15240                        try {
15241                            app.thread.setSchedulingGroup(app.curSchedGroup);
15242                        } catch (RemoteException e) {
15243                        }
15244                    }
15245                }
15246                Process.setSwappiness(app.pid,
15247                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15248            }
15249        }
15250        if (app.repProcState != app.curProcState) {
15251            app.repProcState = app.curProcState;
15252            if (!reportingProcessState && app.thread != null) {
15253                try {
15254                    if (false) {
15255                        //RuntimeException h = new RuntimeException("here");
15256                        Slog.i(TAG, "Sending new process state " + app.repProcState
15257                                + " to " + app /*, h*/);
15258                    }
15259                    app.thread.setProcessState(app.repProcState);
15260                } catch (RemoteException e) {
15261                }
15262            }
15263        }
15264        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15265                app.setProcState)) {
15266            app.lastStateTime = now;
15267            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15268                    mSleeping, now);
15269            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15270                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15271                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15272                    + (app.nextPssTime-now) + ": " + app);
15273        } else {
15274            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15275                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15276                requestPssLocked(app, app.setProcState);
15277                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15278                        mSleeping, now);
15279            } else if (false && DEBUG_PSS) {
15280                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15281            }
15282        }
15283        if (app.setProcState != app.curProcState) {
15284            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15285                    "Proc state change of " + app.processName
15286                    + " to " + app.curProcState);
15287            app.setProcState = app.curProcState;
15288            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15289                app.notCachedSinceIdle = false;
15290            }
15291            if (!doingAll) {
15292                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15293            } else {
15294                app.procStateChanged = true;
15295            }
15296        }
15297        return success;
15298    }
15299
15300    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15301        if (proc.thread != null && proc.baseProcessTracker != null) {
15302            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15303        }
15304    }
15305
15306    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15307            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15308        if (app.thread == null) {
15309            return false;
15310        }
15311
15312        final boolean wasKeeping = app.keeping;
15313
15314        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15315
15316        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15317                reportingProcessState, now);
15318    }
15319
15320    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15321            boolean oomAdj) {
15322        if (isForeground != proc.foregroundServices) {
15323            proc.foregroundServices = isForeground;
15324            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15325                    proc.info.uid);
15326            if (isForeground) {
15327                if (curProcs == null) {
15328                    curProcs = new ArrayList<ProcessRecord>();
15329                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15330                }
15331                if (!curProcs.contains(proc)) {
15332                    curProcs.add(proc);
15333                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15334                            proc.info.packageName, proc.info.uid);
15335                }
15336            } else {
15337                if (curProcs != null) {
15338                    if (curProcs.remove(proc)) {
15339                        mBatteryStatsService.noteEvent(
15340                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15341                                proc.info.packageName, proc.info.uid);
15342                        if (curProcs.size() <= 0) {
15343                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15344                        }
15345                    }
15346                }
15347            }
15348            if (oomAdj) {
15349                updateOomAdjLocked();
15350            }
15351        }
15352    }
15353
15354    private final ActivityRecord resumedAppLocked() {
15355        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15356        String pkg;
15357        int uid;
15358        if (act != null) {
15359            pkg = act.packageName;
15360            uid = act.info.applicationInfo.uid;
15361        } else {
15362            pkg = null;
15363            uid = -1;
15364        }
15365        // Has the UID or resumed package name changed?
15366        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15367                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15368            if (mCurResumedPackage != null) {
15369                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15370                        mCurResumedPackage, mCurResumedUid);
15371            }
15372            mCurResumedPackage = pkg;
15373            mCurResumedUid = uid;
15374            if (mCurResumedPackage != null) {
15375                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15376                        mCurResumedPackage, mCurResumedUid);
15377            }
15378        }
15379        return act;
15380    }
15381
15382    final boolean updateOomAdjLocked(ProcessRecord app) {
15383        return updateOomAdjLocked(app, false);
15384    }
15385
15386    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15387        final ActivityRecord TOP_ACT = resumedAppLocked();
15388        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15389        final boolean wasCached = app.cached;
15390
15391        mAdjSeq++;
15392
15393        // This is the desired cached adjusment we want to tell it to use.
15394        // If our app is currently cached, we know it, and that is it.  Otherwise,
15395        // we don't know it yet, and it needs to now be cached we will then
15396        // need to do a complete oom adj.
15397        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15398                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15399        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15400                SystemClock.uptimeMillis());
15401        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15402            // Changed to/from cached state, so apps after it in the LRU
15403            // list may also be changed.
15404            updateOomAdjLocked();
15405        }
15406        return success;
15407    }
15408
15409    final void updateOomAdjLocked() {
15410        final ActivityRecord TOP_ACT = resumedAppLocked();
15411        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15412        final long now = SystemClock.uptimeMillis();
15413        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15414        final int N = mLruProcesses.size();
15415
15416        if (false) {
15417            RuntimeException e = new RuntimeException();
15418            e.fillInStackTrace();
15419            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15420        }
15421
15422        mAdjSeq++;
15423        mNewNumServiceProcs = 0;
15424        mNewNumAServiceProcs = 0;
15425
15426        final int emptyProcessLimit;
15427        final int cachedProcessLimit;
15428        if (mProcessLimit <= 0) {
15429            emptyProcessLimit = cachedProcessLimit = 0;
15430        } else if (mProcessLimit == 1) {
15431            emptyProcessLimit = 1;
15432            cachedProcessLimit = 0;
15433        } else {
15434            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15435            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15436        }
15437
15438        // Let's determine how many processes we have running vs.
15439        // how many slots we have for background processes; we may want
15440        // to put multiple processes in a slot of there are enough of
15441        // them.
15442        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15443                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15444        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15445        if (numEmptyProcs > cachedProcessLimit) {
15446            // If there are more empty processes than our limit on cached
15447            // processes, then use the cached process limit for the factor.
15448            // This ensures that the really old empty processes get pushed
15449            // down to the bottom, so if we are running low on memory we will
15450            // have a better chance at keeping around more cached processes
15451            // instead of a gazillion empty processes.
15452            numEmptyProcs = cachedProcessLimit;
15453        }
15454        int emptyFactor = numEmptyProcs/numSlots;
15455        if (emptyFactor < 1) emptyFactor = 1;
15456        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15457        if (cachedFactor < 1) cachedFactor = 1;
15458        int stepCached = 0;
15459        int stepEmpty = 0;
15460        int numCached = 0;
15461        int numEmpty = 0;
15462        int numTrimming = 0;
15463
15464        mNumNonCachedProcs = 0;
15465        mNumCachedHiddenProcs = 0;
15466
15467        // First update the OOM adjustment for each of the
15468        // application processes based on their current state.
15469        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15470        int nextCachedAdj = curCachedAdj+1;
15471        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15472        int nextEmptyAdj = curEmptyAdj+2;
15473        for (int i=N-1; i>=0; i--) {
15474            ProcessRecord app = mLruProcesses.get(i);
15475            if (!app.killedByAm && app.thread != null) {
15476                app.procStateChanged = false;
15477                final boolean wasKeeping = app.keeping;
15478                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15479
15480                // If we haven't yet assigned the final cached adj
15481                // to the process, do that now.
15482                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15483                    switch (app.curProcState) {
15484                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15485                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15486                            // This process is a cached process holding activities...
15487                            // assign it the next cached value for that type, and then
15488                            // step that cached level.
15489                            app.curRawAdj = curCachedAdj;
15490                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15491                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15492                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15493                                    + ")");
15494                            if (curCachedAdj != nextCachedAdj) {
15495                                stepCached++;
15496                                if (stepCached >= cachedFactor) {
15497                                    stepCached = 0;
15498                                    curCachedAdj = nextCachedAdj;
15499                                    nextCachedAdj += 2;
15500                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15501                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15502                                    }
15503                                }
15504                            }
15505                            break;
15506                        default:
15507                            // For everything else, assign next empty cached process
15508                            // level and bump that up.  Note that this means that
15509                            // long-running services that have dropped down to the
15510                            // cached level will be treated as empty (since their process
15511                            // state is still as a service), which is what we want.
15512                            app.curRawAdj = curEmptyAdj;
15513                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15514                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15515                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15516                                    + ")");
15517                            if (curEmptyAdj != nextEmptyAdj) {
15518                                stepEmpty++;
15519                                if (stepEmpty >= emptyFactor) {
15520                                    stepEmpty = 0;
15521                                    curEmptyAdj = nextEmptyAdj;
15522                                    nextEmptyAdj += 2;
15523                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15524                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15525                                    }
15526                                }
15527                            }
15528                            break;
15529                    }
15530                }
15531
15532                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15533
15534                // Count the number of process types.
15535                switch (app.curProcState) {
15536                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15537                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15538                        mNumCachedHiddenProcs++;
15539                        numCached++;
15540                        if (numCached > cachedProcessLimit) {
15541                            killUnneededProcessLocked(app, "cached #" + numCached);
15542                        }
15543                        break;
15544                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15545                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15546                                && app.lastActivityTime < oldTime) {
15547                            killUnneededProcessLocked(app, "empty for "
15548                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15549                                    / 1000) + "s");
15550                        } else {
15551                            numEmpty++;
15552                            if (numEmpty > emptyProcessLimit) {
15553                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15554                            }
15555                        }
15556                        break;
15557                    default:
15558                        mNumNonCachedProcs++;
15559                        break;
15560                }
15561
15562                if (app.isolated && app.services.size() <= 0) {
15563                    // If this is an isolated process, and there are no
15564                    // services running in it, then the process is no longer
15565                    // needed.  We agressively kill these because we can by
15566                    // definition not re-use the same process again, and it is
15567                    // good to avoid having whatever code was running in them
15568                    // left sitting around after no longer needed.
15569                    killUnneededProcessLocked(app, "isolated not needed");
15570                }
15571
15572                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15573                        && !app.killedByAm) {
15574                    numTrimming++;
15575                }
15576            }
15577        }
15578
15579        mNumServiceProcs = mNewNumServiceProcs;
15580
15581        // Now determine the memory trimming level of background processes.
15582        // Unfortunately we need to start at the back of the list to do this
15583        // properly.  We only do this if the number of background apps we
15584        // are managing to keep around is less than half the maximum we desire;
15585        // if we are keeping a good number around, we'll let them use whatever
15586        // memory they want.
15587        final int numCachedAndEmpty = numCached + numEmpty;
15588        int memFactor;
15589        if (numCached <= ProcessList.TRIM_CACHED_APPS
15590                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15591            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15592                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15593            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15594                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15595            } else {
15596                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15597            }
15598        } else {
15599            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15600        }
15601        // We always allow the memory level to go up (better).  We only allow it to go
15602        // down if we are in a state where that is allowed, *and* the total number of processes
15603        // has gone down since last time.
15604        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15605                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15606                + " last=" + mLastNumProcesses);
15607        if (memFactor > mLastMemoryLevel) {
15608            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15609                memFactor = mLastMemoryLevel;
15610                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15611            }
15612        }
15613        mLastMemoryLevel = memFactor;
15614        mLastNumProcesses = mLruProcesses.size();
15615        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15616        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15617        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15618            if (mLowRamStartTime == 0) {
15619                mLowRamStartTime = now;
15620            }
15621            int step = 0;
15622            int fgTrimLevel;
15623            switch (memFactor) {
15624                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15625                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15626                    break;
15627                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15628                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15629                    break;
15630                default:
15631                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15632                    break;
15633            }
15634            int factor = numTrimming/3;
15635            int minFactor = 2;
15636            if (mHomeProcess != null) minFactor++;
15637            if (mPreviousProcess != null) minFactor++;
15638            if (factor < minFactor) factor = minFactor;
15639            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15640            for (int i=N-1; i>=0; i--) {
15641                ProcessRecord app = mLruProcesses.get(i);
15642                if (allChanged || app.procStateChanged) {
15643                    setProcessTrackerState(app, trackerMemFactor, now);
15644                    app.procStateChanged = false;
15645                }
15646                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15647                        && !app.killedByAm) {
15648                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15649                        try {
15650                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15651                                    "Trimming memory of " + app.processName
15652                                    + " to " + curLevel);
15653                            app.thread.scheduleTrimMemory(curLevel);
15654                        } catch (RemoteException e) {
15655                        }
15656                        if (false) {
15657                            // For now we won't do this; our memory trimming seems
15658                            // to be good enough at this point that destroying
15659                            // activities causes more harm than good.
15660                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15661                                    && app != mHomeProcess && app != mPreviousProcess) {
15662                                // Need to do this on its own message because the stack may not
15663                                // be in a consistent state at this point.
15664                                // For these apps we will also finish their activities
15665                                // to help them free memory.
15666                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15667                            }
15668                        }
15669                    }
15670                    app.trimMemoryLevel = curLevel;
15671                    step++;
15672                    if (step >= factor) {
15673                        step = 0;
15674                        switch (curLevel) {
15675                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15676                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15677                                break;
15678                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15679                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15680                                break;
15681                        }
15682                    }
15683                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15684                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15685                            && app.thread != null) {
15686                        try {
15687                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15688                                    "Trimming memory of heavy-weight " + app.processName
15689                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15690                            app.thread.scheduleTrimMemory(
15691                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15692                        } catch (RemoteException e) {
15693                        }
15694                    }
15695                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15696                } else {
15697                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15698                            || app.systemNoUi) && app.pendingUiClean) {
15699                        // If this application is now in the background and it
15700                        // had done UI, then give it the special trim level to
15701                        // have it free UI resources.
15702                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15703                        if (app.trimMemoryLevel < level && app.thread != null) {
15704                            try {
15705                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15706                                        "Trimming memory of bg-ui " + app.processName
15707                                        + " to " + level);
15708                                app.thread.scheduleTrimMemory(level);
15709                            } catch (RemoteException e) {
15710                            }
15711                        }
15712                        app.pendingUiClean = false;
15713                    }
15714                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15715                        try {
15716                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15717                                    "Trimming memory of fg " + app.processName
15718                                    + " to " + fgTrimLevel);
15719                            app.thread.scheduleTrimMemory(fgTrimLevel);
15720                        } catch (RemoteException e) {
15721                        }
15722                    }
15723                    app.trimMemoryLevel = fgTrimLevel;
15724                }
15725            }
15726        } else {
15727            if (mLowRamStartTime != 0) {
15728                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15729                mLowRamStartTime = 0;
15730            }
15731            for (int i=N-1; i>=0; i--) {
15732                ProcessRecord app = mLruProcesses.get(i);
15733                if (allChanged || app.procStateChanged) {
15734                    setProcessTrackerState(app, trackerMemFactor, now);
15735                    app.procStateChanged = false;
15736                }
15737                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15738                        || app.systemNoUi) && app.pendingUiClean) {
15739                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15740                            && app.thread != null) {
15741                        try {
15742                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15743                                    "Trimming memory of ui hidden " + app.processName
15744                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15745                            app.thread.scheduleTrimMemory(
15746                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15747                        } catch (RemoteException e) {
15748                        }
15749                    }
15750                    app.pendingUiClean = false;
15751                }
15752                app.trimMemoryLevel = 0;
15753            }
15754        }
15755
15756        if (mAlwaysFinishActivities) {
15757            // Need to do this on its own message because the stack may not
15758            // be in a consistent state at this point.
15759            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15760        }
15761
15762        if (allChanged) {
15763            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15764        }
15765
15766        if (mProcessStats.shouldWriteNowLocked(now)) {
15767            mHandler.post(new Runnable() {
15768                @Override public void run() {
15769                    synchronized (ActivityManagerService.this) {
15770                        mProcessStats.writeStateAsyncLocked();
15771                    }
15772                }
15773            });
15774        }
15775
15776        if (DEBUG_OOM_ADJ) {
15777            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15778        }
15779    }
15780
15781    final void trimApplications() {
15782        synchronized (this) {
15783            int i;
15784
15785            // First remove any unused application processes whose package
15786            // has been removed.
15787            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15788                final ProcessRecord app = mRemovedProcesses.get(i);
15789                if (app.activities.size() == 0
15790                        && app.curReceiver == null && app.services.size() == 0) {
15791                    Slog.i(
15792                        TAG, "Exiting empty application process "
15793                        + app.processName + " ("
15794                        + (app.thread != null ? app.thread.asBinder() : null)
15795                        + ")\n");
15796                    if (app.pid > 0 && app.pid != MY_PID) {
15797                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15798                                app.processName, app.setAdj, "empty");
15799                        app.killedByAm = true;
15800                        Process.killProcessQuiet(app.pid);
15801                    } else {
15802                        try {
15803                            app.thread.scheduleExit();
15804                        } catch (Exception e) {
15805                            // Ignore exceptions.
15806                        }
15807                    }
15808                    cleanUpApplicationRecordLocked(app, false, true, -1);
15809                    mRemovedProcesses.remove(i);
15810
15811                    if (app.persistent) {
15812                        if (app.persistent) {
15813                            addAppLocked(app.info, false);
15814                        }
15815                    }
15816                }
15817            }
15818
15819            // Now update the oom adj for all processes.
15820            updateOomAdjLocked();
15821        }
15822    }
15823
15824    /** This method sends the specified signal to each of the persistent apps */
15825    public void signalPersistentProcesses(int sig) throws RemoteException {
15826        if (sig != Process.SIGNAL_USR1) {
15827            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15828        }
15829
15830        synchronized (this) {
15831            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15832                    != PackageManager.PERMISSION_GRANTED) {
15833                throw new SecurityException("Requires permission "
15834                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15835            }
15836
15837            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15838                ProcessRecord r = mLruProcesses.get(i);
15839                if (r.thread != null && r.persistent) {
15840                    Process.sendSignal(r.pid, sig);
15841                }
15842            }
15843        }
15844    }
15845
15846    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15847        if (proc == null || proc == mProfileProc) {
15848            proc = mProfileProc;
15849            path = mProfileFile;
15850            profileType = mProfileType;
15851            clearProfilerLocked();
15852        }
15853        if (proc == null) {
15854            return;
15855        }
15856        try {
15857            proc.thread.profilerControl(false, path, null, profileType);
15858        } catch (RemoteException e) {
15859            throw new IllegalStateException("Process disappeared");
15860        }
15861    }
15862
15863    private void clearProfilerLocked() {
15864        if (mProfileFd != null) {
15865            try {
15866                mProfileFd.close();
15867            } catch (IOException e) {
15868            }
15869        }
15870        mProfileApp = null;
15871        mProfileProc = null;
15872        mProfileFile = null;
15873        mProfileType = 0;
15874        mAutoStopProfiler = false;
15875    }
15876
15877    public boolean profileControl(String process, int userId, boolean start,
15878            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15879
15880        try {
15881            synchronized (this) {
15882                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15883                // its own permission.
15884                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15885                        != PackageManager.PERMISSION_GRANTED) {
15886                    throw new SecurityException("Requires permission "
15887                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15888                }
15889
15890                if (start && fd == null) {
15891                    throw new IllegalArgumentException("null fd");
15892                }
15893
15894                ProcessRecord proc = null;
15895                if (process != null) {
15896                    proc = findProcessLocked(process, userId, "profileControl");
15897                }
15898
15899                if (start && (proc == null || proc.thread == null)) {
15900                    throw new IllegalArgumentException("Unknown process: " + process);
15901                }
15902
15903                if (start) {
15904                    stopProfilerLocked(null, null, 0);
15905                    setProfileApp(proc.info, proc.processName, path, fd, false);
15906                    mProfileProc = proc;
15907                    mProfileType = profileType;
15908                    try {
15909                        fd = fd.dup();
15910                    } catch (IOException e) {
15911                        fd = null;
15912                    }
15913                    proc.thread.profilerControl(start, path, fd, profileType);
15914                    fd = null;
15915                    mProfileFd = null;
15916                } else {
15917                    stopProfilerLocked(proc, path, profileType);
15918                    if (fd != null) {
15919                        try {
15920                            fd.close();
15921                        } catch (IOException e) {
15922                        }
15923                    }
15924                }
15925
15926                return true;
15927            }
15928        } catch (RemoteException e) {
15929            throw new IllegalStateException("Process disappeared");
15930        } finally {
15931            if (fd != null) {
15932                try {
15933                    fd.close();
15934                } catch (IOException e) {
15935                }
15936            }
15937        }
15938    }
15939
15940    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15941        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15942                userId, true, true, callName, null);
15943        ProcessRecord proc = null;
15944        try {
15945            int pid = Integer.parseInt(process);
15946            synchronized (mPidsSelfLocked) {
15947                proc = mPidsSelfLocked.get(pid);
15948            }
15949        } catch (NumberFormatException e) {
15950        }
15951
15952        if (proc == null) {
15953            ArrayMap<String, SparseArray<ProcessRecord>> all
15954                    = mProcessNames.getMap();
15955            SparseArray<ProcessRecord> procs = all.get(process);
15956            if (procs != null && procs.size() > 0) {
15957                proc = procs.valueAt(0);
15958                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15959                    for (int i=1; i<procs.size(); i++) {
15960                        ProcessRecord thisProc = procs.valueAt(i);
15961                        if (thisProc.userId == userId) {
15962                            proc = thisProc;
15963                            break;
15964                        }
15965                    }
15966                }
15967            }
15968        }
15969
15970        return proc;
15971    }
15972
15973    public boolean dumpHeap(String process, int userId, boolean managed,
15974            String path, ParcelFileDescriptor fd) throws RemoteException {
15975
15976        try {
15977            synchronized (this) {
15978                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15979                // its own permission (same as profileControl).
15980                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15981                        != PackageManager.PERMISSION_GRANTED) {
15982                    throw new SecurityException("Requires permission "
15983                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15984                }
15985
15986                if (fd == null) {
15987                    throw new IllegalArgumentException("null fd");
15988                }
15989
15990                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15991                if (proc == null || proc.thread == null) {
15992                    throw new IllegalArgumentException("Unknown process: " + process);
15993                }
15994
15995                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15996                if (!isDebuggable) {
15997                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15998                        throw new SecurityException("Process not debuggable: " + proc);
15999                    }
16000                }
16001
16002                proc.thread.dumpHeap(managed, path, fd);
16003                fd = null;
16004                return true;
16005            }
16006        } catch (RemoteException e) {
16007            throw new IllegalStateException("Process disappeared");
16008        } finally {
16009            if (fd != null) {
16010                try {
16011                    fd.close();
16012                } catch (IOException e) {
16013                }
16014            }
16015        }
16016    }
16017
16018    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16019    public void monitor() {
16020        synchronized (this) { }
16021    }
16022
16023    void onCoreSettingsChange(Bundle settings) {
16024        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16025            ProcessRecord processRecord = mLruProcesses.get(i);
16026            try {
16027                if (processRecord.thread != null) {
16028                    processRecord.thread.setCoreSettings(settings);
16029                }
16030            } catch (RemoteException re) {
16031                /* ignore */
16032            }
16033        }
16034    }
16035
16036    // Multi-user methods
16037
16038    @Override
16039    public boolean switchUser(final int userId) {
16040        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16041                != PackageManager.PERMISSION_GRANTED) {
16042            String msg = "Permission Denial: switchUser() from pid="
16043                    + Binder.getCallingPid()
16044                    + ", uid=" + Binder.getCallingUid()
16045                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16046            Slog.w(TAG, msg);
16047            throw new SecurityException(msg);
16048        }
16049
16050        final long ident = Binder.clearCallingIdentity();
16051        try {
16052            synchronized (this) {
16053                final int oldUserId = mCurrentUserId;
16054                if (oldUserId == userId) {
16055                    return true;
16056                }
16057
16058                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16059                if (userInfo == null) {
16060                    Slog.w(TAG, "No user info for user #" + userId);
16061                    return false;
16062                }
16063
16064                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16065                        R.anim.screen_user_enter);
16066
16067                boolean needStart = false;
16068
16069                // If the user we are switching to is not currently started, then
16070                // we need to start it now.
16071                if (mStartedUsers.get(userId) == null) {
16072                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16073                    updateStartedUserArrayLocked();
16074                    needStart = true;
16075                }
16076
16077                mCurrentUserId = userId;
16078                final Integer userIdInt = Integer.valueOf(userId);
16079                mUserLru.remove(userIdInt);
16080                mUserLru.add(userIdInt);
16081
16082                mWindowManager.setCurrentUser(userId);
16083
16084                // Once the internal notion of the active user has switched, we lock the device
16085                // with the option to show the user switcher on the keyguard.
16086                mWindowManager.lockNow(null);
16087
16088                final UserStartedState uss = mStartedUsers.get(userId);
16089
16090                // Make sure user is in the started state.  If it is currently
16091                // stopping, we need to knock that off.
16092                if (uss.mState == UserStartedState.STATE_STOPPING) {
16093                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16094                    // so we can just fairly silently bring the user back from
16095                    // the almost-dead.
16096                    uss.mState = UserStartedState.STATE_RUNNING;
16097                    updateStartedUserArrayLocked();
16098                    needStart = true;
16099                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16100                    // This means ACTION_SHUTDOWN has been sent, so we will
16101                    // need to treat this as a new boot of the user.
16102                    uss.mState = UserStartedState.STATE_BOOTING;
16103                    updateStartedUserArrayLocked();
16104                    needStart = true;
16105                }
16106
16107                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16108                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16109                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16110                        oldUserId, userId, uss));
16111                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16112                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16113                if (needStart) {
16114                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16115                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16116                            | Intent.FLAG_RECEIVER_FOREGROUND);
16117                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16118                    broadcastIntentLocked(null, null, intent,
16119                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16120                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16121                }
16122
16123                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16124                    if (userId != 0) {
16125                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16126                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16127                        broadcastIntentLocked(null, null, intent, null,
16128                                new IIntentReceiver.Stub() {
16129                                    public void performReceive(Intent intent, int resultCode,
16130                                            String data, Bundle extras, boolean ordered,
16131                                            boolean sticky, int sendingUser) {
16132                                        userInitialized(uss, userId);
16133                                    }
16134                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16135                                true, false, MY_PID, Process.SYSTEM_UID,
16136                                userId);
16137                        uss.initializing = true;
16138                    } else {
16139                        getUserManagerLocked().makeInitialized(userInfo.id);
16140                    }
16141                }
16142
16143                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16144                if (homeInFront) {
16145                    startHomeActivityLocked(userId);
16146                } else {
16147                    mStackSupervisor.resumeTopActivitiesLocked();
16148                }
16149
16150                EventLogTags.writeAmSwitchUser(userId);
16151                getUserManagerLocked().userForeground(userId);
16152                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16153                if (needStart) {
16154                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16155                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16156                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16157                    broadcastIntentLocked(null, null, intent,
16158                            null, new IIntentReceiver.Stub() {
16159                                @Override
16160                                public void performReceive(Intent intent, int resultCode, String data,
16161                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16162                                        throws RemoteException {
16163                                }
16164                            }, 0, null, null,
16165                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16166                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16167                }
16168            }
16169        } finally {
16170            Binder.restoreCallingIdentity(ident);
16171        }
16172
16173        return true;
16174    }
16175
16176    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16177        long ident = Binder.clearCallingIdentity();
16178        try {
16179            Intent intent;
16180            if (oldUserId >= 0) {
16181                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16182                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16183                        | Intent.FLAG_RECEIVER_FOREGROUND);
16184                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16185                broadcastIntentLocked(null, null, intent,
16186                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16187                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16188            }
16189            if (newUserId >= 0) {
16190                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16191                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16192                        | Intent.FLAG_RECEIVER_FOREGROUND);
16193                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16194                broadcastIntentLocked(null, null, intent,
16195                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16196                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16197                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16198                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16199                        | Intent.FLAG_RECEIVER_FOREGROUND);
16200                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16201                broadcastIntentLocked(null, null, intent,
16202                        null, null, 0, null, null,
16203                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16204                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16205            }
16206        } finally {
16207            Binder.restoreCallingIdentity(ident);
16208        }
16209    }
16210
16211    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16212            final int newUserId) {
16213        final int N = mUserSwitchObservers.beginBroadcast();
16214        if (N > 0) {
16215            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16216                int mCount = 0;
16217                @Override
16218                public void sendResult(Bundle data) throws RemoteException {
16219                    synchronized (ActivityManagerService.this) {
16220                        if (mCurUserSwitchCallback == this) {
16221                            mCount++;
16222                            if (mCount == N) {
16223                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16224                            }
16225                        }
16226                    }
16227                }
16228            };
16229            synchronized (this) {
16230                uss.switching = true;
16231                mCurUserSwitchCallback = callback;
16232            }
16233            for (int i=0; i<N; i++) {
16234                try {
16235                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16236                            newUserId, callback);
16237                } catch (RemoteException e) {
16238                }
16239            }
16240        } else {
16241            synchronized (this) {
16242                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16243            }
16244        }
16245        mUserSwitchObservers.finishBroadcast();
16246    }
16247
16248    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16249        synchronized (this) {
16250            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16251            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16252        }
16253    }
16254
16255    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16256        mCurUserSwitchCallback = null;
16257        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16258        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16259                oldUserId, newUserId, uss));
16260    }
16261
16262    void userInitialized(UserStartedState uss, int newUserId) {
16263        completeSwitchAndInitalize(uss, newUserId, true, false);
16264    }
16265
16266    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16267        completeSwitchAndInitalize(uss, newUserId, false, true);
16268    }
16269
16270    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16271            boolean clearInitializing, boolean clearSwitching) {
16272        boolean unfrozen = false;
16273        synchronized (this) {
16274            if (clearInitializing) {
16275                uss.initializing = false;
16276                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16277            }
16278            if (clearSwitching) {
16279                uss.switching = false;
16280            }
16281            if (!uss.switching && !uss.initializing) {
16282                mWindowManager.stopFreezingScreen();
16283                unfrozen = true;
16284            }
16285        }
16286        if (unfrozen) {
16287            final int N = mUserSwitchObservers.beginBroadcast();
16288            for (int i=0; i<N; i++) {
16289                try {
16290                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16291                } catch (RemoteException e) {
16292                }
16293            }
16294            mUserSwitchObservers.finishBroadcast();
16295        }
16296    }
16297
16298    void finishUserSwitch(UserStartedState uss) {
16299        synchronized (this) {
16300            if (uss.mState == UserStartedState.STATE_BOOTING
16301                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16302                uss.mState = UserStartedState.STATE_RUNNING;
16303                final int userId = uss.mHandle.getIdentifier();
16304                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16305                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16306                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16307                broadcastIntentLocked(null, null, intent,
16308                        null, null, 0, null, null,
16309                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16310                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16311            }
16312            int num = mUserLru.size();
16313            int i = 0;
16314            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16315                Integer oldUserId = mUserLru.get(i);
16316                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16317                if (oldUss == null) {
16318                    // Shouldn't happen, but be sane if it does.
16319                    mUserLru.remove(i);
16320                    num--;
16321                    continue;
16322                }
16323                if (oldUss.mState == UserStartedState.STATE_STOPPING
16324                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16325                    // This user is already stopping, doesn't count.
16326                    num--;
16327                    i++;
16328                    continue;
16329                }
16330                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16331                    // Owner and current can't be stopped, but count as running.
16332                    i++;
16333                    continue;
16334                }
16335                // This is a user to be stopped.
16336                stopUserLocked(oldUserId, null);
16337                num--;
16338                i++;
16339            }
16340        }
16341    }
16342
16343    @Override
16344    public int stopUser(final int userId, final IStopUserCallback callback) {
16345        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16346                != PackageManager.PERMISSION_GRANTED) {
16347            String msg = "Permission Denial: switchUser() from pid="
16348                    + Binder.getCallingPid()
16349                    + ", uid=" + Binder.getCallingUid()
16350                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16351            Slog.w(TAG, msg);
16352            throw new SecurityException(msg);
16353        }
16354        if (userId <= 0) {
16355            throw new IllegalArgumentException("Can't stop primary user " + userId);
16356        }
16357        synchronized (this) {
16358            return stopUserLocked(userId, callback);
16359        }
16360    }
16361
16362    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16363        if (mCurrentUserId == userId) {
16364            return ActivityManager.USER_OP_IS_CURRENT;
16365        }
16366
16367        final UserStartedState uss = mStartedUsers.get(userId);
16368        if (uss == null) {
16369            // User is not started, nothing to do...  but we do need to
16370            // callback if requested.
16371            if (callback != null) {
16372                mHandler.post(new Runnable() {
16373                    @Override
16374                    public void run() {
16375                        try {
16376                            callback.userStopped(userId);
16377                        } catch (RemoteException e) {
16378                        }
16379                    }
16380                });
16381            }
16382            return ActivityManager.USER_OP_SUCCESS;
16383        }
16384
16385        if (callback != null) {
16386            uss.mStopCallbacks.add(callback);
16387        }
16388
16389        if (uss.mState != UserStartedState.STATE_STOPPING
16390                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16391            uss.mState = UserStartedState.STATE_STOPPING;
16392            updateStartedUserArrayLocked();
16393
16394            long ident = Binder.clearCallingIdentity();
16395            try {
16396                // We are going to broadcast ACTION_USER_STOPPING and then
16397                // once that is done send a final ACTION_SHUTDOWN and then
16398                // stop the user.
16399                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16400                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16401                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16402                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16403                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16404                // This is the result receiver for the final shutdown broadcast.
16405                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16406                    @Override
16407                    public void performReceive(Intent intent, int resultCode, String data,
16408                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16409                        finishUserStop(uss);
16410                    }
16411                };
16412                // This is the result receiver for the initial stopping broadcast.
16413                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16414                    @Override
16415                    public void performReceive(Intent intent, int resultCode, String data,
16416                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16417                        // On to the next.
16418                        synchronized (ActivityManagerService.this) {
16419                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16420                                // Whoops, we are being started back up.  Abort, abort!
16421                                return;
16422                            }
16423                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16424                        }
16425                        broadcastIntentLocked(null, null, shutdownIntent,
16426                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16427                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16428                    }
16429                };
16430                // Kick things off.
16431                broadcastIntentLocked(null, null, stoppingIntent,
16432                        null, stoppingReceiver, 0, null, null,
16433                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16434                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16435            } finally {
16436                Binder.restoreCallingIdentity(ident);
16437            }
16438        }
16439
16440        return ActivityManager.USER_OP_SUCCESS;
16441    }
16442
16443    void finishUserStop(UserStartedState uss) {
16444        final int userId = uss.mHandle.getIdentifier();
16445        boolean stopped;
16446        ArrayList<IStopUserCallback> callbacks;
16447        synchronized (this) {
16448            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16449            if (mStartedUsers.get(userId) != uss) {
16450                stopped = false;
16451            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16452                stopped = false;
16453            } else {
16454                stopped = true;
16455                // User can no longer run.
16456                mStartedUsers.remove(userId);
16457                mUserLru.remove(Integer.valueOf(userId));
16458                updateStartedUserArrayLocked();
16459
16460                // Clean up all state and processes associated with the user.
16461                // Kill all the processes for the user.
16462                forceStopUserLocked(userId, "finish user");
16463            }
16464        }
16465
16466        for (int i=0; i<callbacks.size(); i++) {
16467            try {
16468                if (stopped) callbacks.get(i).userStopped(userId);
16469                else callbacks.get(i).userStopAborted(userId);
16470            } catch (RemoteException e) {
16471            }
16472        }
16473
16474        mStackSupervisor.removeUserLocked(userId);
16475    }
16476
16477    @Override
16478    public UserInfo getCurrentUser() {
16479        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16480                != PackageManager.PERMISSION_GRANTED) && (
16481                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16482                != PackageManager.PERMISSION_GRANTED)) {
16483            String msg = "Permission Denial: getCurrentUser() from pid="
16484                    + Binder.getCallingPid()
16485                    + ", uid=" + Binder.getCallingUid()
16486                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16487            Slog.w(TAG, msg);
16488            throw new SecurityException(msg);
16489        }
16490        synchronized (this) {
16491            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16492        }
16493    }
16494
16495    int getCurrentUserIdLocked() {
16496        return mCurrentUserId;
16497    }
16498
16499    @Override
16500    public boolean isUserRunning(int userId, boolean orStopped) {
16501        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16502                != PackageManager.PERMISSION_GRANTED) {
16503            String msg = "Permission Denial: isUserRunning() from pid="
16504                    + Binder.getCallingPid()
16505                    + ", uid=" + Binder.getCallingUid()
16506                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16507            Slog.w(TAG, msg);
16508            throw new SecurityException(msg);
16509        }
16510        synchronized (this) {
16511            return isUserRunningLocked(userId, orStopped);
16512        }
16513    }
16514
16515    boolean isUserRunningLocked(int userId, boolean orStopped) {
16516        UserStartedState state = mStartedUsers.get(userId);
16517        if (state == null) {
16518            return false;
16519        }
16520        if (orStopped) {
16521            return true;
16522        }
16523        return state.mState != UserStartedState.STATE_STOPPING
16524                && state.mState != UserStartedState.STATE_SHUTDOWN;
16525    }
16526
16527    @Override
16528    public int[] getRunningUserIds() {
16529        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16530                != PackageManager.PERMISSION_GRANTED) {
16531            String msg = "Permission Denial: isUserRunning() from pid="
16532                    + Binder.getCallingPid()
16533                    + ", uid=" + Binder.getCallingUid()
16534                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16535            Slog.w(TAG, msg);
16536            throw new SecurityException(msg);
16537        }
16538        synchronized (this) {
16539            return mStartedUserArray;
16540        }
16541    }
16542
16543    private void updateStartedUserArrayLocked() {
16544        int num = 0;
16545        for (int i=0; i<mStartedUsers.size();  i++) {
16546            UserStartedState uss = mStartedUsers.valueAt(i);
16547            // This list does not include stopping users.
16548            if (uss.mState != UserStartedState.STATE_STOPPING
16549                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16550                num++;
16551            }
16552        }
16553        mStartedUserArray = new int[num];
16554        num = 0;
16555        for (int i=0; i<mStartedUsers.size();  i++) {
16556            UserStartedState uss = mStartedUsers.valueAt(i);
16557            if (uss.mState != UserStartedState.STATE_STOPPING
16558                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16559                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16560                num++;
16561            }
16562        }
16563    }
16564
16565    @Override
16566    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16567        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16568                != PackageManager.PERMISSION_GRANTED) {
16569            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16570                    + Binder.getCallingPid()
16571                    + ", uid=" + Binder.getCallingUid()
16572                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16573            Slog.w(TAG, msg);
16574            throw new SecurityException(msg);
16575        }
16576
16577        mUserSwitchObservers.register(observer);
16578    }
16579
16580    @Override
16581    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16582        mUserSwitchObservers.unregister(observer);
16583    }
16584
16585    private boolean userExists(int userId) {
16586        if (userId == 0) {
16587            return true;
16588        }
16589        UserManagerService ums = getUserManagerLocked();
16590        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16591    }
16592
16593    int[] getUsersLocked() {
16594        UserManagerService ums = getUserManagerLocked();
16595        return ums != null ? ums.getUserIds() : new int[] { 0 };
16596    }
16597
16598    UserManagerService getUserManagerLocked() {
16599        if (mUserManager == null) {
16600            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16601            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16602        }
16603        return mUserManager;
16604    }
16605
16606    private int applyUserId(int uid, int userId) {
16607        return UserHandle.getUid(userId, uid);
16608    }
16609
16610    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16611        if (info == null) return null;
16612        ApplicationInfo newInfo = new ApplicationInfo(info);
16613        newInfo.uid = applyUserId(info.uid, userId);
16614        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16615                + info.packageName;
16616        return newInfo;
16617    }
16618
16619    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16620        if (aInfo == null
16621                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16622            return aInfo;
16623        }
16624
16625        ActivityInfo info = new ActivityInfo(aInfo);
16626        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16627        return info;
16628    }
16629}
16630