ActivityManagerService.java revision 9358dcca6f3d33d1e3f976a4c3a5f61e103930dc
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        long ident = Binder.clearCallingIdentity();
7759        try {
7760            synchronized (this) {
7761                ContentProviderConnection conn;
7762                try {
7763                    conn = (ContentProviderConnection)connection;
7764                } catch (ClassCastException e) {
7765                    String msg ="removeContentProvider: " + connection
7766                            + " not a ContentProviderConnection";
7767                    Slog.w(TAG, msg);
7768                    throw new IllegalArgumentException(msg);
7769                }
7770                if (conn == null) {
7771                    throw new NullPointerException("connection is null");
7772                }
7773                if (decProviderCountLocked(conn, null, null, stable)) {
7774                    updateOomAdjLocked();
7775                }
7776            }
7777        } finally {
7778            Binder.restoreCallingIdentity(ident);
7779        }
7780    }
7781
7782    public void removeContentProviderExternal(String name, IBinder token) {
7783        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7784            "Do not have permission in call removeContentProviderExternal()");
7785        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7786    }
7787
7788    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7789        synchronized (this) {
7790            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7791            if(cpr == null) {
7792                //remove from mProvidersByClass
7793                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7794                return;
7795            }
7796
7797            //update content provider record entry info
7798            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7799            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7800            if (localCpr.hasExternalProcessHandles()) {
7801                if (localCpr.removeExternalProcessHandleLocked(token)) {
7802                    updateOomAdjLocked();
7803                } else {
7804                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7805                            + " with no external reference for token: "
7806                            + token + ".");
7807                }
7808            } else {
7809                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7810                        + " with no external references.");
7811            }
7812        }
7813    }
7814
7815    public final void publishContentProviders(IApplicationThread caller,
7816            List<ContentProviderHolder> providers) {
7817        if (providers == null) {
7818            return;
7819        }
7820
7821        enforceNotIsolatedCaller("publishContentProviders");
7822        synchronized (this) {
7823            final ProcessRecord r = getRecordForAppLocked(caller);
7824            if (DEBUG_MU)
7825                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7826            if (r == null) {
7827                throw new SecurityException(
7828                        "Unable to find app for caller " + caller
7829                      + " (pid=" + Binder.getCallingPid()
7830                      + ") when publishing content providers");
7831            }
7832
7833            final long origId = Binder.clearCallingIdentity();
7834
7835            final int N = providers.size();
7836            for (int i=0; i<N; i++) {
7837                ContentProviderHolder src = providers.get(i);
7838                if (src == null || src.info == null || src.provider == null) {
7839                    continue;
7840                }
7841                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7842                if (DEBUG_MU)
7843                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7844                if (dst != null) {
7845                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7846                    mProviderMap.putProviderByClass(comp, dst);
7847                    String names[] = dst.info.authority.split(";");
7848                    for (int j = 0; j < names.length; j++) {
7849                        mProviderMap.putProviderByName(names[j], dst);
7850                    }
7851
7852                    int NL = mLaunchingProviders.size();
7853                    int j;
7854                    for (j=0; j<NL; j++) {
7855                        if (mLaunchingProviders.get(j) == dst) {
7856                            mLaunchingProviders.remove(j);
7857                            j--;
7858                            NL--;
7859                        }
7860                    }
7861                    synchronized (dst) {
7862                        dst.provider = src.provider;
7863                        dst.proc = r;
7864                        dst.notifyAll();
7865                    }
7866                    updateOomAdjLocked(r);
7867                }
7868            }
7869
7870            Binder.restoreCallingIdentity(origId);
7871        }
7872    }
7873
7874    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7875        ContentProviderConnection conn;
7876        try {
7877            conn = (ContentProviderConnection)connection;
7878        } catch (ClassCastException e) {
7879            String msg ="refContentProvider: " + connection
7880                    + " not a ContentProviderConnection";
7881            Slog.w(TAG, msg);
7882            throw new IllegalArgumentException(msg);
7883        }
7884        if (conn == null) {
7885            throw new NullPointerException("connection is null");
7886        }
7887
7888        synchronized (this) {
7889            if (stable > 0) {
7890                conn.numStableIncs += stable;
7891            }
7892            stable = conn.stableCount + stable;
7893            if (stable < 0) {
7894                throw new IllegalStateException("stableCount < 0: " + stable);
7895            }
7896
7897            if (unstable > 0) {
7898                conn.numUnstableIncs += unstable;
7899            }
7900            unstable = conn.unstableCount + unstable;
7901            if (unstable < 0) {
7902                throw new IllegalStateException("unstableCount < 0: " + unstable);
7903            }
7904
7905            if ((stable+unstable) <= 0) {
7906                throw new IllegalStateException("ref counts can't go to zero here: stable="
7907                        + stable + " unstable=" + unstable);
7908            }
7909            conn.stableCount = stable;
7910            conn.unstableCount = unstable;
7911            return !conn.dead;
7912        }
7913    }
7914
7915    public void unstableProviderDied(IBinder connection) {
7916        ContentProviderConnection conn;
7917        try {
7918            conn = (ContentProviderConnection)connection;
7919        } catch (ClassCastException e) {
7920            String msg ="refContentProvider: " + connection
7921                    + " not a ContentProviderConnection";
7922            Slog.w(TAG, msg);
7923            throw new IllegalArgumentException(msg);
7924        }
7925        if (conn == null) {
7926            throw new NullPointerException("connection is null");
7927        }
7928
7929        // Safely retrieve the content provider associated with the connection.
7930        IContentProvider provider;
7931        synchronized (this) {
7932            provider = conn.provider.provider;
7933        }
7934
7935        if (provider == null) {
7936            // Um, yeah, we're way ahead of you.
7937            return;
7938        }
7939
7940        // Make sure the caller is being honest with us.
7941        if (provider.asBinder().pingBinder()) {
7942            // Er, no, still looks good to us.
7943            synchronized (this) {
7944                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7945                        + " says " + conn + " died, but we don't agree");
7946                return;
7947            }
7948        }
7949
7950        // Well look at that!  It's dead!
7951        synchronized (this) {
7952            if (conn.provider.provider != provider) {
7953                // But something changed...  good enough.
7954                return;
7955            }
7956
7957            ProcessRecord proc = conn.provider.proc;
7958            if (proc == null || proc.thread == null) {
7959                // Seems like the process is already cleaned up.
7960                return;
7961            }
7962
7963            // As far as we're concerned, this is just like receiving a
7964            // death notification...  just a bit prematurely.
7965            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7966                    + ") early provider death");
7967            final long ident = Binder.clearCallingIdentity();
7968            try {
7969                appDiedLocked(proc, proc.pid, proc.thread);
7970            } finally {
7971                Binder.restoreCallingIdentity(ident);
7972            }
7973        }
7974    }
7975
7976    @Override
7977    public void appNotRespondingViaProvider(IBinder connection) {
7978        enforceCallingPermission(
7979                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7980
7981        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7982        if (conn == null) {
7983            Slog.w(TAG, "ContentProviderConnection is null");
7984            return;
7985        }
7986
7987        final ProcessRecord host = conn.provider.proc;
7988        if (host == null) {
7989            Slog.w(TAG, "Failed to find hosting ProcessRecord");
7990            return;
7991        }
7992
7993        final long token = Binder.clearCallingIdentity();
7994        try {
7995            appNotResponding(host, null, null, false, "ContentProvider not responding");
7996        } finally {
7997            Binder.restoreCallingIdentity(token);
7998        }
7999    }
8000
8001    public final void installSystemProviders() {
8002        List<ProviderInfo> providers;
8003        synchronized (this) {
8004            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8005            providers = generateApplicationProvidersLocked(app);
8006            if (providers != null) {
8007                for (int i=providers.size()-1; i>=0; i--) {
8008                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8009                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8010                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8011                                + ": not system .apk");
8012                        providers.remove(i);
8013                    }
8014                }
8015            }
8016        }
8017        if (providers != null) {
8018            mSystemThread.installSystemProviders(providers);
8019        }
8020
8021        mCoreSettingsObserver = new CoreSettingsObserver(this);
8022
8023        mUsageStatsService.monitorPackages();
8024    }
8025
8026    /**
8027     * Allows app to retrieve the MIME type of a URI without having permission
8028     * to access its content provider.
8029     *
8030     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8031     *
8032     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8033     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8034     */
8035    public String getProviderMimeType(Uri uri, int userId) {
8036        enforceNotIsolatedCaller("getProviderMimeType");
8037        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8038                userId, false, true, "getProviderMimeType", null);
8039        final String name = uri.getAuthority();
8040        final long ident = Binder.clearCallingIdentity();
8041        ContentProviderHolder holder = null;
8042
8043        try {
8044            holder = getContentProviderExternalUnchecked(name, null, userId);
8045            if (holder != null) {
8046                return holder.provider.getType(uri);
8047            }
8048        } catch (RemoteException e) {
8049            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8050            return null;
8051        } finally {
8052            if (holder != null) {
8053                removeContentProviderExternalUnchecked(name, null, userId);
8054            }
8055            Binder.restoreCallingIdentity(ident);
8056        }
8057
8058        return null;
8059    }
8060
8061    // =========================================================
8062    // GLOBAL MANAGEMENT
8063    // =========================================================
8064
8065    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8066            boolean isolated) {
8067        String proc = customProcess != null ? customProcess : info.processName;
8068        BatteryStatsImpl.Uid.Proc ps = null;
8069        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8070        int uid = info.uid;
8071        if (isolated) {
8072            int userId = UserHandle.getUserId(uid);
8073            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8074            while (true) {
8075                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8076                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8077                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8078                }
8079                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8080                mNextIsolatedProcessUid++;
8081                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8082                    // No process for this uid, use it.
8083                    break;
8084                }
8085                stepsLeft--;
8086                if (stepsLeft <= 0) {
8087                    return null;
8088                }
8089            }
8090        }
8091        return new ProcessRecord(stats, info, proc, uid);
8092    }
8093
8094    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8095        ProcessRecord app;
8096        if (!isolated) {
8097            app = getProcessRecordLocked(info.processName, info.uid, true);
8098        } else {
8099            app = null;
8100        }
8101
8102        if (app == null) {
8103            app = newProcessRecordLocked(info, null, isolated);
8104            mProcessNames.put(info.processName, app.uid, app);
8105            if (isolated) {
8106                mIsolatedProcesses.put(app.uid, app);
8107            }
8108            updateLruProcessLocked(app, false, null);
8109            updateOomAdjLocked();
8110        }
8111
8112        // This package really, really can not be stopped.
8113        try {
8114            AppGlobals.getPackageManager().setPackageStoppedState(
8115                    info.packageName, false, UserHandle.getUserId(app.uid));
8116        } catch (RemoteException e) {
8117        } catch (IllegalArgumentException e) {
8118            Slog.w(TAG, "Failed trying to unstop package "
8119                    + info.packageName + ": " + e);
8120        }
8121
8122        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8123                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8124            app.persistent = true;
8125            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8126        }
8127        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8128            mPersistentStartingProcesses.add(app);
8129            startProcessLocked(app, "added application", app.processName);
8130        }
8131
8132        return app;
8133    }
8134
8135    public void unhandledBack() {
8136        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8137                "unhandledBack()");
8138
8139        synchronized(this) {
8140            final long origId = Binder.clearCallingIdentity();
8141            try {
8142                getFocusedStack().unhandledBackLocked();
8143            } finally {
8144                Binder.restoreCallingIdentity(origId);
8145            }
8146        }
8147    }
8148
8149    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8150        enforceNotIsolatedCaller("openContentUri");
8151        final int userId = UserHandle.getCallingUserId();
8152        String name = uri.getAuthority();
8153        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8154        ParcelFileDescriptor pfd = null;
8155        if (cph != null) {
8156            // We record the binder invoker's uid in thread-local storage before
8157            // going to the content provider to open the file.  Later, in the code
8158            // that handles all permissions checks, we look for this uid and use
8159            // that rather than the Activity Manager's own uid.  The effect is that
8160            // we do the check against the caller's permissions even though it looks
8161            // to the content provider like the Activity Manager itself is making
8162            // the request.
8163            sCallerIdentity.set(new Identity(
8164                    Binder.getCallingPid(), Binder.getCallingUid()));
8165            try {
8166                pfd = cph.provider.openFile(null, uri, "r", null);
8167            } catch (FileNotFoundException e) {
8168                // do nothing; pfd will be returned null
8169            } finally {
8170                // Ensure that whatever happens, we clean up the identity state
8171                sCallerIdentity.remove();
8172            }
8173
8174            // We've got the fd now, so we're done with the provider.
8175            removeContentProviderExternalUnchecked(name, null, userId);
8176        } else {
8177            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8178        }
8179        return pfd;
8180    }
8181
8182    // Actually is sleeping or shutting down or whatever else in the future
8183    // is an inactive state.
8184    public boolean isSleepingOrShuttingDown() {
8185        return mSleeping || mShuttingDown;
8186    }
8187
8188    public void goingToSleep() {
8189        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8190                != PackageManager.PERMISSION_GRANTED) {
8191            throw new SecurityException("Requires permission "
8192                    + android.Manifest.permission.DEVICE_POWER);
8193        }
8194
8195        synchronized(this) {
8196            mWentToSleep = true;
8197            updateEventDispatchingLocked();
8198
8199            if (!mSleeping) {
8200                mSleeping = true;
8201                mStackSupervisor.goingToSleepLocked();
8202
8203                // Initialize the wake times of all processes.
8204                checkExcessivePowerUsageLocked(false);
8205                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8206                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8207                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8208            }
8209        }
8210    }
8211
8212    @Override
8213    public boolean shutdown(int timeout) {
8214        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8215                != PackageManager.PERMISSION_GRANTED) {
8216            throw new SecurityException("Requires permission "
8217                    + android.Manifest.permission.SHUTDOWN);
8218        }
8219
8220        boolean timedout = false;
8221
8222        synchronized(this) {
8223            mShuttingDown = true;
8224            updateEventDispatchingLocked();
8225            timedout = mStackSupervisor.shutdownLocked(timeout);
8226        }
8227
8228        mAppOpsService.shutdown();
8229        mUsageStatsService.shutdown();
8230        mBatteryStatsService.shutdown();
8231        synchronized (this) {
8232            mProcessStats.shutdownLocked();
8233        }
8234
8235        return timedout;
8236    }
8237
8238    public final void activitySlept(IBinder token) {
8239        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8240
8241        final long origId = Binder.clearCallingIdentity();
8242
8243        synchronized (this) {
8244            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8245            if (r != null) {
8246                mStackSupervisor.activitySleptLocked(r);
8247            }
8248        }
8249
8250        Binder.restoreCallingIdentity(origId);
8251    }
8252
8253    void logLockScreen(String msg) {
8254        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8255                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8256                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8257                mStackSupervisor.mDismissKeyguardOnNextActivity);
8258    }
8259
8260    private void comeOutOfSleepIfNeededLocked() {
8261        if (!mWentToSleep && !mLockScreenShown) {
8262            if (mSleeping) {
8263                mSleeping = false;
8264                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8265            }
8266        }
8267    }
8268
8269    public void wakingUp() {
8270        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8271                != PackageManager.PERMISSION_GRANTED) {
8272            throw new SecurityException("Requires permission "
8273                    + android.Manifest.permission.DEVICE_POWER);
8274        }
8275
8276        synchronized(this) {
8277            mWentToSleep = false;
8278            updateEventDispatchingLocked();
8279            comeOutOfSleepIfNeededLocked();
8280        }
8281    }
8282
8283    private void updateEventDispatchingLocked() {
8284        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8285    }
8286
8287    public void setLockScreenShown(boolean shown) {
8288        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8289                != PackageManager.PERMISSION_GRANTED) {
8290            throw new SecurityException("Requires permission "
8291                    + android.Manifest.permission.DEVICE_POWER);
8292        }
8293
8294        synchronized(this) {
8295            long ident = Binder.clearCallingIdentity();
8296            try {
8297                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8298                mLockScreenShown = shown;
8299                comeOutOfSleepIfNeededLocked();
8300            } finally {
8301                Binder.restoreCallingIdentity(ident);
8302            }
8303        }
8304    }
8305
8306    public void stopAppSwitches() {
8307        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8308                != PackageManager.PERMISSION_GRANTED) {
8309            throw new SecurityException("Requires permission "
8310                    + android.Manifest.permission.STOP_APP_SWITCHES);
8311        }
8312
8313        synchronized(this) {
8314            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8315                    + APP_SWITCH_DELAY_TIME;
8316            mDidAppSwitch = false;
8317            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8318            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8319            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8320        }
8321    }
8322
8323    public void resumeAppSwitches() {
8324        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8325                != PackageManager.PERMISSION_GRANTED) {
8326            throw new SecurityException("Requires permission "
8327                    + android.Manifest.permission.STOP_APP_SWITCHES);
8328        }
8329
8330        synchronized(this) {
8331            // Note that we don't execute any pending app switches... we will
8332            // let those wait until either the timeout, or the next start
8333            // activity request.
8334            mAppSwitchesAllowedTime = 0;
8335        }
8336    }
8337
8338    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8339            String name) {
8340        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8341            return true;
8342        }
8343
8344        final int perm = checkComponentPermission(
8345                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8346                callingUid, -1, true);
8347        if (perm == PackageManager.PERMISSION_GRANTED) {
8348            return true;
8349        }
8350
8351        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8352        return false;
8353    }
8354
8355    public void setDebugApp(String packageName, boolean waitForDebugger,
8356            boolean persistent) {
8357        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8358                "setDebugApp()");
8359
8360        long ident = Binder.clearCallingIdentity();
8361        try {
8362            // Note that this is not really thread safe if there are multiple
8363            // callers into it at the same time, but that's not a situation we
8364            // care about.
8365            if (persistent) {
8366                final ContentResolver resolver = mContext.getContentResolver();
8367                Settings.Global.putString(
8368                    resolver, Settings.Global.DEBUG_APP,
8369                    packageName);
8370                Settings.Global.putInt(
8371                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8372                    waitForDebugger ? 1 : 0);
8373            }
8374
8375            synchronized (this) {
8376                if (!persistent) {
8377                    mOrigDebugApp = mDebugApp;
8378                    mOrigWaitForDebugger = mWaitForDebugger;
8379                }
8380                mDebugApp = packageName;
8381                mWaitForDebugger = waitForDebugger;
8382                mDebugTransient = !persistent;
8383                if (packageName != null) {
8384                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8385                            false, UserHandle.USER_ALL, "set debug app");
8386                }
8387            }
8388        } finally {
8389            Binder.restoreCallingIdentity(ident);
8390        }
8391    }
8392
8393    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8394        synchronized (this) {
8395            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8396            if (!isDebuggable) {
8397                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8398                    throw new SecurityException("Process not debuggable: " + app.packageName);
8399                }
8400            }
8401
8402            mOpenGlTraceApp = processName;
8403        }
8404    }
8405
8406    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8407            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8408        synchronized (this) {
8409            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8410            if (!isDebuggable) {
8411                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8412                    throw new SecurityException("Process not debuggable: " + app.packageName);
8413                }
8414            }
8415            mProfileApp = processName;
8416            mProfileFile = profileFile;
8417            if (mProfileFd != null) {
8418                try {
8419                    mProfileFd.close();
8420                } catch (IOException e) {
8421                }
8422                mProfileFd = null;
8423            }
8424            mProfileFd = profileFd;
8425            mProfileType = 0;
8426            mAutoStopProfiler = autoStopProfiler;
8427        }
8428    }
8429
8430    @Override
8431    public void setAlwaysFinish(boolean enabled) {
8432        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8433                "setAlwaysFinish()");
8434
8435        Settings.Global.putInt(
8436                mContext.getContentResolver(),
8437                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8438
8439        synchronized (this) {
8440            mAlwaysFinishActivities = enabled;
8441        }
8442    }
8443
8444    @Override
8445    public void setActivityController(IActivityController controller) {
8446        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8447                "setActivityController()");
8448        synchronized (this) {
8449            mController = controller;
8450            Watchdog.getInstance().setActivityController(controller);
8451        }
8452    }
8453
8454    @Override
8455    public void setUserIsMonkey(boolean userIsMonkey) {
8456        synchronized (this) {
8457            synchronized (mPidsSelfLocked) {
8458                final int callingPid = Binder.getCallingPid();
8459                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8460                if (precessRecord == null) {
8461                    throw new SecurityException("Unknown process: " + callingPid);
8462                }
8463                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8464                    throw new SecurityException("Only an instrumentation process "
8465                            + "with a UiAutomation can call setUserIsMonkey");
8466                }
8467            }
8468            mUserIsMonkey = userIsMonkey;
8469        }
8470    }
8471
8472    @Override
8473    public boolean isUserAMonkey() {
8474        synchronized (this) {
8475            // If there is a controller also implies the user is a monkey.
8476            return (mUserIsMonkey || mController != null);
8477        }
8478    }
8479
8480    public void requestBugReport() {
8481        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8482        SystemProperties.set("ctl.start", "bugreport");
8483    }
8484
8485    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8486        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8487    }
8488
8489    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8490        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8491            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8492        }
8493        return KEY_DISPATCHING_TIMEOUT;
8494    }
8495
8496    @Override
8497    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8498        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8499                != PackageManager.PERMISSION_GRANTED) {
8500            throw new SecurityException("Requires permission "
8501                    + android.Manifest.permission.FILTER_EVENTS);
8502        }
8503        ProcessRecord proc;
8504        long timeout;
8505        synchronized (this) {
8506            synchronized (mPidsSelfLocked) {
8507                proc = mPidsSelfLocked.get(pid);
8508            }
8509            timeout = getInputDispatchingTimeoutLocked(proc);
8510        }
8511
8512        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8513            return -1;
8514        }
8515
8516        return timeout;
8517    }
8518
8519    /**
8520     * Handle input dispatching timeouts.
8521     * Returns whether input dispatching should be aborted or not.
8522     */
8523    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8524            final ActivityRecord activity, final ActivityRecord parent,
8525            final boolean aboveSystem, String reason) {
8526        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8527                != PackageManager.PERMISSION_GRANTED) {
8528            throw new SecurityException("Requires permission "
8529                    + android.Manifest.permission.FILTER_EVENTS);
8530        }
8531
8532        final String annotation;
8533        if (reason == null) {
8534            annotation = "Input dispatching timed out";
8535        } else {
8536            annotation = "Input dispatching timed out (" + reason + ")";
8537        }
8538
8539        if (proc != null) {
8540            synchronized (this) {
8541                if (proc.debugging) {
8542                    return false;
8543                }
8544
8545                if (mDidDexOpt) {
8546                    // Give more time since we were dexopting.
8547                    mDidDexOpt = false;
8548                    return false;
8549                }
8550
8551                if (proc.instrumentationClass != null) {
8552                    Bundle info = new Bundle();
8553                    info.putString("shortMsg", "keyDispatchingTimedOut");
8554                    info.putString("longMsg", annotation);
8555                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8556                    return true;
8557                }
8558            }
8559            mHandler.post(new Runnable() {
8560                @Override
8561                public void run() {
8562                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8563                }
8564            });
8565        }
8566
8567        return true;
8568    }
8569
8570    public Bundle getAssistContextExtras(int requestType) {
8571        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8572                "getAssistContextExtras()");
8573        PendingAssistExtras pae;
8574        Bundle extras = new Bundle();
8575        synchronized (this) {
8576            ActivityRecord activity = getFocusedStack().mResumedActivity;
8577            if (activity == null) {
8578                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8579                return null;
8580            }
8581            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8582            if (activity.app == null || activity.app.thread == null) {
8583                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8584                return extras;
8585            }
8586            if (activity.app.pid == Binder.getCallingPid()) {
8587                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8588                return extras;
8589            }
8590            pae = new PendingAssistExtras(activity);
8591            try {
8592                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8593                        requestType);
8594                mPendingAssistExtras.add(pae);
8595                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8596            } catch (RemoteException e) {
8597                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8598                return extras;
8599            }
8600        }
8601        synchronized (pae) {
8602            while (!pae.haveResult) {
8603                try {
8604                    pae.wait();
8605                } catch (InterruptedException e) {
8606                }
8607            }
8608            if (pae.result != null) {
8609                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8610            }
8611        }
8612        synchronized (this) {
8613            mPendingAssistExtras.remove(pae);
8614            mHandler.removeCallbacks(pae);
8615        }
8616        return extras;
8617    }
8618
8619    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8620        PendingAssistExtras pae = (PendingAssistExtras)token;
8621        synchronized (pae) {
8622            pae.result = extras;
8623            pae.haveResult = true;
8624            pae.notifyAll();
8625        }
8626    }
8627
8628    public void registerProcessObserver(IProcessObserver observer) {
8629        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8630                "registerProcessObserver()");
8631        synchronized (this) {
8632            mProcessObservers.register(observer);
8633        }
8634    }
8635
8636    @Override
8637    public void unregisterProcessObserver(IProcessObserver observer) {
8638        synchronized (this) {
8639            mProcessObservers.unregister(observer);
8640        }
8641    }
8642
8643    @Override
8644    public boolean convertFromTranslucent(IBinder token) {
8645        final long origId = Binder.clearCallingIdentity();
8646        try {
8647            synchronized (this) {
8648                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8649                if (r == null) {
8650                    return false;
8651                }
8652                if (r.changeWindowTranslucency(true)) {
8653                    mWindowManager.setAppFullscreen(token, true);
8654                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8655                    return true;
8656                }
8657                return false;
8658            }
8659        } finally {
8660            Binder.restoreCallingIdentity(origId);
8661        }
8662    }
8663
8664    @Override
8665    public boolean convertToTranslucent(IBinder token) {
8666        final long origId = Binder.clearCallingIdentity();
8667        try {
8668            synchronized (this) {
8669                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8670                if (r == null) {
8671                    return false;
8672                }
8673                if (r.changeWindowTranslucency(false)) {
8674                    r.task.stack.convertToTranslucent(r);
8675                    mWindowManager.setAppFullscreen(token, false);
8676                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8677                    return true;
8678                }
8679                return false;
8680            }
8681        } finally {
8682            Binder.restoreCallingIdentity(origId);
8683        }
8684    }
8685
8686    @Override
8687    public void setImmersive(IBinder token, boolean immersive) {
8688        synchronized(this) {
8689            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8690            if (r == null) {
8691                throw new IllegalArgumentException();
8692            }
8693            r.immersive = immersive;
8694
8695            // update associated state if we're frontmost
8696            if (r == mFocusedActivity) {
8697                if (DEBUG_IMMERSIVE) {
8698                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8699                }
8700                applyUpdateLockStateLocked(r);
8701            }
8702        }
8703    }
8704
8705    @Override
8706    public boolean isImmersive(IBinder token) {
8707        synchronized (this) {
8708            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8709            if (r == null) {
8710                throw new IllegalArgumentException();
8711            }
8712            return r.immersive;
8713        }
8714    }
8715
8716    public boolean isTopActivityImmersive() {
8717        enforceNotIsolatedCaller("startActivity");
8718        synchronized (this) {
8719            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8720            return (r != null) ? r.immersive : false;
8721        }
8722    }
8723
8724    public final void enterSafeMode() {
8725        synchronized(this) {
8726            // It only makes sense to do this before the system is ready
8727            // and started launching other packages.
8728            if (!mSystemReady) {
8729                try {
8730                    AppGlobals.getPackageManager().enterSafeMode();
8731                } catch (RemoteException e) {
8732                }
8733            }
8734        }
8735    }
8736
8737    public final void showSafeModeOverlay() {
8738        View v = LayoutInflater.from(mContext).inflate(
8739                com.android.internal.R.layout.safe_mode, null);
8740        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8741        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8742        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8743        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8744        lp.gravity = Gravity.BOTTOM | Gravity.START;
8745        lp.format = v.getBackground().getOpacity();
8746        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8747                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8748        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8749        ((WindowManager)mContext.getSystemService(
8750                Context.WINDOW_SERVICE)).addView(v, lp);
8751    }
8752
8753    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8754        if (!(sender instanceof PendingIntentRecord)) {
8755            return;
8756        }
8757        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8758        synchronized (stats) {
8759            if (mBatteryStatsService.isOnBattery()) {
8760                mBatteryStatsService.enforceCallingPermission();
8761                PendingIntentRecord rec = (PendingIntentRecord)sender;
8762                int MY_UID = Binder.getCallingUid();
8763                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8764                BatteryStatsImpl.Uid.Pkg pkg =
8765                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8766                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8767                pkg.incWakeupsLocked();
8768            }
8769        }
8770    }
8771
8772    public boolean killPids(int[] pids, String pReason, boolean secure) {
8773        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8774            throw new SecurityException("killPids only available to the system");
8775        }
8776        String reason = (pReason == null) ? "Unknown" : pReason;
8777        // XXX Note: don't acquire main activity lock here, because the window
8778        // manager calls in with its locks held.
8779
8780        boolean killed = false;
8781        synchronized (mPidsSelfLocked) {
8782            int[] types = new int[pids.length];
8783            int worstType = 0;
8784            for (int i=0; i<pids.length; i++) {
8785                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8786                if (proc != null) {
8787                    int type = proc.setAdj;
8788                    types[i] = type;
8789                    if (type > worstType) {
8790                        worstType = type;
8791                    }
8792                }
8793            }
8794
8795            // If the worst oom_adj is somewhere in the cached proc LRU range,
8796            // then constrain it so we will kill all cached procs.
8797            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8798                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8799                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8800            }
8801
8802            // If this is not a secure call, don't let it kill processes that
8803            // are important.
8804            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8805                worstType = ProcessList.SERVICE_ADJ;
8806            }
8807
8808            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8809            for (int i=0; i<pids.length; i++) {
8810                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8811                if (proc == null) {
8812                    continue;
8813                }
8814                int adj = proc.setAdj;
8815                if (adj >= worstType && !proc.killedByAm) {
8816                    killUnneededProcessLocked(proc, reason);
8817                    killed = true;
8818                }
8819            }
8820        }
8821        return killed;
8822    }
8823
8824    @Override
8825    public void killUid(int uid, String reason) {
8826        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8827            throw new SecurityException("killUid only available to the system");
8828        }
8829        synchronized (this) {
8830            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8831                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8832                    reason != null ? reason : "kill uid");
8833        }
8834    }
8835
8836    @Override
8837    public boolean killProcessesBelowForeground(String reason) {
8838        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8839            throw new SecurityException("killProcessesBelowForeground() only available to system");
8840        }
8841
8842        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8843    }
8844
8845    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8846        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8847            throw new SecurityException("killProcessesBelowAdj() only available to system");
8848        }
8849
8850        boolean killed = false;
8851        synchronized (mPidsSelfLocked) {
8852            final int size = mPidsSelfLocked.size();
8853            for (int i = 0; i < size; i++) {
8854                final int pid = mPidsSelfLocked.keyAt(i);
8855                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8856                if (proc == null) continue;
8857
8858                final int adj = proc.setAdj;
8859                if (adj > belowAdj && !proc.killedByAm) {
8860                    killUnneededProcessLocked(proc, reason);
8861                    killed = true;
8862                }
8863            }
8864        }
8865        return killed;
8866    }
8867
8868    @Override
8869    public void hang(final IBinder who, boolean allowRestart) {
8870        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8871                != PackageManager.PERMISSION_GRANTED) {
8872            throw new SecurityException("Requires permission "
8873                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8874        }
8875
8876        final IBinder.DeathRecipient death = new DeathRecipient() {
8877            @Override
8878            public void binderDied() {
8879                synchronized (this) {
8880                    notifyAll();
8881                }
8882            }
8883        };
8884
8885        try {
8886            who.linkToDeath(death, 0);
8887        } catch (RemoteException e) {
8888            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8889            return;
8890        }
8891
8892        synchronized (this) {
8893            Watchdog.getInstance().setAllowRestart(allowRestart);
8894            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8895            synchronized (death) {
8896                while (who.isBinderAlive()) {
8897                    try {
8898                        death.wait();
8899                    } catch (InterruptedException e) {
8900                    }
8901                }
8902            }
8903            Watchdog.getInstance().setAllowRestart(true);
8904        }
8905    }
8906
8907    @Override
8908    public void restart() {
8909        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8910                != PackageManager.PERMISSION_GRANTED) {
8911            throw new SecurityException("Requires permission "
8912                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8913        }
8914
8915        Log.i(TAG, "Sending shutdown broadcast...");
8916
8917        BroadcastReceiver br = new BroadcastReceiver() {
8918            @Override public void onReceive(Context context, Intent intent) {
8919                // Now the broadcast is done, finish up the low-level shutdown.
8920                Log.i(TAG, "Shutting down activity manager...");
8921                shutdown(10000);
8922                Log.i(TAG, "Shutdown complete, restarting!");
8923                Process.killProcess(Process.myPid());
8924                System.exit(10);
8925            }
8926        };
8927
8928        // First send the high-level shut down broadcast.
8929        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8930        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8931        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8932        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8933        mContext.sendOrderedBroadcastAsUser(intent,
8934                UserHandle.ALL, null, br, mHandler, 0, null, null);
8935        */
8936        br.onReceive(mContext, intent);
8937    }
8938
8939    private long getLowRamTimeSinceIdle(long now) {
8940        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8941    }
8942
8943    @Override
8944    public void performIdleMaintenance() {
8945        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8946                != PackageManager.PERMISSION_GRANTED) {
8947            throw new SecurityException("Requires permission "
8948                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8949        }
8950
8951        synchronized (this) {
8952            final long now = SystemClock.uptimeMillis();
8953            final long timeSinceLastIdle = now - mLastIdleTime;
8954            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8955            mLastIdleTime = now;
8956            mLowRamTimeSinceLastIdle = 0;
8957            if (mLowRamStartTime != 0) {
8958                mLowRamStartTime = now;
8959            }
8960
8961            StringBuilder sb = new StringBuilder(128);
8962            sb.append("Idle maintenance over ");
8963            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8964            sb.append(" low RAM for ");
8965            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8966            Slog.i(TAG, sb.toString());
8967
8968            // If at least 1/3 of our time since the last idle period has been spent
8969            // with RAM low, then we want to kill processes.
8970            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8971
8972            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8973                ProcessRecord proc = mLruProcesses.get(i);
8974                if (proc.notCachedSinceIdle) {
8975                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8976                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8977                        if (doKilling && proc.initialIdlePss != 0
8978                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8979                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8980                                    + " from " + proc.initialIdlePss + ")");
8981                        }
8982                    }
8983                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8984                    proc.notCachedSinceIdle = true;
8985                    proc.initialIdlePss = 0;
8986                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8987                            mSleeping, now);
8988                }
8989            }
8990
8991            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8992            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8993        }
8994    }
8995
8996    public final void startRunning(String pkg, String cls, String action,
8997            String data) {
8998        synchronized(this) {
8999            if (mStartRunning) {
9000                return;
9001            }
9002            mStartRunning = true;
9003            mTopComponent = pkg != null && cls != null
9004                    ? new ComponentName(pkg, cls) : null;
9005            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9006            mTopData = data;
9007            if (!mSystemReady) {
9008                return;
9009            }
9010        }
9011
9012        systemReady(null);
9013    }
9014
9015    private void retrieveSettings() {
9016        final ContentResolver resolver = mContext.getContentResolver();
9017        String debugApp = Settings.Global.getString(
9018            resolver, Settings.Global.DEBUG_APP);
9019        boolean waitForDebugger = Settings.Global.getInt(
9020            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9021        boolean alwaysFinishActivities = Settings.Global.getInt(
9022            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9023        boolean forceRtl = Settings.Global.getInt(
9024                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9025        // Transfer any global setting for forcing RTL layout, into a System Property
9026        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9027
9028        Configuration configuration = new Configuration();
9029        Settings.System.getConfiguration(resolver, configuration);
9030        if (forceRtl) {
9031            // This will take care of setting the correct layout direction flags
9032            configuration.setLayoutDirection(configuration.locale);
9033        }
9034
9035        synchronized (this) {
9036            mDebugApp = mOrigDebugApp = debugApp;
9037            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9038            mAlwaysFinishActivities = alwaysFinishActivities;
9039            // This happens before any activities are started, so we can
9040            // change mConfiguration in-place.
9041            updateConfigurationLocked(configuration, null, false, true);
9042            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9043        }
9044    }
9045
9046    public boolean testIsSystemReady() {
9047        // no need to synchronize(this) just to read & return the value
9048        return mSystemReady;
9049    }
9050
9051    private static File getCalledPreBootReceiversFile() {
9052        File dataDir = Environment.getDataDirectory();
9053        File systemDir = new File(dataDir, "system");
9054        File fname = new File(systemDir, "called_pre_boots.dat");
9055        return fname;
9056    }
9057
9058    static final int LAST_DONE_VERSION = 10000;
9059
9060    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9061        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9062        File file = getCalledPreBootReceiversFile();
9063        FileInputStream fis = null;
9064        try {
9065            fis = new FileInputStream(file);
9066            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9067            int fvers = dis.readInt();
9068            if (fvers == LAST_DONE_VERSION) {
9069                String vers = dis.readUTF();
9070                String codename = dis.readUTF();
9071                String build = dis.readUTF();
9072                if (android.os.Build.VERSION.RELEASE.equals(vers)
9073                        && android.os.Build.VERSION.CODENAME.equals(codename)
9074                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9075                    int num = dis.readInt();
9076                    while (num > 0) {
9077                        num--;
9078                        String pkg = dis.readUTF();
9079                        String cls = dis.readUTF();
9080                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9081                    }
9082                }
9083            }
9084        } catch (FileNotFoundException e) {
9085        } catch (IOException e) {
9086            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9087        } finally {
9088            if (fis != null) {
9089                try {
9090                    fis.close();
9091                } catch (IOException e) {
9092                }
9093            }
9094        }
9095        return lastDoneReceivers;
9096    }
9097
9098    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9099        File file = getCalledPreBootReceiversFile();
9100        FileOutputStream fos = null;
9101        DataOutputStream dos = null;
9102        try {
9103            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9104            fos = new FileOutputStream(file);
9105            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9106            dos.writeInt(LAST_DONE_VERSION);
9107            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9108            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9109            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9110            dos.writeInt(list.size());
9111            for (int i=0; i<list.size(); i++) {
9112                dos.writeUTF(list.get(i).getPackageName());
9113                dos.writeUTF(list.get(i).getClassName());
9114            }
9115        } catch (IOException e) {
9116            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9117            file.delete();
9118        } finally {
9119            FileUtils.sync(fos);
9120            if (dos != null) {
9121                try {
9122                    dos.close();
9123                } catch (IOException e) {
9124                    // TODO Auto-generated catch block
9125                    e.printStackTrace();
9126                }
9127            }
9128        }
9129    }
9130
9131    public void systemReady(final Runnable goingCallback) {
9132        synchronized(this) {
9133            if (mSystemReady) {
9134                if (goingCallback != null) goingCallback.run();
9135                return;
9136            }
9137
9138            // Check to see if there are any update receivers to run.
9139            if (!mDidUpdate) {
9140                if (mWaitingUpdate) {
9141                    return;
9142                }
9143                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9144                List<ResolveInfo> ris = null;
9145                try {
9146                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9147                            intent, null, 0, 0);
9148                } catch (RemoteException e) {
9149                }
9150                if (ris != null) {
9151                    for (int i=ris.size()-1; i>=0; i--) {
9152                        if ((ris.get(i).activityInfo.applicationInfo.flags
9153                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9154                            ris.remove(i);
9155                        }
9156                    }
9157                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9158
9159                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9160
9161                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9162                    for (int i=0; i<ris.size(); i++) {
9163                        ActivityInfo ai = ris.get(i).activityInfo;
9164                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9165                        if (lastDoneReceivers.contains(comp)) {
9166                            ris.remove(i);
9167                            i--;
9168                        }
9169                    }
9170
9171                    final int[] users = getUsersLocked();
9172                    for (int i=0; i<ris.size(); i++) {
9173                        ActivityInfo ai = ris.get(i).activityInfo;
9174                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9175                        doneReceivers.add(comp);
9176                        intent.setComponent(comp);
9177                        for (int j=0; j<users.length; j++) {
9178                            IIntentReceiver finisher = null;
9179                            if (i == ris.size()-1 && j == users.length-1) {
9180                                finisher = new IIntentReceiver.Stub() {
9181                                    public void performReceive(Intent intent, int resultCode,
9182                                            String data, Bundle extras, boolean ordered,
9183                                            boolean sticky, int sendingUser) {
9184                                        // The raw IIntentReceiver interface is called
9185                                        // with the AM lock held, so redispatch to
9186                                        // execute our code without the lock.
9187                                        mHandler.post(new Runnable() {
9188                                            public void run() {
9189                                                synchronized (ActivityManagerService.this) {
9190                                                    mDidUpdate = true;
9191                                                }
9192                                                writeLastDonePreBootReceivers(doneReceivers);
9193                                                showBootMessage(mContext.getText(
9194                                                        R.string.android_upgrading_complete),
9195                                                        false);
9196                                                systemReady(goingCallback);
9197                                            }
9198                                        });
9199                                    }
9200                                };
9201                            }
9202                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9203                                    + " for user " + users[j]);
9204                            broadcastIntentLocked(null, null, intent, null, finisher,
9205                                    0, null, null, null, AppOpsManager.OP_NONE,
9206                                    true, false, MY_PID, Process.SYSTEM_UID,
9207                                    users[j]);
9208                            if (finisher != null) {
9209                                mWaitingUpdate = true;
9210                            }
9211                        }
9212                    }
9213                }
9214                if (mWaitingUpdate) {
9215                    return;
9216                }
9217                mDidUpdate = true;
9218            }
9219
9220            mAppOpsService.systemReady();
9221            mSystemReady = true;
9222            if (!mStartRunning) {
9223                return;
9224            }
9225        }
9226
9227        ArrayList<ProcessRecord> procsToKill = null;
9228        synchronized(mPidsSelfLocked) {
9229            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9230                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9231                if (!isAllowedWhileBooting(proc.info)){
9232                    if (procsToKill == null) {
9233                        procsToKill = new ArrayList<ProcessRecord>();
9234                    }
9235                    procsToKill.add(proc);
9236                }
9237            }
9238        }
9239
9240        synchronized(this) {
9241            if (procsToKill != null) {
9242                for (int i=procsToKill.size()-1; i>=0; i--) {
9243                    ProcessRecord proc = procsToKill.get(i);
9244                    Slog.i(TAG, "Removing system update proc: " + proc);
9245                    removeProcessLocked(proc, true, false, "system update done");
9246                }
9247            }
9248
9249            // Now that we have cleaned up any update processes, we
9250            // are ready to start launching real processes and know that
9251            // we won't trample on them any more.
9252            mProcessesReady = true;
9253        }
9254
9255        Slog.i(TAG, "System now ready");
9256        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9257            SystemClock.uptimeMillis());
9258
9259        synchronized(this) {
9260            // Make sure we have no pre-ready processes sitting around.
9261
9262            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9263                ResolveInfo ri = mContext.getPackageManager()
9264                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9265                                STOCK_PM_FLAGS);
9266                CharSequence errorMsg = null;
9267                if (ri != null) {
9268                    ActivityInfo ai = ri.activityInfo;
9269                    ApplicationInfo app = ai.applicationInfo;
9270                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9271                        mTopAction = Intent.ACTION_FACTORY_TEST;
9272                        mTopData = null;
9273                        mTopComponent = new ComponentName(app.packageName,
9274                                ai.name);
9275                    } else {
9276                        errorMsg = mContext.getResources().getText(
9277                                com.android.internal.R.string.factorytest_not_system);
9278                    }
9279                } else {
9280                    errorMsg = mContext.getResources().getText(
9281                            com.android.internal.R.string.factorytest_no_action);
9282                }
9283                if (errorMsg != null) {
9284                    mTopAction = null;
9285                    mTopData = null;
9286                    mTopComponent = null;
9287                    Message msg = Message.obtain();
9288                    msg.what = SHOW_FACTORY_ERROR_MSG;
9289                    msg.getData().putCharSequence("msg", errorMsg);
9290                    mHandler.sendMessage(msg);
9291                }
9292            }
9293        }
9294
9295        retrieveSettings();
9296
9297        synchronized (this) {
9298            readGrantedUriPermissionsLocked();
9299        }
9300
9301        if (goingCallback != null) goingCallback.run();
9302
9303        synchronized (this) {
9304            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9305                try {
9306                    List apps = AppGlobals.getPackageManager().
9307                        getPersistentApplications(STOCK_PM_FLAGS);
9308                    if (apps != null) {
9309                        int N = apps.size();
9310                        int i;
9311                        for (i=0; i<N; i++) {
9312                            ApplicationInfo info
9313                                = (ApplicationInfo)apps.get(i);
9314                            if (info != null &&
9315                                    !info.packageName.equals("android")) {
9316                                addAppLocked(info, false);
9317                            }
9318                        }
9319                    }
9320                } catch (RemoteException ex) {
9321                    // pm is in same process, this will never happen.
9322                }
9323            }
9324
9325            // Start up initial activity.
9326            mBooting = true;
9327
9328            try {
9329                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9330                    Message msg = Message.obtain();
9331                    msg.what = SHOW_UID_ERROR_MSG;
9332                    mHandler.sendMessage(msg);
9333                }
9334            } catch (RemoteException e) {
9335            }
9336
9337            long ident = Binder.clearCallingIdentity();
9338            try {
9339                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9340                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9341                        | Intent.FLAG_RECEIVER_FOREGROUND);
9342                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9343                broadcastIntentLocked(null, null, intent,
9344                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9345                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9346                intent = new Intent(Intent.ACTION_USER_STARTING);
9347                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9348                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9349                broadcastIntentLocked(null, null, intent,
9350                        null, new IIntentReceiver.Stub() {
9351                            @Override
9352                            public void performReceive(Intent intent, int resultCode, String data,
9353                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9354                                    throws RemoteException {
9355                            }
9356                        }, 0, null, null,
9357                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9358                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9359            } finally {
9360                Binder.restoreCallingIdentity(ident);
9361            }
9362            mStackSupervisor.resumeTopActivitiesLocked();
9363            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9364        }
9365    }
9366
9367    private boolean makeAppCrashingLocked(ProcessRecord app,
9368            String shortMsg, String longMsg, String stackTrace) {
9369        app.crashing = true;
9370        app.crashingReport = generateProcessError(app,
9371                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9372        startAppProblemLocked(app);
9373        app.stopFreezingAllLocked();
9374        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9375    }
9376
9377    private void makeAppNotRespondingLocked(ProcessRecord app,
9378            String activity, String shortMsg, String longMsg) {
9379        app.notResponding = true;
9380        app.notRespondingReport = generateProcessError(app,
9381                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9382                activity, shortMsg, longMsg, null);
9383        startAppProblemLocked(app);
9384        app.stopFreezingAllLocked();
9385    }
9386
9387    /**
9388     * Generate a process error record, suitable for attachment to a ProcessRecord.
9389     *
9390     * @param app The ProcessRecord in which the error occurred.
9391     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9392     *                      ActivityManager.AppErrorStateInfo
9393     * @param activity The activity associated with the crash, if known.
9394     * @param shortMsg Short message describing the crash.
9395     * @param longMsg Long message describing the crash.
9396     * @param stackTrace Full crash stack trace, may be null.
9397     *
9398     * @return Returns a fully-formed AppErrorStateInfo record.
9399     */
9400    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9401            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9402        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9403
9404        report.condition = condition;
9405        report.processName = app.processName;
9406        report.pid = app.pid;
9407        report.uid = app.info.uid;
9408        report.tag = activity;
9409        report.shortMsg = shortMsg;
9410        report.longMsg = longMsg;
9411        report.stackTrace = stackTrace;
9412
9413        return report;
9414    }
9415
9416    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9417        synchronized (this) {
9418            app.crashing = false;
9419            app.crashingReport = null;
9420            app.notResponding = false;
9421            app.notRespondingReport = null;
9422            if (app.anrDialog == fromDialog) {
9423                app.anrDialog = null;
9424            }
9425            if (app.waitDialog == fromDialog) {
9426                app.waitDialog = null;
9427            }
9428            if (app.pid > 0 && app.pid != MY_PID) {
9429                handleAppCrashLocked(app, null, null, null);
9430                killUnneededProcessLocked(app, "user request after error");
9431            }
9432        }
9433    }
9434
9435    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9436            String stackTrace) {
9437        long now = SystemClock.uptimeMillis();
9438
9439        Long crashTime;
9440        if (!app.isolated) {
9441            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9442        } else {
9443            crashTime = null;
9444        }
9445        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9446            // This process loses!
9447            Slog.w(TAG, "Process " + app.info.processName
9448                    + " has crashed too many times: killing!");
9449            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9450                    app.userId, app.info.processName, app.uid);
9451            mStackSupervisor.handleAppCrashLocked(app);
9452            if (!app.persistent) {
9453                // We don't want to start this process again until the user
9454                // explicitly does so...  but for persistent process, we really
9455                // need to keep it running.  If a persistent process is actually
9456                // repeatedly crashing, then badness for everyone.
9457                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9458                        app.info.processName);
9459                if (!app.isolated) {
9460                    // XXX We don't have a way to mark isolated processes
9461                    // as bad, since they don't have a peristent identity.
9462                    mBadProcesses.put(app.info.processName, app.uid,
9463                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9464                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9465                }
9466                app.bad = true;
9467                app.removed = true;
9468                // Don't let services in this process be restarted and potentially
9469                // annoy the user repeatedly.  Unless it is persistent, since those
9470                // processes run critical code.
9471                removeProcessLocked(app, false, false, "crash");
9472                mStackSupervisor.resumeTopActivitiesLocked();
9473                return false;
9474            }
9475            mStackSupervisor.resumeTopActivitiesLocked();
9476        } else {
9477            mStackSupervisor.finishTopRunningActivityLocked(app);
9478        }
9479
9480        // Bump up the crash count of any services currently running in the proc.
9481        for (int i=app.services.size()-1; i>=0; i--) {
9482            // Any services running in the application need to be placed
9483            // back in the pending list.
9484            ServiceRecord sr = app.services.valueAt(i);
9485            sr.crashCount++;
9486        }
9487
9488        // If the crashing process is what we consider to be the "home process" and it has been
9489        // replaced by a third-party app, clear the package preferred activities from packages
9490        // with a home activity running in the process to prevent a repeatedly crashing app
9491        // from blocking the user to manually clear the list.
9492        final ArrayList<ActivityRecord> activities = app.activities;
9493        if (app == mHomeProcess && activities.size() > 0
9494                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9495            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9496                final ActivityRecord r = activities.get(activityNdx);
9497                if (r.isHomeActivity()) {
9498                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9499                    try {
9500                        ActivityThread.getPackageManager()
9501                                .clearPackagePreferredActivities(r.packageName);
9502                    } catch (RemoteException c) {
9503                        // pm is in same process, this will never happen.
9504                    }
9505                }
9506            }
9507        }
9508
9509        if (!app.isolated) {
9510            // XXX Can't keep track of crash times for isolated processes,
9511            // because they don't have a perisistent identity.
9512            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9513        }
9514
9515        return true;
9516    }
9517
9518    void startAppProblemLocked(ProcessRecord app) {
9519        if (app.userId == mCurrentUserId) {
9520            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9521                    mContext, app.info.packageName, app.info.flags);
9522        } else {
9523            // If this app is not running under the current user, then we
9524            // can't give it a report button because that would require
9525            // launching the report UI under a different user.
9526            app.errorReportReceiver = null;
9527        }
9528        skipCurrentReceiverLocked(app);
9529    }
9530
9531    void skipCurrentReceiverLocked(ProcessRecord app) {
9532        for (BroadcastQueue queue : mBroadcastQueues) {
9533            queue.skipCurrentReceiverLocked(app);
9534        }
9535    }
9536
9537    /**
9538     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9539     * The application process will exit immediately after this call returns.
9540     * @param app object of the crashing app, null for the system server
9541     * @param crashInfo describing the exception
9542     */
9543    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9544        ProcessRecord r = findAppProcess(app, "Crash");
9545        final String processName = app == null ? "system_server"
9546                : (r == null ? "unknown" : r.processName);
9547
9548        handleApplicationCrashInner("crash", r, processName, crashInfo);
9549    }
9550
9551    /* Native crash reporting uses this inner version because it needs to be somewhat
9552     * decoupled from the AM-managed cleanup lifecycle
9553     */
9554    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9555            ApplicationErrorReport.CrashInfo crashInfo) {
9556        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9557                UserHandle.getUserId(Binder.getCallingUid()), processName,
9558                r == null ? -1 : r.info.flags,
9559                crashInfo.exceptionClassName,
9560                crashInfo.exceptionMessage,
9561                crashInfo.throwFileName,
9562                crashInfo.throwLineNumber);
9563
9564        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9565
9566        crashApplication(r, crashInfo);
9567    }
9568
9569    public void handleApplicationStrictModeViolation(
9570            IBinder app,
9571            int violationMask,
9572            StrictMode.ViolationInfo info) {
9573        ProcessRecord r = findAppProcess(app, "StrictMode");
9574        if (r == null) {
9575            return;
9576        }
9577
9578        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9579            Integer stackFingerprint = info.hashCode();
9580            boolean logIt = true;
9581            synchronized (mAlreadyLoggedViolatedStacks) {
9582                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9583                    logIt = false;
9584                    // TODO: sub-sample into EventLog for these, with
9585                    // the info.durationMillis?  Then we'd get
9586                    // the relative pain numbers, without logging all
9587                    // the stack traces repeatedly.  We'd want to do
9588                    // likewise in the client code, which also does
9589                    // dup suppression, before the Binder call.
9590                } else {
9591                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9592                        mAlreadyLoggedViolatedStacks.clear();
9593                    }
9594                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9595                }
9596            }
9597            if (logIt) {
9598                logStrictModeViolationToDropBox(r, info);
9599            }
9600        }
9601
9602        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9603            AppErrorResult result = new AppErrorResult();
9604            synchronized (this) {
9605                final long origId = Binder.clearCallingIdentity();
9606
9607                Message msg = Message.obtain();
9608                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9609                HashMap<String, Object> data = new HashMap<String, Object>();
9610                data.put("result", result);
9611                data.put("app", r);
9612                data.put("violationMask", violationMask);
9613                data.put("info", info);
9614                msg.obj = data;
9615                mHandler.sendMessage(msg);
9616
9617                Binder.restoreCallingIdentity(origId);
9618            }
9619            int res = result.get();
9620            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9621        }
9622    }
9623
9624    // Depending on the policy in effect, there could be a bunch of
9625    // these in quick succession so we try to batch these together to
9626    // minimize disk writes, number of dropbox entries, and maximize
9627    // compression, by having more fewer, larger records.
9628    private void logStrictModeViolationToDropBox(
9629            ProcessRecord process,
9630            StrictMode.ViolationInfo info) {
9631        if (info == null) {
9632            return;
9633        }
9634        final boolean isSystemApp = process == null ||
9635                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9636                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9637        final String processName = process == null ? "unknown" : process.processName;
9638        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9639        final DropBoxManager dbox = (DropBoxManager)
9640                mContext.getSystemService(Context.DROPBOX_SERVICE);
9641
9642        // Exit early if the dropbox isn't configured to accept this report type.
9643        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9644
9645        boolean bufferWasEmpty;
9646        boolean needsFlush;
9647        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9648        synchronized (sb) {
9649            bufferWasEmpty = sb.length() == 0;
9650            appendDropBoxProcessHeaders(process, processName, sb);
9651            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9652            sb.append("System-App: ").append(isSystemApp).append("\n");
9653            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9654            if (info.violationNumThisLoop != 0) {
9655                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9656            }
9657            if (info.numAnimationsRunning != 0) {
9658                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9659            }
9660            if (info.broadcastIntentAction != null) {
9661                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9662            }
9663            if (info.durationMillis != -1) {
9664                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9665            }
9666            if (info.numInstances != -1) {
9667                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9668            }
9669            if (info.tags != null) {
9670                for (String tag : info.tags) {
9671                    sb.append("Span-Tag: ").append(tag).append("\n");
9672                }
9673            }
9674            sb.append("\n");
9675            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9676                sb.append(info.crashInfo.stackTrace);
9677            }
9678            sb.append("\n");
9679
9680            // Only buffer up to ~64k.  Various logging bits truncate
9681            // things at 128k.
9682            needsFlush = (sb.length() > 64 * 1024);
9683        }
9684
9685        // Flush immediately if the buffer's grown too large, or this
9686        // is a non-system app.  Non-system apps are isolated with a
9687        // different tag & policy and not batched.
9688        //
9689        // Batching is useful during internal testing with
9690        // StrictMode settings turned up high.  Without batching,
9691        // thousands of separate files could be created on boot.
9692        if (!isSystemApp || needsFlush) {
9693            new Thread("Error dump: " + dropboxTag) {
9694                @Override
9695                public void run() {
9696                    String report;
9697                    synchronized (sb) {
9698                        report = sb.toString();
9699                        sb.delete(0, sb.length());
9700                        sb.trimToSize();
9701                    }
9702                    if (report.length() != 0) {
9703                        dbox.addText(dropboxTag, report);
9704                    }
9705                }
9706            }.start();
9707            return;
9708        }
9709
9710        // System app batching:
9711        if (!bufferWasEmpty) {
9712            // An existing dropbox-writing thread is outstanding, so
9713            // we don't need to start it up.  The existing thread will
9714            // catch the buffer appends we just did.
9715            return;
9716        }
9717
9718        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9719        // (After this point, we shouldn't access AMS internal data structures.)
9720        new Thread("Error dump: " + dropboxTag) {
9721            @Override
9722            public void run() {
9723                // 5 second sleep to let stacks arrive and be batched together
9724                try {
9725                    Thread.sleep(5000);  // 5 seconds
9726                } catch (InterruptedException e) {}
9727
9728                String errorReport;
9729                synchronized (mStrictModeBuffer) {
9730                    errorReport = mStrictModeBuffer.toString();
9731                    if (errorReport.length() == 0) {
9732                        return;
9733                    }
9734                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9735                    mStrictModeBuffer.trimToSize();
9736                }
9737                dbox.addText(dropboxTag, errorReport);
9738            }
9739        }.start();
9740    }
9741
9742    /**
9743     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9744     * @param app object of the crashing app, null for the system server
9745     * @param tag reported by the caller
9746     * @param crashInfo describing the context of the error
9747     * @return true if the process should exit immediately (WTF is fatal)
9748     */
9749    public boolean handleApplicationWtf(IBinder app, String tag,
9750            ApplicationErrorReport.CrashInfo crashInfo) {
9751        ProcessRecord r = findAppProcess(app, "WTF");
9752        final String processName = app == null ? "system_server"
9753                : (r == null ? "unknown" : r.processName);
9754
9755        EventLog.writeEvent(EventLogTags.AM_WTF,
9756                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9757                processName,
9758                r == null ? -1 : r.info.flags,
9759                tag, crashInfo.exceptionMessage);
9760
9761        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9762
9763        if (r != null && r.pid != Process.myPid() &&
9764                Settings.Global.getInt(mContext.getContentResolver(),
9765                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9766            crashApplication(r, crashInfo);
9767            return true;
9768        } else {
9769            return false;
9770        }
9771    }
9772
9773    /**
9774     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9775     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9776     */
9777    private ProcessRecord findAppProcess(IBinder app, String reason) {
9778        if (app == null) {
9779            return null;
9780        }
9781
9782        synchronized (this) {
9783            final int NP = mProcessNames.getMap().size();
9784            for (int ip=0; ip<NP; ip++) {
9785                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9786                final int NA = apps.size();
9787                for (int ia=0; ia<NA; ia++) {
9788                    ProcessRecord p = apps.valueAt(ia);
9789                    if (p.thread != null && p.thread.asBinder() == app) {
9790                        return p;
9791                    }
9792                }
9793            }
9794
9795            Slog.w(TAG, "Can't find mystery application for " + reason
9796                    + " from pid=" + Binder.getCallingPid()
9797                    + " uid=" + Binder.getCallingUid() + ": " + app);
9798            return null;
9799        }
9800    }
9801
9802    /**
9803     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9804     * to append various headers to the dropbox log text.
9805     */
9806    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9807            StringBuilder sb) {
9808        // Watchdog thread ends up invoking this function (with
9809        // a null ProcessRecord) to add the stack file to dropbox.
9810        // Do not acquire a lock on this (am) in such cases, as it
9811        // could cause a potential deadlock, if and when watchdog
9812        // is invoked due to unavailability of lock on am and it
9813        // would prevent watchdog from killing system_server.
9814        if (process == null) {
9815            sb.append("Process: ").append(processName).append("\n");
9816            return;
9817        }
9818        // Note: ProcessRecord 'process' is guarded by the service
9819        // instance.  (notably process.pkgList, which could otherwise change
9820        // concurrently during execution of this method)
9821        synchronized (this) {
9822            sb.append("Process: ").append(processName).append("\n");
9823            int flags = process.info.flags;
9824            IPackageManager pm = AppGlobals.getPackageManager();
9825            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9826            for (int ip=0; ip<process.pkgList.size(); ip++) {
9827                String pkg = process.pkgList.keyAt(ip);
9828                sb.append("Package: ").append(pkg);
9829                try {
9830                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9831                    if (pi != null) {
9832                        sb.append(" v").append(pi.versionCode);
9833                        if (pi.versionName != null) {
9834                            sb.append(" (").append(pi.versionName).append(")");
9835                        }
9836                    }
9837                } catch (RemoteException e) {
9838                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9839                }
9840                sb.append("\n");
9841            }
9842        }
9843    }
9844
9845    private static String processClass(ProcessRecord process) {
9846        if (process == null || process.pid == MY_PID) {
9847            return "system_server";
9848        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9849            return "system_app";
9850        } else {
9851            return "data_app";
9852        }
9853    }
9854
9855    /**
9856     * Write a description of an error (crash, WTF, ANR) to the drop box.
9857     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9858     * @param process which caused the error, null means the system server
9859     * @param activity which triggered the error, null if unknown
9860     * @param parent activity related to the error, null if unknown
9861     * @param subject line related to the error, null if absent
9862     * @param report in long form describing the error, null if absent
9863     * @param logFile to include in the report, null if none
9864     * @param crashInfo giving an application stack trace, null if absent
9865     */
9866    public void addErrorToDropBox(String eventType,
9867            ProcessRecord process, String processName, ActivityRecord activity,
9868            ActivityRecord parent, String subject,
9869            final String report, final File logFile,
9870            final ApplicationErrorReport.CrashInfo crashInfo) {
9871        // NOTE -- this must never acquire the ActivityManagerService lock,
9872        // otherwise the watchdog may be prevented from resetting the system.
9873
9874        final String dropboxTag = processClass(process) + "_" + eventType;
9875        final DropBoxManager dbox = (DropBoxManager)
9876                mContext.getSystemService(Context.DROPBOX_SERVICE);
9877
9878        // Exit early if the dropbox isn't configured to accept this report type.
9879        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9880
9881        final StringBuilder sb = new StringBuilder(1024);
9882        appendDropBoxProcessHeaders(process, processName, sb);
9883        if (activity != null) {
9884            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9885        }
9886        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9887            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9888        }
9889        if (parent != null && parent != activity) {
9890            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9891        }
9892        if (subject != null) {
9893            sb.append("Subject: ").append(subject).append("\n");
9894        }
9895        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9896        if (Debug.isDebuggerConnected()) {
9897            sb.append("Debugger: Connected\n");
9898        }
9899        sb.append("\n");
9900
9901        // Do the rest in a worker thread to avoid blocking the caller on I/O
9902        // (After this point, we shouldn't access AMS internal data structures.)
9903        Thread worker = new Thread("Error dump: " + dropboxTag) {
9904            @Override
9905            public void run() {
9906                if (report != null) {
9907                    sb.append(report);
9908                }
9909                if (logFile != null) {
9910                    try {
9911                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9912                                    "\n\n[[TRUNCATED]]"));
9913                    } catch (IOException e) {
9914                        Slog.e(TAG, "Error reading " + logFile, e);
9915                    }
9916                }
9917                if (crashInfo != null && crashInfo.stackTrace != null) {
9918                    sb.append(crashInfo.stackTrace);
9919                }
9920
9921                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9922                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9923                if (lines > 0) {
9924                    sb.append("\n");
9925
9926                    // Merge several logcat streams, and take the last N lines
9927                    InputStreamReader input = null;
9928                    try {
9929                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9930                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9931                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9932
9933                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9934                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9935                        input = new InputStreamReader(logcat.getInputStream());
9936
9937                        int num;
9938                        char[] buf = new char[8192];
9939                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9940                    } catch (IOException e) {
9941                        Slog.e(TAG, "Error running logcat", e);
9942                    } finally {
9943                        if (input != null) try { input.close(); } catch (IOException e) {}
9944                    }
9945                }
9946
9947                dbox.addText(dropboxTag, sb.toString());
9948            }
9949        };
9950
9951        if (process == null) {
9952            // If process is null, we are being called from some internal code
9953            // and may be about to die -- run this synchronously.
9954            worker.run();
9955        } else {
9956            worker.start();
9957        }
9958    }
9959
9960    /**
9961     * Bring up the "unexpected error" dialog box for a crashing app.
9962     * Deal with edge cases (intercepts from instrumented applications,
9963     * ActivityController, error intent receivers, that sort of thing).
9964     * @param r the application crashing
9965     * @param crashInfo describing the failure
9966     */
9967    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9968        long timeMillis = System.currentTimeMillis();
9969        String shortMsg = crashInfo.exceptionClassName;
9970        String longMsg = crashInfo.exceptionMessage;
9971        String stackTrace = crashInfo.stackTrace;
9972        if (shortMsg != null && longMsg != null) {
9973            longMsg = shortMsg + ": " + longMsg;
9974        } else if (shortMsg != null) {
9975            longMsg = shortMsg;
9976        }
9977
9978        AppErrorResult result = new AppErrorResult();
9979        synchronized (this) {
9980            if (mController != null) {
9981                try {
9982                    String name = r != null ? r.processName : null;
9983                    int pid = r != null ? r.pid : Binder.getCallingPid();
9984                    if (!mController.appCrashed(name, pid,
9985                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9986                        Slog.w(TAG, "Force-killing crashed app " + name
9987                                + " at watcher's request");
9988                        Process.killProcess(pid);
9989                        return;
9990                    }
9991                } catch (RemoteException e) {
9992                    mController = null;
9993                    Watchdog.getInstance().setActivityController(null);
9994                }
9995            }
9996
9997            final long origId = Binder.clearCallingIdentity();
9998
9999            // If this process is running instrumentation, finish it.
10000            if (r != null && r.instrumentationClass != null) {
10001                Slog.w(TAG, "Error in app " + r.processName
10002                      + " running instrumentation " + r.instrumentationClass + ":");
10003                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10004                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10005                Bundle info = new Bundle();
10006                info.putString("shortMsg", shortMsg);
10007                info.putString("longMsg", longMsg);
10008                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10009                Binder.restoreCallingIdentity(origId);
10010                return;
10011            }
10012
10013            // If we can't identify the process or it's already exceeded its crash quota,
10014            // quit right away without showing a crash dialog.
10015            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10016                Binder.restoreCallingIdentity(origId);
10017                return;
10018            }
10019
10020            Message msg = Message.obtain();
10021            msg.what = SHOW_ERROR_MSG;
10022            HashMap data = new HashMap();
10023            data.put("result", result);
10024            data.put("app", r);
10025            msg.obj = data;
10026            mHandler.sendMessage(msg);
10027
10028            Binder.restoreCallingIdentity(origId);
10029        }
10030
10031        int res = result.get();
10032
10033        Intent appErrorIntent = null;
10034        synchronized (this) {
10035            if (r != null && !r.isolated) {
10036                // XXX Can't keep track of crash time for isolated processes,
10037                // since they don't have a persistent identity.
10038                mProcessCrashTimes.put(r.info.processName, r.uid,
10039                        SystemClock.uptimeMillis());
10040            }
10041            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10042                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10043            }
10044        }
10045
10046        if (appErrorIntent != null) {
10047            try {
10048                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10049            } catch (ActivityNotFoundException e) {
10050                Slog.w(TAG, "bug report receiver dissappeared", e);
10051            }
10052        }
10053    }
10054
10055    Intent createAppErrorIntentLocked(ProcessRecord r,
10056            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10057        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10058        if (report == null) {
10059            return null;
10060        }
10061        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10062        result.setComponent(r.errorReportReceiver);
10063        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10064        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10065        return result;
10066    }
10067
10068    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10069            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10070        if (r.errorReportReceiver == null) {
10071            return null;
10072        }
10073
10074        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10075            return null;
10076        }
10077
10078        ApplicationErrorReport report = new ApplicationErrorReport();
10079        report.packageName = r.info.packageName;
10080        report.installerPackageName = r.errorReportReceiver.getPackageName();
10081        report.processName = r.processName;
10082        report.time = timeMillis;
10083        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10084
10085        if (r.crashing || r.forceCrashReport) {
10086            report.type = ApplicationErrorReport.TYPE_CRASH;
10087            report.crashInfo = crashInfo;
10088        } else if (r.notResponding) {
10089            report.type = ApplicationErrorReport.TYPE_ANR;
10090            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10091
10092            report.anrInfo.activity = r.notRespondingReport.tag;
10093            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10094            report.anrInfo.info = r.notRespondingReport.longMsg;
10095        }
10096
10097        return report;
10098    }
10099
10100    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10101        enforceNotIsolatedCaller("getProcessesInErrorState");
10102        // assume our apps are happy - lazy create the list
10103        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10104
10105        final boolean allUsers = ActivityManager.checkUidPermission(
10106                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10107                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10108        int userId = UserHandle.getUserId(Binder.getCallingUid());
10109
10110        synchronized (this) {
10111
10112            // iterate across all processes
10113            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10114                ProcessRecord app = mLruProcesses.get(i);
10115                if (!allUsers && app.userId != userId) {
10116                    continue;
10117                }
10118                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10119                    // This one's in trouble, so we'll generate a report for it
10120                    // crashes are higher priority (in case there's a crash *and* an anr)
10121                    ActivityManager.ProcessErrorStateInfo report = null;
10122                    if (app.crashing) {
10123                        report = app.crashingReport;
10124                    } else if (app.notResponding) {
10125                        report = app.notRespondingReport;
10126                    }
10127
10128                    if (report != null) {
10129                        if (errList == null) {
10130                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10131                        }
10132                        errList.add(report);
10133                    } else {
10134                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10135                                " crashing = " + app.crashing +
10136                                " notResponding = " + app.notResponding);
10137                    }
10138                }
10139            }
10140        }
10141
10142        return errList;
10143    }
10144
10145    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10146        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10147            if (currApp != null) {
10148                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10149            }
10150            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10151        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10152            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10153        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10154            if (currApp != null) {
10155                currApp.lru = 0;
10156            }
10157            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10158        } else if (adj >= ProcessList.SERVICE_ADJ) {
10159            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10160        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10161            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10162        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10163            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10164        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10165            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10166        } else {
10167            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10168        }
10169    }
10170
10171    private void fillInProcMemInfo(ProcessRecord app,
10172            ActivityManager.RunningAppProcessInfo outInfo) {
10173        outInfo.pid = app.pid;
10174        outInfo.uid = app.info.uid;
10175        if (mHeavyWeightProcess == app) {
10176            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10177        }
10178        if (app.persistent) {
10179            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10180        }
10181        if (app.activities.size() > 0) {
10182            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10183        }
10184        outInfo.lastTrimLevel = app.trimMemoryLevel;
10185        int adj = app.curAdj;
10186        outInfo.importance = oomAdjToImportance(adj, outInfo);
10187        outInfo.importanceReasonCode = app.adjTypeCode;
10188    }
10189
10190    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10191        enforceNotIsolatedCaller("getRunningAppProcesses");
10192        // Lazy instantiation of list
10193        List<ActivityManager.RunningAppProcessInfo> runList = null;
10194        final boolean allUsers = ActivityManager.checkUidPermission(
10195                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10196                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10197        int userId = UserHandle.getUserId(Binder.getCallingUid());
10198        synchronized (this) {
10199            // Iterate across all processes
10200            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10201                ProcessRecord app = mLruProcesses.get(i);
10202                if (!allUsers && app.userId != userId) {
10203                    continue;
10204                }
10205                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10206                    // Generate process state info for running application
10207                    ActivityManager.RunningAppProcessInfo currApp =
10208                        new ActivityManager.RunningAppProcessInfo(app.processName,
10209                                app.pid, app.getPackageList());
10210                    fillInProcMemInfo(app, currApp);
10211                    if (app.adjSource instanceof ProcessRecord) {
10212                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10213                        currApp.importanceReasonImportance = oomAdjToImportance(
10214                                app.adjSourceOom, null);
10215                    } else if (app.adjSource instanceof ActivityRecord) {
10216                        ActivityRecord r = (ActivityRecord)app.adjSource;
10217                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10218                    }
10219                    if (app.adjTarget instanceof ComponentName) {
10220                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10221                    }
10222                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10223                    //        + " lru=" + currApp.lru);
10224                    if (runList == null) {
10225                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10226                    }
10227                    runList.add(currApp);
10228                }
10229            }
10230        }
10231        return runList;
10232    }
10233
10234    public List<ApplicationInfo> getRunningExternalApplications() {
10235        enforceNotIsolatedCaller("getRunningExternalApplications");
10236        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10237        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10238        if (runningApps != null && runningApps.size() > 0) {
10239            Set<String> extList = new HashSet<String>();
10240            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10241                if (app.pkgList != null) {
10242                    for (String pkg : app.pkgList) {
10243                        extList.add(pkg);
10244                    }
10245                }
10246            }
10247            IPackageManager pm = AppGlobals.getPackageManager();
10248            for (String pkg : extList) {
10249                try {
10250                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10251                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10252                        retList.add(info);
10253                    }
10254                } catch (RemoteException e) {
10255                }
10256            }
10257        }
10258        return retList;
10259    }
10260
10261    @Override
10262    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10263        enforceNotIsolatedCaller("getMyMemoryState");
10264        synchronized (this) {
10265            ProcessRecord proc;
10266            synchronized (mPidsSelfLocked) {
10267                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10268            }
10269            fillInProcMemInfo(proc, outInfo);
10270        }
10271    }
10272
10273    @Override
10274    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10275        if (checkCallingPermission(android.Manifest.permission.DUMP)
10276                != PackageManager.PERMISSION_GRANTED) {
10277            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10278                    + Binder.getCallingPid()
10279                    + ", uid=" + Binder.getCallingUid()
10280                    + " without permission "
10281                    + android.Manifest.permission.DUMP);
10282            return;
10283        }
10284
10285        boolean dumpAll = false;
10286        boolean dumpClient = false;
10287        String dumpPackage = null;
10288
10289        int opti = 0;
10290        while (opti < args.length) {
10291            String opt = args[opti];
10292            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10293                break;
10294            }
10295            opti++;
10296            if ("-a".equals(opt)) {
10297                dumpAll = true;
10298            } else if ("-c".equals(opt)) {
10299                dumpClient = true;
10300            } else if ("-h".equals(opt)) {
10301                pw.println("Activity manager dump options:");
10302                pw.println("  [-a] [-c] [-h] [cmd] ...");
10303                pw.println("  cmd may be one of:");
10304                pw.println("    a[ctivities]: activity stack state");
10305                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10306                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10307                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10308                pw.println("    o[om]: out of memory management");
10309                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10310                pw.println("    provider [COMP_SPEC]: provider client-side state");
10311                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10312                pw.println("    service [COMP_SPEC]: service client-side state");
10313                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10314                pw.println("    all: dump all activities");
10315                pw.println("    top: dump the top activity");
10316                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10317                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10318                pw.println("    a partial substring in a component name, a");
10319                pw.println("    hex object identifier.");
10320                pw.println("  -a: include all available server state.");
10321                pw.println("  -c: include client state.");
10322                return;
10323            } else {
10324                pw.println("Unknown argument: " + opt + "; use -h for help");
10325            }
10326        }
10327
10328        long origId = Binder.clearCallingIdentity();
10329        boolean more = false;
10330        // Is the caller requesting to dump a particular piece of data?
10331        if (opti < args.length) {
10332            String cmd = args[opti];
10333            opti++;
10334            if ("activities".equals(cmd) || "a".equals(cmd)) {
10335                synchronized (this) {
10336                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10337                }
10338            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10339                String[] newArgs;
10340                String name;
10341                if (opti >= args.length) {
10342                    name = null;
10343                    newArgs = EMPTY_STRING_ARRAY;
10344                } else {
10345                    name = args[opti];
10346                    opti++;
10347                    newArgs = new String[args.length - opti];
10348                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10349                            args.length - opti);
10350                }
10351                synchronized (this) {
10352                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10353                }
10354            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10355                String[] newArgs;
10356                String name;
10357                if (opti >= args.length) {
10358                    name = null;
10359                    newArgs = EMPTY_STRING_ARRAY;
10360                } else {
10361                    name = args[opti];
10362                    opti++;
10363                    newArgs = new String[args.length - opti];
10364                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10365                            args.length - opti);
10366                }
10367                synchronized (this) {
10368                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10369                }
10370            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10371                String[] newArgs;
10372                String name;
10373                if (opti >= args.length) {
10374                    name = null;
10375                    newArgs = EMPTY_STRING_ARRAY;
10376                } else {
10377                    name = args[opti];
10378                    opti++;
10379                    newArgs = new String[args.length - opti];
10380                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10381                            args.length - opti);
10382                }
10383                synchronized (this) {
10384                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10385                }
10386            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10387                synchronized (this) {
10388                    dumpOomLocked(fd, pw, args, opti, true);
10389                }
10390            } else if ("provider".equals(cmd)) {
10391                String[] newArgs;
10392                String name;
10393                if (opti >= args.length) {
10394                    name = null;
10395                    newArgs = EMPTY_STRING_ARRAY;
10396                } else {
10397                    name = args[opti];
10398                    opti++;
10399                    newArgs = new String[args.length - opti];
10400                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10401                }
10402                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10403                    pw.println("No providers match: " + name);
10404                    pw.println("Use -h for help.");
10405                }
10406            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10407                synchronized (this) {
10408                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10409                }
10410            } else if ("service".equals(cmd)) {
10411                String[] newArgs;
10412                String name;
10413                if (opti >= args.length) {
10414                    name = null;
10415                    newArgs = EMPTY_STRING_ARRAY;
10416                } else {
10417                    name = args[opti];
10418                    opti++;
10419                    newArgs = new String[args.length - opti];
10420                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10421                            args.length - opti);
10422                }
10423                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10424                    pw.println("No services match: " + name);
10425                    pw.println("Use -h for help.");
10426                }
10427            } else if ("package".equals(cmd)) {
10428                String[] newArgs;
10429                if (opti >= args.length) {
10430                    pw.println("package: no package name specified");
10431                    pw.println("Use -h for help.");
10432                } else {
10433                    dumpPackage = args[opti];
10434                    opti++;
10435                    newArgs = new String[args.length - opti];
10436                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10437                            args.length - opti);
10438                    args = newArgs;
10439                    opti = 0;
10440                    more = true;
10441                }
10442            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10443                synchronized (this) {
10444                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10445                }
10446            } else {
10447                // Dumping a single activity?
10448                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10449                    pw.println("Bad activity command, or no activities match: " + cmd);
10450                    pw.println("Use -h for help.");
10451                }
10452            }
10453            if (!more) {
10454                Binder.restoreCallingIdentity(origId);
10455                return;
10456            }
10457        }
10458
10459        // No piece of data specified, dump everything.
10460        synchronized (this) {
10461            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10462            pw.println();
10463            if (dumpAll) {
10464                pw.println("-------------------------------------------------------------------------------");
10465            }
10466            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10467            pw.println();
10468            if (dumpAll) {
10469                pw.println("-------------------------------------------------------------------------------");
10470            }
10471            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10472            pw.println();
10473            if (dumpAll) {
10474                pw.println("-------------------------------------------------------------------------------");
10475            }
10476            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10477            pw.println();
10478            if (dumpAll) {
10479                pw.println("-------------------------------------------------------------------------------");
10480            }
10481            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10482            pw.println();
10483            if (dumpAll) {
10484                pw.println("-------------------------------------------------------------------------------");
10485            }
10486            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10487        }
10488        Binder.restoreCallingIdentity(origId);
10489    }
10490
10491    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10492            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10493        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10494
10495        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10496                dumpPackage);
10497        boolean needSep = printedAnything;
10498
10499        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10500                dumpPackage, needSep, "  mFocusedActivity: ");
10501        if (printed) {
10502            printedAnything = true;
10503            needSep = false;
10504        }
10505
10506        if (dumpPackage == null) {
10507            if (needSep) {
10508                pw.println();
10509            }
10510            needSep = true;
10511            printedAnything = true;
10512            mStackSupervisor.dump(pw, "  ");
10513        }
10514
10515        if (mRecentTasks.size() > 0) {
10516            boolean printedHeader = false;
10517
10518            final int N = mRecentTasks.size();
10519            for (int i=0; i<N; i++) {
10520                TaskRecord tr = mRecentTasks.get(i);
10521                if (dumpPackage != null) {
10522                    if (tr.realActivity == null ||
10523                            !dumpPackage.equals(tr.realActivity)) {
10524                        continue;
10525                    }
10526                }
10527                if (!printedHeader) {
10528                    if (needSep) {
10529                        pw.println();
10530                    }
10531                    pw.println("  Recent tasks:");
10532                    printedHeader = true;
10533                    printedAnything = true;
10534                }
10535                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10536                        pw.println(tr);
10537                if (dumpAll) {
10538                    mRecentTasks.get(i).dump(pw, "    ");
10539                }
10540            }
10541        }
10542
10543        if (!printedAnything) {
10544            pw.println("  (nothing)");
10545        }
10546    }
10547
10548    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10549            int opti, boolean dumpAll, String dumpPackage) {
10550        boolean needSep = false;
10551        boolean printedAnything = false;
10552        int numPers = 0;
10553
10554        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10555
10556        if (dumpAll) {
10557            final int NP = mProcessNames.getMap().size();
10558            for (int ip=0; ip<NP; ip++) {
10559                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10560                final int NA = procs.size();
10561                for (int ia=0; ia<NA; ia++) {
10562                    ProcessRecord r = procs.valueAt(ia);
10563                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10564                        continue;
10565                    }
10566                    if (!needSep) {
10567                        pw.println("  All known processes:");
10568                        needSep = true;
10569                        printedAnything = true;
10570                    }
10571                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10572                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10573                        pw.print(" "); pw.println(r);
10574                    r.dump(pw, "    ");
10575                    if (r.persistent) {
10576                        numPers++;
10577                    }
10578                }
10579            }
10580        }
10581
10582        if (mIsolatedProcesses.size() > 0) {
10583            boolean printed = false;
10584            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10585                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10586                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10587                    continue;
10588                }
10589                if (!printed) {
10590                    if (needSep) {
10591                        pw.println();
10592                    }
10593                    pw.println("  Isolated process list (sorted by uid):");
10594                    printedAnything = true;
10595                    printed = true;
10596                    needSep = true;
10597                }
10598                pw.println(String.format("%sIsolated #%2d: %s",
10599                        "    ", i, r.toString()));
10600            }
10601        }
10602
10603        if (mLruProcesses.size() > 0) {
10604            if (needSep) {
10605                pw.println();
10606            }
10607            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10608                    pw.print(" total, non-act at ");
10609                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10610                    pw.print(", non-svc at ");
10611                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10612                    pw.println("):");
10613            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10614            needSep = true;
10615            printedAnything = true;
10616        }
10617
10618        if (dumpAll || dumpPackage != null) {
10619            synchronized (mPidsSelfLocked) {
10620                boolean printed = false;
10621                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10622                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10623                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10624                        continue;
10625                    }
10626                    if (!printed) {
10627                        if (needSep) pw.println();
10628                        needSep = true;
10629                        pw.println("  PID mappings:");
10630                        printed = true;
10631                        printedAnything = true;
10632                    }
10633                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10634                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10635                }
10636            }
10637        }
10638
10639        if (mForegroundProcesses.size() > 0) {
10640            synchronized (mPidsSelfLocked) {
10641                boolean printed = false;
10642                for (int i=0; i<mForegroundProcesses.size(); i++) {
10643                    ProcessRecord r = mPidsSelfLocked.get(
10644                            mForegroundProcesses.valueAt(i).pid);
10645                    if (dumpPackage != null && (r == null
10646                            || !r.pkgList.containsKey(dumpPackage))) {
10647                        continue;
10648                    }
10649                    if (!printed) {
10650                        if (needSep) pw.println();
10651                        needSep = true;
10652                        pw.println("  Foreground Processes:");
10653                        printed = true;
10654                        printedAnything = true;
10655                    }
10656                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10657                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10658                }
10659            }
10660        }
10661
10662        if (mPersistentStartingProcesses.size() > 0) {
10663            if (needSep) pw.println();
10664            needSep = true;
10665            printedAnything = true;
10666            pw.println("  Persisent processes that are starting:");
10667            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10668                    "Starting Norm", "Restarting PERS", dumpPackage);
10669        }
10670
10671        if (mRemovedProcesses.size() > 0) {
10672            if (needSep) pw.println();
10673            needSep = true;
10674            printedAnything = true;
10675            pw.println("  Processes that are being removed:");
10676            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10677                    "Removed Norm", "Removed PERS", dumpPackage);
10678        }
10679
10680        if (mProcessesOnHold.size() > 0) {
10681            if (needSep) pw.println();
10682            needSep = true;
10683            printedAnything = true;
10684            pw.println("  Processes that are on old until the system is ready:");
10685            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10686                    "OnHold Norm", "OnHold PERS", dumpPackage);
10687        }
10688
10689        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10690
10691        if (mProcessCrashTimes.getMap().size() > 0) {
10692            boolean printed = false;
10693            long now = SystemClock.uptimeMillis();
10694            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10695            final int NP = pmap.size();
10696            for (int ip=0; ip<NP; ip++) {
10697                String pname = pmap.keyAt(ip);
10698                SparseArray<Long> uids = pmap.valueAt(ip);
10699                final int N = uids.size();
10700                for (int i=0; i<N; i++) {
10701                    int puid = uids.keyAt(i);
10702                    ProcessRecord r = mProcessNames.get(pname, puid);
10703                    if (dumpPackage != null && (r == null
10704                            || !r.pkgList.containsKey(dumpPackage))) {
10705                        continue;
10706                    }
10707                    if (!printed) {
10708                        if (needSep) pw.println();
10709                        needSep = true;
10710                        pw.println("  Time since processes crashed:");
10711                        printed = true;
10712                        printedAnything = true;
10713                    }
10714                    pw.print("    Process "); pw.print(pname);
10715                            pw.print(" uid "); pw.print(puid);
10716                            pw.print(": last crashed ");
10717                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10718                            pw.println(" ago");
10719                }
10720            }
10721        }
10722
10723        if (mBadProcesses.getMap().size() > 0) {
10724            boolean printed = false;
10725            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10726            final int NP = pmap.size();
10727            for (int ip=0; ip<NP; ip++) {
10728                String pname = pmap.keyAt(ip);
10729                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10730                final int N = uids.size();
10731                for (int i=0; i<N; i++) {
10732                    int puid = uids.keyAt(i);
10733                    ProcessRecord r = mProcessNames.get(pname, puid);
10734                    if (dumpPackage != null && (r == null
10735                            || !r.pkgList.containsKey(dumpPackage))) {
10736                        continue;
10737                    }
10738                    if (!printed) {
10739                        if (needSep) pw.println();
10740                        needSep = true;
10741                        pw.println("  Bad processes:");
10742                        printedAnything = true;
10743                    }
10744                    BadProcessInfo info = uids.valueAt(i);
10745                    pw.print("    Bad process "); pw.print(pname);
10746                            pw.print(" uid "); pw.print(puid);
10747                            pw.print(": crashed at time "); pw.println(info.time);
10748                    if (info.shortMsg != null) {
10749                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10750                    }
10751                    if (info.longMsg != null) {
10752                        pw.print("      Long msg: "); pw.println(info.longMsg);
10753                    }
10754                    if (info.stack != null) {
10755                        pw.println("      Stack:");
10756                        int lastPos = 0;
10757                        for (int pos=0; pos<info.stack.length(); pos++) {
10758                            if (info.stack.charAt(pos) == '\n') {
10759                                pw.print("        ");
10760                                pw.write(info.stack, lastPos, pos-lastPos);
10761                                pw.println();
10762                                lastPos = pos+1;
10763                            }
10764                        }
10765                        if (lastPos < info.stack.length()) {
10766                            pw.print("        ");
10767                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10768                            pw.println();
10769                        }
10770                    }
10771                }
10772            }
10773        }
10774
10775        if (dumpPackage == null) {
10776            pw.println();
10777            needSep = false;
10778            pw.println("  mStartedUsers:");
10779            for (int i=0; i<mStartedUsers.size(); i++) {
10780                UserStartedState uss = mStartedUsers.valueAt(i);
10781                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10782                        pw.print(": "); uss.dump("", pw);
10783            }
10784            pw.print("  mStartedUserArray: [");
10785            for (int i=0; i<mStartedUserArray.length; i++) {
10786                if (i > 0) pw.print(", ");
10787                pw.print(mStartedUserArray[i]);
10788            }
10789            pw.println("]");
10790            pw.print("  mUserLru: [");
10791            for (int i=0; i<mUserLru.size(); i++) {
10792                if (i > 0) pw.print(", ");
10793                pw.print(mUserLru.get(i));
10794            }
10795            pw.println("]");
10796            if (dumpAll) {
10797                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10798            }
10799        }
10800        if (mHomeProcess != null && (dumpPackage == null
10801                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10802            if (needSep) {
10803                pw.println();
10804                needSep = false;
10805            }
10806            pw.println("  mHomeProcess: " + mHomeProcess);
10807        }
10808        if (mPreviousProcess != null && (dumpPackage == null
10809                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10810            if (needSep) {
10811                pw.println();
10812                needSep = false;
10813            }
10814            pw.println("  mPreviousProcess: " + mPreviousProcess);
10815        }
10816        if (dumpAll) {
10817            StringBuilder sb = new StringBuilder(128);
10818            sb.append("  mPreviousProcessVisibleTime: ");
10819            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10820            pw.println(sb);
10821        }
10822        if (mHeavyWeightProcess != null && (dumpPackage == null
10823                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10824            if (needSep) {
10825                pw.println();
10826                needSep = false;
10827            }
10828            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10829        }
10830        if (dumpPackage == null) {
10831            pw.println("  mConfiguration: " + mConfiguration);
10832        }
10833        if (dumpAll) {
10834            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10835            if (mCompatModePackages.getPackages().size() > 0) {
10836                boolean printed = false;
10837                for (Map.Entry<String, Integer> entry
10838                        : mCompatModePackages.getPackages().entrySet()) {
10839                    String pkg = entry.getKey();
10840                    int mode = entry.getValue();
10841                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10842                        continue;
10843                    }
10844                    if (!printed) {
10845                        pw.println("  mScreenCompatPackages:");
10846                        printed = true;
10847                    }
10848                    pw.print("    "); pw.print(pkg); pw.print(": ");
10849                            pw.print(mode); pw.println();
10850                }
10851            }
10852        }
10853        if (dumpPackage == null) {
10854            if (mSleeping || mWentToSleep || mLockScreenShown) {
10855                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10856                        + " mLockScreenShown " + mLockScreenShown);
10857            }
10858            if (mShuttingDown) {
10859                pw.println("  mShuttingDown=" + mShuttingDown);
10860            }
10861        }
10862        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10863                || mOrigWaitForDebugger) {
10864            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10865                    || dumpPackage.equals(mOrigDebugApp)) {
10866                if (needSep) {
10867                    pw.println();
10868                    needSep = false;
10869                }
10870                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10871                        + " mDebugTransient=" + mDebugTransient
10872                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10873            }
10874        }
10875        if (mOpenGlTraceApp != null) {
10876            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10877                if (needSep) {
10878                    pw.println();
10879                    needSep = false;
10880                }
10881                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10882            }
10883        }
10884        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10885                || mProfileFd != null) {
10886            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10887                if (needSep) {
10888                    pw.println();
10889                    needSep = false;
10890                }
10891                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10892                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10893                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10894                        + mAutoStopProfiler);
10895            }
10896        }
10897        if (dumpPackage == null) {
10898            if (mAlwaysFinishActivities || mController != null) {
10899                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10900                        + " mController=" + mController);
10901            }
10902            if (dumpAll) {
10903                pw.println("  Total persistent processes: " + numPers);
10904                pw.println("  mStartRunning=" + mStartRunning
10905                        + " mProcessesReady=" + mProcessesReady
10906                        + " mSystemReady=" + mSystemReady);
10907                pw.println("  mBooting=" + mBooting
10908                        + " mBooted=" + mBooted
10909                        + " mFactoryTest=" + mFactoryTest);
10910                pw.print("  mLastPowerCheckRealtime=");
10911                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10912                        pw.println("");
10913                pw.print("  mLastPowerCheckUptime=");
10914                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10915                        pw.println("");
10916                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10917                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10918                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10919                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10920                        + " (" + mLruProcesses.size() + " total)"
10921                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10922                        + " mNumServiceProcs=" + mNumServiceProcs
10923                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10924                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10925                        + " mLastMemoryLevel" + mLastMemoryLevel
10926                        + " mLastNumProcesses" + mLastNumProcesses);
10927                long now = SystemClock.uptimeMillis();
10928                pw.print("  mLastIdleTime=");
10929                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10930                        pw.print(" mLowRamSinceLastIdle=");
10931                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10932                        pw.println();
10933            }
10934        }
10935
10936        if (!printedAnything) {
10937            pw.println("  (nothing)");
10938        }
10939    }
10940
10941    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10942            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10943        if (mProcessesToGc.size() > 0) {
10944            boolean printed = false;
10945            long now = SystemClock.uptimeMillis();
10946            for (int i=0; i<mProcessesToGc.size(); i++) {
10947                ProcessRecord proc = mProcessesToGc.get(i);
10948                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10949                    continue;
10950                }
10951                if (!printed) {
10952                    if (needSep) pw.println();
10953                    needSep = true;
10954                    pw.println("  Processes that are waiting to GC:");
10955                    printed = true;
10956                }
10957                pw.print("    Process "); pw.println(proc);
10958                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10959                        pw.print(", last gced=");
10960                        pw.print(now-proc.lastRequestedGc);
10961                        pw.print(" ms ago, last lowMem=");
10962                        pw.print(now-proc.lastLowMemory);
10963                        pw.println(" ms ago");
10964
10965            }
10966        }
10967        return needSep;
10968    }
10969
10970    void printOomLevel(PrintWriter pw, String name, int adj) {
10971        pw.print("    ");
10972        if (adj >= 0) {
10973            pw.print(' ');
10974            if (adj < 10) pw.print(' ');
10975        } else {
10976            if (adj > -10) pw.print(' ');
10977        }
10978        pw.print(adj);
10979        pw.print(": ");
10980        pw.print(name);
10981        pw.print(" (");
10982        pw.print(mProcessList.getMemLevel(adj)/1024);
10983        pw.println(" kB)");
10984    }
10985
10986    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10987            int opti, boolean dumpAll) {
10988        boolean needSep = false;
10989
10990        if (mLruProcesses.size() > 0) {
10991            if (needSep) pw.println();
10992            needSep = true;
10993            pw.println("  OOM levels:");
10994            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10995            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10996            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10997            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10998            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10999            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11000            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11001            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11002            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11003            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11004            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11005            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11006            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11007
11008            if (needSep) pw.println();
11009            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11010                    pw.print(" total, non-act at ");
11011                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11012                    pw.print(", non-svc at ");
11013                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11014                    pw.println("):");
11015            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11016            needSep = true;
11017        }
11018
11019        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11020
11021        pw.println();
11022        pw.println("  mHomeProcess: " + mHomeProcess);
11023        pw.println("  mPreviousProcess: " + mPreviousProcess);
11024        if (mHeavyWeightProcess != null) {
11025            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11026        }
11027
11028        return true;
11029    }
11030
11031    /**
11032     * There are three ways to call this:
11033     *  - no provider specified: dump all the providers
11034     *  - a flattened component name that matched an existing provider was specified as the
11035     *    first arg: dump that one provider
11036     *  - the first arg isn't the flattened component name of an existing provider:
11037     *    dump all providers whose component contains the first arg as a substring
11038     */
11039    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11040            int opti, boolean dumpAll) {
11041        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11042    }
11043
11044    static class ItemMatcher {
11045        ArrayList<ComponentName> components;
11046        ArrayList<String> strings;
11047        ArrayList<Integer> objects;
11048        boolean all;
11049
11050        ItemMatcher() {
11051            all = true;
11052        }
11053
11054        void build(String name) {
11055            ComponentName componentName = ComponentName.unflattenFromString(name);
11056            if (componentName != null) {
11057                if (components == null) {
11058                    components = new ArrayList<ComponentName>();
11059                }
11060                components.add(componentName);
11061                all = false;
11062            } else {
11063                int objectId = 0;
11064                // Not a '/' separated full component name; maybe an object ID?
11065                try {
11066                    objectId = Integer.parseInt(name, 16);
11067                    if (objects == null) {
11068                        objects = new ArrayList<Integer>();
11069                    }
11070                    objects.add(objectId);
11071                    all = false;
11072                } catch (RuntimeException e) {
11073                    // Not an integer; just do string match.
11074                    if (strings == null) {
11075                        strings = new ArrayList<String>();
11076                    }
11077                    strings.add(name);
11078                    all = false;
11079                }
11080            }
11081        }
11082
11083        int build(String[] args, int opti) {
11084            for (; opti<args.length; opti++) {
11085                String name = args[opti];
11086                if ("--".equals(name)) {
11087                    return opti+1;
11088                }
11089                build(name);
11090            }
11091            return opti;
11092        }
11093
11094        boolean match(Object object, ComponentName comp) {
11095            if (all) {
11096                return true;
11097            }
11098            if (components != null) {
11099                for (int i=0; i<components.size(); i++) {
11100                    if (components.get(i).equals(comp)) {
11101                        return true;
11102                    }
11103                }
11104            }
11105            if (objects != null) {
11106                for (int i=0; i<objects.size(); i++) {
11107                    if (System.identityHashCode(object) == objects.get(i)) {
11108                        return true;
11109                    }
11110                }
11111            }
11112            if (strings != null) {
11113                String flat = comp.flattenToString();
11114                for (int i=0; i<strings.size(); i++) {
11115                    if (flat.contains(strings.get(i))) {
11116                        return true;
11117                    }
11118                }
11119            }
11120            return false;
11121        }
11122    }
11123
11124    /**
11125     * There are three things that cmd can be:
11126     *  - a flattened component name that matches an existing activity
11127     *  - the cmd arg isn't the flattened component name of an existing activity:
11128     *    dump all activity whose component contains the cmd as a substring
11129     *  - A hex number of the ActivityRecord object instance.
11130     */
11131    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11132            int opti, boolean dumpAll) {
11133        ArrayList<ActivityRecord> activities;
11134
11135        synchronized (this) {
11136            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11137        }
11138
11139        if (activities.size() <= 0) {
11140            return false;
11141        }
11142
11143        String[] newArgs = new String[args.length - opti];
11144        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11145
11146        TaskRecord lastTask = null;
11147        boolean needSep = false;
11148        for (int i=activities.size()-1; i>=0; i--) {
11149            ActivityRecord r = activities.get(i);
11150            if (needSep) {
11151                pw.println();
11152            }
11153            needSep = true;
11154            synchronized (this) {
11155                if (lastTask != r.task) {
11156                    lastTask = r.task;
11157                    pw.print("TASK "); pw.print(lastTask.affinity);
11158                            pw.print(" id="); pw.println(lastTask.taskId);
11159                    if (dumpAll) {
11160                        lastTask.dump(pw, "  ");
11161                    }
11162                }
11163            }
11164            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11165        }
11166        return true;
11167    }
11168
11169    /**
11170     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11171     * there is a thread associated with the activity.
11172     */
11173    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11174            final ActivityRecord r, String[] args, boolean dumpAll) {
11175        String innerPrefix = prefix + "  ";
11176        synchronized (this) {
11177            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11178                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11179                    pw.print(" pid=");
11180                    if (r.app != null) pw.println(r.app.pid);
11181                    else pw.println("(not running)");
11182            if (dumpAll) {
11183                r.dump(pw, innerPrefix);
11184            }
11185        }
11186        if (r.app != null && r.app.thread != null) {
11187            // flush anything that is already in the PrintWriter since the thread is going
11188            // to write to the file descriptor directly
11189            pw.flush();
11190            try {
11191                TransferPipe tp = new TransferPipe();
11192                try {
11193                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11194                            r.appToken, innerPrefix, args);
11195                    tp.go(fd);
11196                } finally {
11197                    tp.kill();
11198                }
11199            } catch (IOException e) {
11200                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11201            } catch (RemoteException e) {
11202                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11203            }
11204        }
11205    }
11206
11207    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11208            int opti, boolean dumpAll, String dumpPackage) {
11209        boolean needSep = false;
11210        boolean onlyHistory = false;
11211        boolean printedAnything = false;
11212
11213        if ("history".equals(dumpPackage)) {
11214            if (opti < args.length && "-s".equals(args[opti])) {
11215                dumpAll = false;
11216            }
11217            onlyHistory = true;
11218            dumpPackage = null;
11219        }
11220
11221        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11222        if (!onlyHistory && dumpAll) {
11223            if (mRegisteredReceivers.size() > 0) {
11224                boolean printed = false;
11225                Iterator it = mRegisteredReceivers.values().iterator();
11226                while (it.hasNext()) {
11227                    ReceiverList r = (ReceiverList)it.next();
11228                    if (dumpPackage != null && (r.app == null ||
11229                            !dumpPackage.equals(r.app.info.packageName))) {
11230                        continue;
11231                    }
11232                    if (!printed) {
11233                        pw.println("  Registered Receivers:");
11234                        needSep = true;
11235                        printed = true;
11236                        printedAnything = true;
11237                    }
11238                    pw.print("  * "); pw.println(r);
11239                    r.dump(pw, "    ");
11240                }
11241            }
11242
11243            if (mReceiverResolver.dump(pw, needSep ?
11244                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11245                    "    ", dumpPackage, false)) {
11246                needSep = true;
11247                printedAnything = true;
11248            }
11249        }
11250
11251        for (BroadcastQueue q : mBroadcastQueues) {
11252            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11253            printedAnything |= needSep;
11254        }
11255
11256        needSep = true;
11257
11258        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11259            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11260                if (needSep) {
11261                    pw.println();
11262                }
11263                needSep = true;
11264                printedAnything = true;
11265                pw.print("  Sticky broadcasts for user ");
11266                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11267                StringBuilder sb = new StringBuilder(128);
11268                for (Map.Entry<String, ArrayList<Intent>> ent
11269                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11270                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11271                    if (dumpAll) {
11272                        pw.println(":");
11273                        ArrayList<Intent> intents = ent.getValue();
11274                        final int N = intents.size();
11275                        for (int i=0; i<N; i++) {
11276                            sb.setLength(0);
11277                            sb.append("    Intent: ");
11278                            intents.get(i).toShortString(sb, false, true, false, false);
11279                            pw.println(sb.toString());
11280                            Bundle bundle = intents.get(i).getExtras();
11281                            if (bundle != null) {
11282                                pw.print("      ");
11283                                pw.println(bundle.toString());
11284                            }
11285                        }
11286                    } else {
11287                        pw.println("");
11288                    }
11289                }
11290            }
11291        }
11292
11293        if (!onlyHistory && dumpAll) {
11294            pw.println();
11295            for (BroadcastQueue queue : mBroadcastQueues) {
11296                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11297                        + queue.mBroadcastsScheduled);
11298            }
11299            pw.println("  mHandler:");
11300            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11301            needSep = true;
11302            printedAnything = true;
11303        }
11304
11305        if (!printedAnything) {
11306            pw.println("  (nothing)");
11307        }
11308    }
11309
11310    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11311            int opti, boolean dumpAll, String dumpPackage) {
11312        boolean needSep;
11313        boolean printedAnything = false;
11314
11315        ItemMatcher matcher = new ItemMatcher();
11316        matcher.build(args, opti);
11317
11318        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11319
11320        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11321        printedAnything |= needSep;
11322
11323        if (mLaunchingProviders.size() > 0) {
11324            boolean printed = false;
11325            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11326                ContentProviderRecord r = mLaunchingProviders.get(i);
11327                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11328                    continue;
11329                }
11330                if (!printed) {
11331                    if (needSep) pw.println();
11332                    needSep = true;
11333                    pw.println("  Launching content providers:");
11334                    printed = true;
11335                    printedAnything = true;
11336                }
11337                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11338                        pw.println(r);
11339            }
11340        }
11341
11342        if (mGrantedUriPermissions.size() > 0) {
11343            boolean printed = false;
11344            int dumpUid = -2;
11345            if (dumpPackage != null) {
11346                try {
11347                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11348                } catch (NameNotFoundException e) {
11349                    dumpUid = -1;
11350                }
11351            }
11352            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11353                int uid = mGrantedUriPermissions.keyAt(i);
11354                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11355                    continue;
11356                }
11357                ArrayMap<Uri, UriPermission> perms
11358                        = mGrantedUriPermissions.valueAt(i);
11359                if (!printed) {
11360                    if (needSep) pw.println();
11361                    needSep = true;
11362                    pw.println("  Granted Uri Permissions:");
11363                    printed = true;
11364                    printedAnything = true;
11365                }
11366                pw.print("  * UID "); pw.print(uid);
11367                        pw.println(" holds:");
11368                for (UriPermission perm : perms.values()) {
11369                    pw.print("    "); pw.println(perm);
11370                    if (dumpAll) {
11371                        perm.dump(pw, "      ");
11372                    }
11373                }
11374            }
11375        }
11376
11377        if (!printedAnything) {
11378            pw.println("  (nothing)");
11379        }
11380    }
11381
11382    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11383            int opti, boolean dumpAll, String dumpPackage) {
11384        boolean printed = false;
11385
11386        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11387
11388        if (mIntentSenderRecords.size() > 0) {
11389            Iterator<WeakReference<PendingIntentRecord>> it
11390                    = mIntentSenderRecords.values().iterator();
11391            while (it.hasNext()) {
11392                WeakReference<PendingIntentRecord> ref = it.next();
11393                PendingIntentRecord rec = ref != null ? ref.get(): null;
11394                if (dumpPackage != null && (rec == null
11395                        || !dumpPackage.equals(rec.key.packageName))) {
11396                    continue;
11397                }
11398                printed = true;
11399                if (rec != null) {
11400                    pw.print("  * "); pw.println(rec);
11401                    if (dumpAll) {
11402                        rec.dump(pw, "    ");
11403                    }
11404                } else {
11405                    pw.print("  * "); pw.println(ref);
11406                }
11407            }
11408        }
11409
11410        if (!printed) {
11411            pw.println("  (nothing)");
11412        }
11413    }
11414
11415    private static final int dumpProcessList(PrintWriter pw,
11416            ActivityManagerService service, List list,
11417            String prefix, String normalLabel, String persistentLabel,
11418            String dumpPackage) {
11419        int numPers = 0;
11420        final int N = list.size()-1;
11421        for (int i=N; i>=0; i--) {
11422            ProcessRecord r = (ProcessRecord)list.get(i);
11423            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11424                continue;
11425            }
11426            pw.println(String.format("%s%s #%2d: %s",
11427                    prefix, (r.persistent ? persistentLabel : normalLabel),
11428                    i, r.toString()));
11429            if (r.persistent) {
11430                numPers++;
11431            }
11432        }
11433        return numPers;
11434    }
11435
11436    private static final boolean dumpProcessOomList(PrintWriter pw,
11437            ActivityManagerService service, List<ProcessRecord> origList,
11438            String prefix, String normalLabel, String persistentLabel,
11439            boolean inclDetails, String dumpPackage) {
11440
11441        ArrayList<Pair<ProcessRecord, Integer>> list
11442                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11443        for (int i=0; i<origList.size(); i++) {
11444            ProcessRecord r = origList.get(i);
11445            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11446                continue;
11447            }
11448            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11449        }
11450
11451        if (list.size() <= 0) {
11452            return false;
11453        }
11454
11455        Comparator<Pair<ProcessRecord, Integer>> comparator
11456                = new Comparator<Pair<ProcessRecord, Integer>>() {
11457            @Override
11458            public int compare(Pair<ProcessRecord, Integer> object1,
11459                    Pair<ProcessRecord, Integer> object2) {
11460                if (object1.first.setAdj != object2.first.setAdj) {
11461                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11462                }
11463                if (object1.second.intValue() != object2.second.intValue()) {
11464                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11465                }
11466                return 0;
11467            }
11468        };
11469
11470        Collections.sort(list, comparator);
11471
11472        final long curRealtime = SystemClock.elapsedRealtime();
11473        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11474        final long curUptime = SystemClock.uptimeMillis();
11475        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11476
11477        for (int i=list.size()-1; i>=0; i--) {
11478            ProcessRecord r = list.get(i).first;
11479            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11480            char schedGroup;
11481            switch (r.setSchedGroup) {
11482                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11483                    schedGroup = 'B';
11484                    break;
11485                case Process.THREAD_GROUP_DEFAULT:
11486                    schedGroup = 'F';
11487                    break;
11488                default:
11489                    schedGroup = '?';
11490                    break;
11491            }
11492            char foreground;
11493            if (r.foregroundActivities) {
11494                foreground = 'A';
11495            } else if (r.foregroundServices) {
11496                foreground = 'S';
11497            } else {
11498                foreground = ' ';
11499            }
11500            String procState = ProcessList.makeProcStateString(r.curProcState);
11501            pw.print(prefix);
11502            pw.print(r.persistent ? persistentLabel : normalLabel);
11503            pw.print(" #");
11504            int num = (origList.size()-1)-list.get(i).second;
11505            if (num < 10) pw.print(' ');
11506            pw.print(num);
11507            pw.print(": ");
11508            pw.print(oomAdj);
11509            pw.print(' ');
11510            pw.print(schedGroup);
11511            pw.print('/');
11512            pw.print(foreground);
11513            pw.print('/');
11514            pw.print(procState);
11515            pw.print(" trm:");
11516            if (r.trimMemoryLevel < 10) pw.print(' ');
11517            pw.print(r.trimMemoryLevel);
11518            pw.print(' ');
11519            pw.print(r.toShortString());
11520            pw.print(" (");
11521            pw.print(r.adjType);
11522            pw.println(')');
11523            if (r.adjSource != null || r.adjTarget != null) {
11524                pw.print(prefix);
11525                pw.print("    ");
11526                if (r.adjTarget instanceof ComponentName) {
11527                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11528                } else if (r.adjTarget != null) {
11529                    pw.print(r.adjTarget.toString());
11530                } else {
11531                    pw.print("{null}");
11532                }
11533                pw.print("<=");
11534                if (r.adjSource instanceof ProcessRecord) {
11535                    pw.print("Proc{");
11536                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11537                    pw.println("}");
11538                } else if (r.adjSource != null) {
11539                    pw.println(r.adjSource.toString());
11540                } else {
11541                    pw.println("{null}");
11542                }
11543            }
11544            if (inclDetails) {
11545                pw.print(prefix);
11546                pw.print("    ");
11547                pw.print("oom: max="); pw.print(r.maxAdj);
11548                pw.print(" curRaw="); pw.print(r.curRawAdj);
11549                pw.print(" setRaw="); pw.print(r.setRawAdj);
11550                pw.print(" cur="); pw.print(r.curAdj);
11551                pw.print(" set="); pw.println(r.setAdj);
11552                pw.print(prefix);
11553                pw.print("    ");
11554                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11555                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11556                pw.print(" lastPss="); pw.print(r.lastPss);
11557                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11558                pw.print(prefix);
11559                pw.print("    ");
11560                pw.print("keeping="); pw.print(r.keeping);
11561                pw.print(" cached="); pw.print(r.cached);
11562                pw.print(" empty="); pw.print(r.empty);
11563                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11564
11565                if (!r.keeping) {
11566                    if (r.lastWakeTime != 0) {
11567                        long wtime;
11568                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11569                        synchronized (stats) {
11570                            wtime = stats.getProcessWakeTime(r.info.uid,
11571                                    r.pid, curRealtime);
11572                        }
11573                        long timeUsed = wtime - r.lastWakeTime;
11574                        pw.print(prefix);
11575                        pw.print("    ");
11576                        pw.print("keep awake over ");
11577                        TimeUtils.formatDuration(realtimeSince, pw);
11578                        pw.print(" used ");
11579                        TimeUtils.formatDuration(timeUsed, pw);
11580                        pw.print(" (");
11581                        pw.print((timeUsed*100)/realtimeSince);
11582                        pw.println("%)");
11583                    }
11584                    if (r.lastCpuTime != 0) {
11585                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11586                        pw.print(prefix);
11587                        pw.print("    ");
11588                        pw.print("run cpu over ");
11589                        TimeUtils.formatDuration(uptimeSince, pw);
11590                        pw.print(" used ");
11591                        TimeUtils.formatDuration(timeUsed, pw);
11592                        pw.print(" (");
11593                        pw.print((timeUsed*100)/uptimeSince);
11594                        pw.println("%)");
11595                    }
11596                }
11597            }
11598        }
11599        return true;
11600    }
11601
11602    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11603        ArrayList<ProcessRecord> procs;
11604        synchronized (this) {
11605            if (args != null && args.length > start
11606                    && args[start].charAt(0) != '-') {
11607                procs = new ArrayList<ProcessRecord>();
11608                int pid = -1;
11609                try {
11610                    pid = Integer.parseInt(args[start]);
11611                } catch (NumberFormatException e) {
11612                }
11613                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11614                    ProcessRecord proc = mLruProcesses.get(i);
11615                    if (proc.pid == pid) {
11616                        procs.add(proc);
11617                    } else if (proc.processName.equals(args[start])) {
11618                        procs.add(proc);
11619                    }
11620                }
11621                if (procs.size() <= 0) {
11622                    return null;
11623                }
11624            } else {
11625                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11626            }
11627        }
11628        return procs;
11629    }
11630
11631    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11632            PrintWriter pw, String[] args) {
11633        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11634        if (procs == null) {
11635            pw.println("No process found for: " + args[0]);
11636            return;
11637        }
11638
11639        long uptime = SystemClock.uptimeMillis();
11640        long realtime = SystemClock.elapsedRealtime();
11641        pw.println("Applications Graphics Acceleration Info:");
11642        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11643
11644        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11645            ProcessRecord r = procs.get(i);
11646            if (r.thread != null) {
11647                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11648                pw.flush();
11649                try {
11650                    TransferPipe tp = new TransferPipe();
11651                    try {
11652                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11653                        tp.go(fd);
11654                    } finally {
11655                        tp.kill();
11656                    }
11657                } catch (IOException e) {
11658                    pw.println("Failure while dumping the app: " + r);
11659                    pw.flush();
11660                } catch (RemoteException e) {
11661                    pw.println("Got a RemoteException while dumping the app " + r);
11662                    pw.flush();
11663                }
11664            }
11665        }
11666    }
11667
11668    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11669        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11670        if (procs == null) {
11671            pw.println("No process found for: " + args[0]);
11672            return;
11673        }
11674
11675        pw.println("Applications Database Info:");
11676
11677        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11678            ProcessRecord r = procs.get(i);
11679            if (r.thread != null) {
11680                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11681                pw.flush();
11682                try {
11683                    TransferPipe tp = new TransferPipe();
11684                    try {
11685                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11686                        tp.go(fd);
11687                    } finally {
11688                        tp.kill();
11689                    }
11690                } catch (IOException e) {
11691                    pw.println("Failure while dumping the app: " + r);
11692                    pw.flush();
11693                } catch (RemoteException e) {
11694                    pw.println("Got a RemoteException while dumping the app " + r);
11695                    pw.flush();
11696                }
11697            }
11698        }
11699    }
11700
11701    final static class MemItem {
11702        final boolean isProc;
11703        final String label;
11704        final String shortLabel;
11705        final long pss;
11706        final int id;
11707        final boolean hasActivities;
11708        ArrayList<MemItem> subitems;
11709
11710        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11711                boolean _hasActivities) {
11712            isProc = true;
11713            label = _label;
11714            shortLabel = _shortLabel;
11715            pss = _pss;
11716            id = _id;
11717            hasActivities = _hasActivities;
11718        }
11719
11720        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11721            isProc = false;
11722            label = _label;
11723            shortLabel = _shortLabel;
11724            pss = _pss;
11725            id = _id;
11726            hasActivities = false;
11727        }
11728    }
11729
11730    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11731            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11732        if (sort && !isCompact) {
11733            Collections.sort(items, new Comparator<MemItem>() {
11734                @Override
11735                public int compare(MemItem lhs, MemItem rhs) {
11736                    if (lhs.pss < rhs.pss) {
11737                        return 1;
11738                    } else if (lhs.pss > rhs.pss) {
11739                        return -1;
11740                    }
11741                    return 0;
11742                }
11743            });
11744        }
11745
11746        for (int i=0; i<items.size(); i++) {
11747            MemItem mi = items.get(i);
11748            if (!isCompact) {
11749                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11750            } else if (mi.isProc) {
11751                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11752                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11753                pw.println(mi.hasActivities ? ",a" : ",e");
11754            } else {
11755                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11756                pw.println(mi.pss);
11757            }
11758            if (mi.subitems != null) {
11759                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11760                        true, isCompact);
11761            }
11762        }
11763    }
11764
11765    // These are in KB.
11766    static final long[] DUMP_MEM_BUCKETS = new long[] {
11767        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11768        120*1024, 160*1024, 200*1024,
11769        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11770        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11771    };
11772
11773    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11774            boolean stackLike) {
11775        int start = label.lastIndexOf('.');
11776        if (start >= 0) start++;
11777        else start = 0;
11778        int end = label.length();
11779        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11780            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11781                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11782                out.append(bucket);
11783                out.append(stackLike ? "MB." : "MB ");
11784                out.append(label, start, end);
11785                return;
11786            }
11787        }
11788        out.append(memKB/1024);
11789        out.append(stackLike ? "MB." : "MB ");
11790        out.append(label, start, end);
11791    }
11792
11793    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11794            ProcessList.NATIVE_ADJ,
11795            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11796            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11797            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11798            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11799            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11800    };
11801    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11802            "Native",
11803            "System", "Persistent", "Foreground",
11804            "Visible", "Perceptible",
11805            "Heavy Weight", "Backup",
11806            "A Services", "Home",
11807            "Previous", "B Services", "Cached"
11808    };
11809    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11810            "native",
11811            "sys", "pers", "fore",
11812            "vis", "percept",
11813            "heavy", "backup",
11814            "servicea", "home",
11815            "prev", "serviceb", "cached"
11816    };
11817
11818    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11819            long realtime, boolean isCheckinRequest, boolean isCompact) {
11820        if (isCheckinRequest || isCompact) {
11821            // short checkin version
11822            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11823        } else {
11824            pw.println("Applications Memory Usage (kB):");
11825            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11826        }
11827    }
11828
11829    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11830            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11831        boolean dumpDetails = false;
11832        boolean dumpFullDetails = false;
11833        boolean dumpDalvik = false;
11834        boolean oomOnly = false;
11835        boolean isCompact = false;
11836        boolean localOnly = false;
11837
11838        int opti = 0;
11839        while (opti < args.length) {
11840            String opt = args[opti];
11841            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11842                break;
11843            }
11844            opti++;
11845            if ("-a".equals(opt)) {
11846                dumpDetails = true;
11847                dumpFullDetails = true;
11848                dumpDalvik = true;
11849            } else if ("-d".equals(opt)) {
11850                dumpDalvik = true;
11851            } else if ("-c".equals(opt)) {
11852                isCompact = true;
11853            } else if ("--oom".equals(opt)) {
11854                oomOnly = true;
11855            } else if ("--local".equals(opt)) {
11856                localOnly = true;
11857            } else if ("-h".equals(opt)) {
11858                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11859                pw.println("  -a: include all available information for each process.");
11860                pw.println("  -d: include dalvik details when dumping process details.");
11861                pw.println("  -c: dump in a compact machine-parseable representation.");
11862                pw.println("  --oom: only show processes organized by oom adj.");
11863                pw.println("  --local: only collect details locally, don't call process.");
11864                pw.println("If [process] is specified it can be the name or ");
11865                pw.println("pid of a specific process to dump.");
11866                return;
11867            } else {
11868                pw.println("Unknown argument: " + opt + "; use -h for help");
11869            }
11870        }
11871
11872        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11873        long uptime = SystemClock.uptimeMillis();
11874        long realtime = SystemClock.elapsedRealtime();
11875        final long[] tmpLong = new long[1];
11876
11877        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11878        if (procs == null) {
11879            // No Java processes.  Maybe they want to print a native process.
11880            if (args != null && args.length > opti
11881                    && args[opti].charAt(0) != '-') {
11882                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11883                        = new ArrayList<ProcessCpuTracker.Stats>();
11884                updateCpuStatsNow();
11885                int findPid = -1;
11886                try {
11887                    findPid = Integer.parseInt(args[opti]);
11888                } catch (NumberFormatException e) {
11889                }
11890                synchronized (mProcessCpuThread) {
11891                    final int N = mProcessCpuTracker.countStats();
11892                    for (int i=0; i<N; i++) {
11893                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11894                        if (st.pid == findPid || (st.baseName != null
11895                                && st.baseName.equals(args[opti]))) {
11896                            nativeProcs.add(st);
11897                        }
11898                    }
11899                }
11900                if (nativeProcs.size() > 0) {
11901                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11902                            isCompact);
11903                    Debug.MemoryInfo mi = null;
11904                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11905                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11906                        final int pid = r.pid;
11907                        if (!isCheckinRequest && dumpDetails) {
11908                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11909                        }
11910                        if (mi == null) {
11911                            mi = new Debug.MemoryInfo();
11912                        }
11913                        if (dumpDetails || (!brief && !oomOnly)) {
11914                            Debug.getMemoryInfo(pid, mi);
11915                        } else {
11916                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11917                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11918                        }
11919                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11920                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11921                        if (isCheckinRequest) {
11922                            pw.println();
11923                        }
11924                    }
11925                    return;
11926                }
11927            }
11928            pw.println("No process found for: " + args[opti]);
11929            return;
11930        }
11931
11932        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11933            dumpDetails = true;
11934        }
11935
11936        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11937
11938        String[] innerArgs = new String[args.length-opti];
11939        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11940
11941        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11942        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11943        long nativePss=0, dalvikPss=0, otherPss=0;
11944        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11945
11946        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11947        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11948                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11949
11950        long totalPss = 0;
11951        long cachedPss = 0;
11952
11953        Debug.MemoryInfo mi = null;
11954        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11955            final ProcessRecord r = procs.get(i);
11956            final IApplicationThread thread;
11957            final int pid;
11958            final int oomAdj;
11959            final boolean hasActivities;
11960            synchronized (this) {
11961                thread = r.thread;
11962                pid = r.pid;
11963                oomAdj = r.getSetAdjWithServices();
11964                hasActivities = r.activities.size() > 0;
11965            }
11966            if (thread != null) {
11967                if (!isCheckinRequest && dumpDetails) {
11968                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11969                }
11970                if (mi == null) {
11971                    mi = new Debug.MemoryInfo();
11972                }
11973                if (dumpDetails || (!brief && !oomOnly)) {
11974                    Debug.getMemoryInfo(pid, mi);
11975                } else {
11976                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11977                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11978                }
11979                if (dumpDetails) {
11980                    if (localOnly) {
11981                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11982                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11983                        if (isCheckinRequest) {
11984                            pw.println();
11985                        }
11986                    } else {
11987                        try {
11988                            pw.flush();
11989                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11990                                    dumpDalvik, innerArgs);
11991                        } catch (RemoteException e) {
11992                            if (!isCheckinRequest) {
11993                                pw.println("Got RemoteException!");
11994                                pw.flush();
11995                            }
11996                        }
11997                    }
11998                }
11999
12000                final long myTotalPss = mi.getTotalPss();
12001                final long myTotalUss = mi.getTotalUss();
12002
12003                synchronized (this) {
12004                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12005                        // Record this for posterity if the process has been stable.
12006                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12007                    }
12008                }
12009
12010                if (!isCheckinRequest && mi != null) {
12011                    totalPss += myTotalPss;
12012                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12013                            (hasActivities ? " / activities)" : ")"),
12014                            r.processName, myTotalPss, pid, hasActivities);
12015                    procMems.add(pssItem);
12016                    procMemsMap.put(pid, pssItem);
12017
12018                    nativePss += mi.nativePss;
12019                    dalvikPss += mi.dalvikPss;
12020                    otherPss += mi.otherPss;
12021                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12022                        long mem = mi.getOtherPss(j);
12023                        miscPss[j] += mem;
12024                        otherPss -= mem;
12025                    }
12026
12027                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12028                        cachedPss += myTotalPss;
12029                    }
12030
12031                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12032                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12033                                || oomIndex == (oomPss.length-1)) {
12034                            oomPss[oomIndex] += myTotalPss;
12035                            if (oomProcs[oomIndex] == null) {
12036                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12037                            }
12038                            oomProcs[oomIndex].add(pssItem);
12039                            break;
12040                        }
12041                    }
12042                }
12043            }
12044        }
12045
12046        if (!isCheckinRequest && procs.size() > 1) {
12047            // If we are showing aggregations, also look for native processes to
12048            // include so that our aggregations are more accurate.
12049            updateCpuStatsNow();
12050            synchronized (mProcessCpuThread) {
12051                final int N = mProcessCpuTracker.countStats();
12052                for (int i=0; i<N; i++) {
12053                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12054                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12055                        if (mi == null) {
12056                            mi = new Debug.MemoryInfo();
12057                        }
12058                        if (!brief && !oomOnly) {
12059                            Debug.getMemoryInfo(st.pid, mi);
12060                        } else {
12061                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12062                            mi.nativePrivateDirty = (int)tmpLong[0];
12063                        }
12064
12065                        final long myTotalPss = mi.getTotalPss();
12066                        totalPss += myTotalPss;
12067
12068                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12069                                st.name, myTotalPss, st.pid, false);
12070                        procMems.add(pssItem);
12071
12072                        nativePss += mi.nativePss;
12073                        dalvikPss += mi.dalvikPss;
12074                        otherPss += mi.otherPss;
12075                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12076                            long mem = mi.getOtherPss(j);
12077                            miscPss[j] += mem;
12078                            otherPss -= mem;
12079                        }
12080                        oomPss[0] += myTotalPss;
12081                        if (oomProcs[0] == null) {
12082                            oomProcs[0] = new ArrayList<MemItem>();
12083                        }
12084                        oomProcs[0].add(pssItem);
12085                    }
12086                }
12087            }
12088
12089            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12090
12091            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12092            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12093            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12094            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12095                String label = Debug.MemoryInfo.getOtherLabel(j);
12096                catMems.add(new MemItem(label, label, miscPss[j], j));
12097            }
12098
12099            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12100            for (int j=0; j<oomPss.length; j++) {
12101                if (oomPss[j] != 0) {
12102                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12103                            : DUMP_MEM_OOM_LABEL[j];
12104                    MemItem item = new MemItem(label, label, oomPss[j],
12105                            DUMP_MEM_OOM_ADJ[j]);
12106                    item.subitems = oomProcs[j];
12107                    oomMems.add(item);
12108                }
12109            }
12110
12111            if (!brief && !oomOnly && !isCompact) {
12112                pw.println();
12113                pw.println("Total PSS by process:");
12114                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12115                pw.println();
12116            }
12117            if (!isCompact) {
12118                pw.println("Total PSS by OOM adjustment:");
12119            }
12120            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12121            if (!brief && !oomOnly) {
12122                PrintWriter out = categoryPw != null ? categoryPw : pw;
12123                if (!isCompact) {
12124                    out.println();
12125                    out.println("Total PSS by category:");
12126                }
12127                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12128            }
12129            if (!isCompact) {
12130                pw.println();
12131            }
12132            MemInfoReader memInfo = new MemInfoReader();
12133            memInfo.readMemInfo();
12134            if (!brief) {
12135                if (!isCompact) {
12136                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12137                    pw.print(" kB (status ");
12138                    switch (mLastMemoryLevel) {
12139                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12140                            pw.println("normal)");
12141                            break;
12142                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12143                            pw.println("moderate)");
12144                            break;
12145                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12146                            pw.println("low)");
12147                            break;
12148                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12149                            pw.println("critical)");
12150                            break;
12151                        default:
12152                            pw.print(mLastMemoryLevel);
12153                            pw.println(")");
12154                            break;
12155                    }
12156                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12157                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12158                            pw.print(cachedPss); pw.print(" cached pss + ");
12159                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12160                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12161                } else {
12162                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12163                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12164                            + memInfo.getFreeSizeKb()); pw.print(",");
12165                    pw.println(totalPss - cachedPss);
12166                }
12167            }
12168            if (!isCompact) {
12169                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12170                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12171                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12172                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12173                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12174                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12175                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12176                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12177                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12178                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12179                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12180            }
12181            if (!brief) {
12182                if (memInfo.getZramTotalSizeKb() != 0) {
12183                    if (!isCompact) {
12184                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12185                                pw.print(" kB physical used for ");
12186                                pw.print(memInfo.getSwapTotalSizeKb()
12187                                        - memInfo.getSwapFreeSizeKb());
12188                                pw.print(" kB in swap (");
12189                                pw.print(memInfo.getSwapTotalSizeKb());
12190                                pw.println(" kB total swap)");
12191                    } else {
12192                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12193                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12194                                pw.println(memInfo.getSwapFreeSizeKb());
12195                    }
12196                }
12197                final int[] SINGLE_LONG_FORMAT = new int[] {
12198                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12199                };
12200                long[] longOut = new long[1];
12201                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12202                        SINGLE_LONG_FORMAT, null, longOut, null);
12203                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12204                longOut[0] = 0;
12205                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12206                        SINGLE_LONG_FORMAT, null, longOut, null);
12207                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12208                longOut[0] = 0;
12209                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12210                        SINGLE_LONG_FORMAT, null, longOut, null);
12211                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12212                longOut[0] = 0;
12213                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12214                        SINGLE_LONG_FORMAT, null, longOut, null);
12215                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12216                if (!isCompact) {
12217                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12218                        pw.print("      KSM: "); pw.print(sharing);
12219                                pw.print(" kB saved from shared ");
12220                                pw.print(shared); pw.println(" kB");
12221                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12222                                pw.print(voltile); pw.println(" kB volatile");
12223                    }
12224                    pw.print("   Tuning: ");
12225                    pw.print(ActivityManager.staticGetMemoryClass());
12226                    pw.print(" (large ");
12227                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12228                    pw.print("), oom ");
12229                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12230                    pw.print(" kB");
12231                    pw.print(", restore limit ");
12232                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12233                    pw.print(" kB");
12234                    if (ActivityManager.isLowRamDeviceStatic()) {
12235                        pw.print(" (low-ram)");
12236                    }
12237                    if (ActivityManager.isHighEndGfx()) {
12238                        pw.print(" (high-end-gfx)");
12239                    }
12240                    pw.println();
12241                } else {
12242                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12243                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12244                    pw.println(voltile);
12245                    pw.print("tuning,");
12246                    pw.print(ActivityManager.staticGetMemoryClass());
12247                    pw.print(',');
12248                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12249                    pw.print(',');
12250                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12251                    if (ActivityManager.isLowRamDeviceStatic()) {
12252                        pw.print(",low-ram");
12253                    }
12254                    if (ActivityManager.isHighEndGfx()) {
12255                        pw.print(",high-end-gfx");
12256                    }
12257                    pw.println();
12258                }
12259            }
12260        }
12261    }
12262
12263    /**
12264     * Searches array of arguments for the specified string
12265     * @param args array of argument strings
12266     * @param value value to search for
12267     * @return true if the value is contained in the array
12268     */
12269    private static boolean scanArgs(String[] args, String value) {
12270        if (args != null) {
12271            for (String arg : args) {
12272                if (value.equals(arg)) {
12273                    return true;
12274                }
12275            }
12276        }
12277        return false;
12278    }
12279
12280    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12281            ContentProviderRecord cpr, boolean always) {
12282        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12283
12284        if (!inLaunching || always) {
12285            synchronized (cpr) {
12286                cpr.launchingApp = null;
12287                cpr.notifyAll();
12288            }
12289            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12290            String names[] = cpr.info.authority.split(";");
12291            for (int j = 0; j < names.length; j++) {
12292                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12293            }
12294        }
12295
12296        for (int i=0; i<cpr.connections.size(); i++) {
12297            ContentProviderConnection conn = cpr.connections.get(i);
12298            if (conn.waiting) {
12299                // If this connection is waiting for the provider, then we don't
12300                // need to mess with its process unless we are always removing
12301                // or for some reason the provider is not currently launching.
12302                if (inLaunching && !always) {
12303                    continue;
12304                }
12305            }
12306            ProcessRecord capp = conn.client;
12307            conn.dead = true;
12308            if (conn.stableCount > 0) {
12309                if (!capp.persistent && capp.thread != null
12310                        && capp.pid != 0
12311                        && capp.pid != MY_PID) {
12312                    killUnneededProcessLocked(capp, "depends on provider "
12313                            + cpr.name.flattenToShortString()
12314                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12315                }
12316            } else if (capp.thread != null && conn.provider.provider != null) {
12317                try {
12318                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12319                } catch (RemoteException e) {
12320                }
12321                // In the protocol here, we don't expect the client to correctly
12322                // clean up this connection, we'll just remove it.
12323                cpr.connections.remove(i);
12324                conn.client.conProviders.remove(conn);
12325            }
12326        }
12327
12328        if (inLaunching && always) {
12329            mLaunchingProviders.remove(cpr);
12330        }
12331        return inLaunching;
12332    }
12333
12334    /**
12335     * Main code for cleaning up a process when it has gone away.  This is
12336     * called both as a result of the process dying, or directly when stopping
12337     * a process when running in single process mode.
12338     */
12339    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12340            boolean restarting, boolean allowRestart, int index) {
12341        if (index >= 0) {
12342            removeLruProcessLocked(app);
12343            ProcessList.remove(app.pid);
12344        }
12345
12346        mProcessesToGc.remove(app);
12347        mPendingPssProcesses.remove(app);
12348
12349        // Dismiss any open dialogs.
12350        if (app.crashDialog != null && !app.forceCrashReport) {
12351            app.crashDialog.dismiss();
12352            app.crashDialog = null;
12353        }
12354        if (app.anrDialog != null) {
12355            app.anrDialog.dismiss();
12356            app.anrDialog = null;
12357        }
12358        if (app.waitDialog != null) {
12359            app.waitDialog.dismiss();
12360            app.waitDialog = null;
12361        }
12362
12363        app.crashing = false;
12364        app.notResponding = false;
12365
12366        app.resetPackageList(mProcessStats);
12367        app.unlinkDeathRecipient();
12368        app.makeInactive(mProcessStats);
12369        app.forcingToForeground = null;
12370        updateProcessForegroundLocked(app, false, false);
12371        app.foregroundActivities = false;
12372        app.hasShownUi = false;
12373        app.hasAboveClient = false;
12374
12375        mServices.killServicesLocked(app, allowRestart);
12376
12377        boolean restart = false;
12378
12379        // Remove published content providers.
12380        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12381            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12382            final boolean always = app.bad || !allowRestart;
12383            if (removeDyingProviderLocked(app, cpr, always) || always) {
12384                // We left the provider in the launching list, need to
12385                // restart it.
12386                restart = true;
12387            }
12388
12389            cpr.provider = null;
12390            cpr.proc = null;
12391        }
12392        app.pubProviders.clear();
12393
12394        // Take care of any launching providers waiting for this process.
12395        if (checkAppInLaunchingProvidersLocked(app, false)) {
12396            restart = true;
12397        }
12398
12399        // Unregister from connected content providers.
12400        if (!app.conProviders.isEmpty()) {
12401            for (int i=0; i<app.conProviders.size(); i++) {
12402                ContentProviderConnection conn = app.conProviders.get(i);
12403                conn.provider.connections.remove(conn);
12404            }
12405            app.conProviders.clear();
12406        }
12407
12408        // At this point there may be remaining entries in mLaunchingProviders
12409        // where we were the only one waiting, so they are no longer of use.
12410        // Look for these and clean up if found.
12411        // XXX Commented out for now.  Trying to figure out a way to reproduce
12412        // the actual situation to identify what is actually going on.
12413        if (false) {
12414            for (int i=0; i<mLaunchingProviders.size(); i++) {
12415                ContentProviderRecord cpr = (ContentProviderRecord)
12416                        mLaunchingProviders.get(i);
12417                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12418                    synchronized (cpr) {
12419                        cpr.launchingApp = null;
12420                        cpr.notifyAll();
12421                    }
12422                }
12423            }
12424        }
12425
12426        skipCurrentReceiverLocked(app);
12427
12428        // Unregister any receivers.
12429        for (int i=app.receivers.size()-1; i>=0; i--) {
12430            removeReceiverLocked(app.receivers.valueAt(i));
12431        }
12432        app.receivers.clear();
12433
12434        // If the app is undergoing backup, tell the backup manager about it
12435        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12436            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12437                    + mBackupTarget.appInfo + " died during backup");
12438            try {
12439                IBackupManager bm = IBackupManager.Stub.asInterface(
12440                        ServiceManager.getService(Context.BACKUP_SERVICE));
12441                bm.agentDisconnected(app.info.packageName);
12442            } catch (RemoteException e) {
12443                // can't happen; backup manager is local
12444            }
12445        }
12446
12447        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12448            ProcessChangeItem item = mPendingProcessChanges.get(i);
12449            if (item.pid == app.pid) {
12450                mPendingProcessChanges.remove(i);
12451                mAvailProcessChanges.add(item);
12452            }
12453        }
12454        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12455
12456        // If the caller is restarting this app, then leave it in its
12457        // current lists and let the caller take care of it.
12458        if (restarting) {
12459            return;
12460        }
12461
12462        if (!app.persistent || app.isolated) {
12463            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12464                    "Removing non-persistent process during cleanup: " + app);
12465            mProcessNames.remove(app.processName, app.uid);
12466            mIsolatedProcesses.remove(app.uid);
12467            if (mHeavyWeightProcess == app) {
12468                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12469                        mHeavyWeightProcess.userId, 0));
12470                mHeavyWeightProcess = null;
12471            }
12472        } else if (!app.removed) {
12473            // This app is persistent, so we need to keep its record around.
12474            // If it is not already on the pending app list, add it there
12475            // and start a new process for it.
12476            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12477                mPersistentStartingProcesses.add(app);
12478                restart = true;
12479            }
12480        }
12481        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12482                "Clean-up removing on hold: " + app);
12483        mProcessesOnHold.remove(app);
12484
12485        if (app == mHomeProcess) {
12486            mHomeProcess = null;
12487        }
12488        if (app == mPreviousProcess) {
12489            mPreviousProcess = null;
12490        }
12491
12492        if (restart && !app.isolated) {
12493            // We have components that still need to be running in the
12494            // process, so re-launch it.
12495            mProcessNames.put(app.processName, app.uid, app);
12496            startProcessLocked(app, "restart", app.processName);
12497        } else if (app.pid > 0 && app.pid != MY_PID) {
12498            // Goodbye!
12499            boolean removed;
12500            synchronized (mPidsSelfLocked) {
12501                mPidsSelfLocked.remove(app.pid);
12502                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12503            }
12504            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12505                    app.processName, app.info.uid);
12506            if (app.isolated) {
12507                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12508            }
12509            app.setPid(0);
12510        }
12511    }
12512
12513    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12514        // Look through the content providers we are waiting to have launched,
12515        // and if any run in this process then either schedule a restart of
12516        // the process or kill the client waiting for it if this process has
12517        // gone bad.
12518        int NL = mLaunchingProviders.size();
12519        boolean restart = false;
12520        for (int i=0; i<NL; i++) {
12521            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12522            if (cpr.launchingApp == app) {
12523                if (!alwaysBad && !app.bad) {
12524                    restart = true;
12525                } else {
12526                    removeDyingProviderLocked(app, cpr, true);
12527                    // cpr should have been removed from mLaunchingProviders
12528                    NL = mLaunchingProviders.size();
12529                    i--;
12530                }
12531            }
12532        }
12533        return restart;
12534    }
12535
12536    // =========================================================
12537    // SERVICES
12538    // =========================================================
12539
12540    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12541            int flags) {
12542        enforceNotIsolatedCaller("getServices");
12543        synchronized (this) {
12544            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12545        }
12546    }
12547
12548    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12549        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12550        synchronized (this) {
12551            return mServices.getRunningServiceControlPanelLocked(name);
12552        }
12553    }
12554
12555    public ComponentName startService(IApplicationThread caller, Intent service,
12556            String resolvedType, int userId) {
12557        enforceNotIsolatedCaller("startService");
12558        // Refuse possible leaked file descriptors
12559        if (service != null && service.hasFileDescriptors() == true) {
12560            throw new IllegalArgumentException("File descriptors passed in Intent");
12561        }
12562
12563        if (DEBUG_SERVICE)
12564            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12565        synchronized(this) {
12566            final int callingPid = Binder.getCallingPid();
12567            final int callingUid = Binder.getCallingUid();
12568            final long origId = Binder.clearCallingIdentity();
12569            ComponentName res = mServices.startServiceLocked(caller, service,
12570                    resolvedType, callingPid, callingUid, userId);
12571            Binder.restoreCallingIdentity(origId);
12572            return res;
12573        }
12574    }
12575
12576    ComponentName startServiceInPackage(int uid,
12577            Intent service, String resolvedType, int userId) {
12578        synchronized(this) {
12579            if (DEBUG_SERVICE)
12580                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12581            final long origId = Binder.clearCallingIdentity();
12582            ComponentName res = mServices.startServiceLocked(null, service,
12583                    resolvedType, -1, uid, userId);
12584            Binder.restoreCallingIdentity(origId);
12585            return res;
12586        }
12587    }
12588
12589    public int stopService(IApplicationThread caller, Intent service,
12590            String resolvedType, int userId) {
12591        enforceNotIsolatedCaller("stopService");
12592        // Refuse possible leaked file descriptors
12593        if (service != null && service.hasFileDescriptors() == true) {
12594            throw new IllegalArgumentException("File descriptors passed in Intent");
12595        }
12596
12597        synchronized(this) {
12598            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12599        }
12600    }
12601
12602    public IBinder peekService(Intent service, String resolvedType) {
12603        enforceNotIsolatedCaller("peekService");
12604        // Refuse possible leaked file descriptors
12605        if (service != null && service.hasFileDescriptors() == true) {
12606            throw new IllegalArgumentException("File descriptors passed in Intent");
12607        }
12608        synchronized(this) {
12609            return mServices.peekServiceLocked(service, resolvedType);
12610        }
12611    }
12612
12613    public boolean stopServiceToken(ComponentName className, IBinder token,
12614            int startId) {
12615        synchronized(this) {
12616            return mServices.stopServiceTokenLocked(className, token, startId);
12617        }
12618    }
12619
12620    public void setServiceForeground(ComponentName className, IBinder token,
12621            int id, Notification notification, boolean removeNotification) {
12622        synchronized(this) {
12623            mServices.setServiceForegroundLocked(className, token, id, notification,
12624                    removeNotification);
12625        }
12626    }
12627
12628    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12629            boolean requireFull, String name, String callerPackage) {
12630        final int callingUserId = UserHandle.getUserId(callingUid);
12631        if (callingUserId != userId) {
12632            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12633                if ((requireFull || checkComponentPermission(
12634                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12635                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12636                        && checkComponentPermission(
12637                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12638                                callingPid, callingUid, -1, true)
12639                                != PackageManager.PERMISSION_GRANTED) {
12640                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12641                        // In this case, they would like to just execute as their
12642                        // owner user instead of failing.
12643                        userId = callingUserId;
12644                    } else {
12645                        StringBuilder builder = new StringBuilder(128);
12646                        builder.append("Permission Denial: ");
12647                        builder.append(name);
12648                        if (callerPackage != null) {
12649                            builder.append(" from ");
12650                            builder.append(callerPackage);
12651                        }
12652                        builder.append(" asks to run as user ");
12653                        builder.append(userId);
12654                        builder.append(" but is calling from user ");
12655                        builder.append(UserHandle.getUserId(callingUid));
12656                        builder.append("; this requires ");
12657                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12658                        if (!requireFull) {
12659                            builder.append(" or ");
12660                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12661                        }
12662                        String msg = builder.toString();
12663                        Slog.w(TAG, msg);
12664                        throw new SecurityException(msg);
12665                    }
12666                }
12667            }
12668            if (userId == UserHandle.USER_CURRENT
12669                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12670                // Note that we may be accessing this outside of a lock...
12671                // shouldn't be a big deal, if this is being called outside
12672                // of a locked context there is intrinsically a race with
12673                // the value the caller will receive and someone else changing it.
12674                userId = mCurrentUserId;
12675            }
12676            if (!allowAll && userId < 0) {
12677                throw new IllegalArgumentException(
12678                        "Call does not support special user #" + userId);
12679            }
12680        }
12681        return userId;
12682    }
12683
12684    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12685            String className, int flags) {
12686        boolean result = false;
12687        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12688            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12689                if (ActivityManager.checkUidPermission(
12690                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12691                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12692                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12693                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12694                            + " requests FLAG_SINGLE_USER, but app does not hold "
12695                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12696                    Slog.w(TAG, msg);
12697                    throw new SecurityException(msg);
12698                }
12699                result = true;
12700            }
12701        } else if (componentProcessName == aInfo.packageName) {
12702            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12703        } else if ("system".equals(componentProcessName)) {
12704            result = true;
12705        }
12706        if (DEBUG_MU) {
12707            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12708                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12709        }
12710        return result;
12711    }
12712
12713    public int bindService(IApplicationThread caller, IBinder token,
12714            Intent service, String resolvedType,
12715            IServiceConnection connection, int flags, int userId) {
12716        enforceNotIsolatedCaller("bindService");
12717        // Refuse possible leaked file descriptors
12718        if (service != null && service.hasFileDescriptors() == true) {
12719            throw new IllegalArgumentException("File descriptors passed in Intent");
12720        }
12721
12722        synchronized(this) {
12723            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12724                    connection, flags, userId);
12725        }
12726    }
12727
12728    public boolean unbindService(IServiceConnection connection) {
12729        synchronized (this) {
12730            return mServices.unbindServiceLocked(connection);
12731        }
12732    }
12733
12734    public void publishService(IBinder token, Intent intent, IBinder service) {
12735        // Refuse possible leaked file descriptors
12736        if (intent != null && intent.hasFileDescriptors() == true) {
12737            throw new IllegalArgumentException("File descriptors passed in Intent");
12738        }
12739
12740        synchronized(this) {
12741            if (!(token instanceof ServiceRecord)) {
12742                throw new IllegalArgumentException("Invalid service token");
12743            }
12744            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12745        }
12746    }
12747
12748    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12749        // Refuse possible leaked file descriptors
12750        if (intent != null && intent.hasFileDescriptors() == true) {
12751            throw new IllegalArgumentException("File descriptors passed in Intent");
12752        }
12753
12754        synchronized(this) {
12755            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12756        }
12757    }
12758
12759    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12760        synchronized(this) {
12761            if (!(token instanceof ServiceRecord)) {
12762                throw new IllegalArgumentException("Invalid service token");
12763            }
12764            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12765        }
12766    }
12767
12768    // =========================================================
12769    // BACKUP AND RESTORE
12770    // =========================================================
12771
12772    // Cause the target app to be launched if necessary and its backup agent
12773    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12774    // activity manager to announce its creation.
12775    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12776        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12777        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12778
12779        synchronized(this) {
12780            // !!! TODO: currently no check here that we're already bound
12781            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12782            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12783            synchronized (stats) {
12784                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12785            }
12786
12787            // Backup agent is now in use, its package can't be stopped.
12788            try {
12789                AppGlobals.getPackageManager().setPackageStoppedState(
12790                        app.packageName, false, UserHandle.getUserId(app.uid));
12791            } catch (RemoteException e) {
12792            } catch (IllegalArgumentException e) {
12793                Slog.w(TAG, "Failed trying to unstop package "
12794                        + app.packageName + ": " + e);
12795            }
12796
12797            BackupRecord r = new BackupRecord(ss, app, backupMode);
12798            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12799                    ? new ComponentName(app.packageName, app.backupAgentName)
12800                    : new ComponentName("android", "FullBackupAgent");
12801            // startProcessLocked() returns existing proc's record if it's already running
12802            ProcessRecord proc = startProcessLocked(app.processName, app,
12803                    false, 0, "backup", hostingName, false, false, false);
12804            if (proc == null) {
12805                Slog.e(TAG, "Unable to start backup agent process " + r);
12806                return false;
12807            }
12808
12809            r.app = proc;
12810            mBackupTarget = r;
12811            mBackupAppName = app.packageName;
12812
12813            // Try not to kill the process during backup
12814            updateOomAdjLocked(proc);
12815
12816            // If the process is already attached, schedule the creation of the backup agent now.
12817            // If it is not yet live, this will be done when it attaches to the framework.
12818            if (proc.thread != null) {
12819                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12820                try {
12821                    proc.thread.scheduleCreateBackupAgent(app,
12822                            compatibilityInfoForPackageLocked(app), backupMode);
12823                } catch (RemoteException e) {
12824                    // Will time out on the backup manager side
12825                }
12826            } else {
12827                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12828            }
12829            // Invariants: at this point, the target app process exists and the application
12830            // is either already running or in the process of coming up.  mBackupTarget and
12831            // mBackupAppName describe the app, so that when it binds back to the AM we
12832            // know that it's scheduled for a backup-agent operation.
12833        }
12834
12835        return true;
12836    }
12837
12838    @Override
12839    public void clearPendingBackup() {
12840        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12841        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12842
12843        synchronized (this) {
12844            mBackupTarget = null;
12845            mBackupAppName = null;
12846        }
12847    }
12848
12849    // A backup agent has just come up
12850    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12851        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12852                + " = " + agent);
12853
12854        synchronized(this) {
12855            if (!agentPackageName.equals(mBackupAppName)) {
12856                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12857                return;
12858            }
12859        }
12860
12861        long oldIdent = Binder.clearCallingIdentity();
12862        try {
12863            IBackupManager bm = IBackupManager.Stub.asInterface(
12864                    ServiceManager.getService(Context.BACKUP_SERVICE));
12865            bm.agentConnected(agentPackageName, agent);
12866        } catch (RemoteException e) {
12867            // can't happen; the backup manager service is local
12868        } catch (Exception e) {
12869            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12870            e.printStackTrace();
12871        } finally {
12872            Binder.restoreCallingIdentity(oldIdent);
12873        }
12874    }
12875
12876    // done with this agent
12877    public void unbindBackupAgent(ApplicationInfo appInfo) {
12878        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12879        if (appInfo == null) {
12880            Slog.w(TAG, "unbind backup agent for null app");
12881            return;
12882        }
12883
12884        synchronized(this) {
12885            try {
12886                if (mBackupAppName == null) {
12887                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12888                    return;
12889                }
12890
12891                if (!mBackupAppName.equals(appInfo.packageName)) {
12892                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12893                    return;
12894                }
12895
12896                // Not backing this app up any more; reset its OOM adjustment
12897                final ProcessRecord proc = mBackupTarget.app;
12898                updateOomAdjLocked(proc);
12899
12900                // If the app crashed during backup, 'thread' will be null here
12901                if (proc.thread != null) {
12902                    try {
12903                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12904                                compatibilityInfoForPackageLocked(appInfo));
12905                    } catch (Exception e) {
12906                        Slog.e(TAG, "Exception when unbinding backup agent:");
12907                        e.printStackTrace();
12908                    }
12909                }
12910            } finally {
12911                mBackupTarget = null;
12912                mBackupAppName = null;
12913            }
12914        }
12915    }
12916    // =========================================================
12917    // BROADCASTS
12918    // =========================================================
12919
12920    private final List getStickiesLocked(String action, IntentFilter filter,
12921            List cur, int userId) {
12922        final ContentResolver resolver = mContext.getContentResolver();
12923        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12924        if (stickies == null) {
12925            return cur;
12926        }
12927        final ArrayList<Intent> list = stickies.get(action);
12928        if (list == null) {
12929            return cur;
12930        }
12931        int N = list.size();
12932        for (int i=0; i<N; i++) {
12933            Intent intent = list.get(i);
12934            if (filter.match(resolver, intent, true, TAG) >= 0) {
12935                if (cur == null) {
12936                    cur = new ArrayList<Intent>();
12937                }
12938                cur.add(intent);
12939            }
12940        }
12941        return cur;
12942    }
12943
12944    boolean isPendingBroadcastProcessLocked(int pid) {
12945        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12946                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12947    }
12948
12949    void skipPendingBroadcastLocked(int pid) {
12950            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12951            for (BroadcastQueue queue : mBroadcastQueues) {
12952                queue.skipPendingBroadcastLocked(pid);
12953            }
12954    }
12955
12956    // The app just attached; send any pending broadcasts that it should receive
12957    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12958        boolean didSomething = false;
12959        for (BroadcastQueue queue : mBroadcastQueues) {
12960            didSomething |= queue.sendPendingBroadcastsLocked(app);
12961        }
12962        return didSomething;
12963    }
12964
12965    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12966            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12967        enforceNotIsolatedCaller("registerReceiver");
12968        int callingUid;
12969        int callingPid;
12970        synchronized(this) {
12971            ProcessRecord callerApp = null;
12972            if (caller != null) {
12973                callerApp = getRecordForAppLocked(caller);
12974                if (callerApp == null) {
12975                    throw new SecurityException(
12976                            "Unable to find app for caller " + caller
12977                            + " (pid=" + Binder.getCallingPid()
12978                            + ") when registering receiver " + receiver);
12979                }
12980                if (callerApp.info.uid != Process.SYSTEM_UID &&
12981                        !callerApp.pkgList.containsKey(callerPackage) &&
12982                        !"android".equals(callerPackage)) {
12983                    throw new SecurityException("Given caller package " + callerPackage
12984                            + " is not running in process " + callerApp);
12985                }
12986                callingUid = callerApp.info.uid;
12987                callingPid = callerApp.pid;
12988            } else {
12989                callerPackage = null;
12990                callingUid = Binder.getCallingUid();
12991                callingPid = Binder.getCallingPid();
12992            }
12993
12994            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12995                    true, true, "registerReceiver", callerPackage);
12996
12997            List allSticky = null;
12998
12999            // Look for any matching sticky broadcasts...
13000            Iterator actions = filter.actionsIterator();
13001            if (actions != null) {
13002                while (actions.hasNext()) {
13003                    String action = (String)actions.next();
13004                    allSticky = getStickiesLocked(action, filter, allSticky,
13005                            UserHandle.USER_ALL);
13006                    allSticky = getStickiesLocked(action, filter, allSticky,
13007                            UserHandle.getUserId(callingUid));
13008                }
13009            } else {
13010                allSticky = getStickiesLocked(null, filter, allSticky,
13011                        UserHandle.USER_ALL);
13012                allSticky = getStickiesLocked(null, filter, allSticky,
13013                        UserHandle.getUserId(callingUid));
13014            }
13015
13016            // The first sticky in the list is returned directly back to
13017            // the client.
13018            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13019
13020            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13021                    + ": " + sticky);
13022
13023            if (receiver == null) {
13024                return sticky;
13025            }
13026
13027            ReceiverList rl
13028                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13029            if (rl == null) {
13030                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13031                        userId, receiver);
13032                if (rl.app != null) {
13033                    rl.app.receivers.add(rl);
13034                } else {
13035                    try {
13036                        receiver.asBinder().linkToDeath(rl, 0);
13037                    } catch (RemoteException e) {
13038                        return sticky;
13039                    }
13040                    rl.linkedToDeath = true;
13041                }
13042                mRegisteredReceivers.put(receiver.asBinder(), rl);
13043            } else if (rl.uid != callingUid) {
13044                throw new IllegalArgumentException(
13045                        "Receiver requested to register for uid " + callingUid
13046                        + " was previously registered for uid " + rl.uid);
13047            } else if (rl.pid != callingPid) {
13048                throw new IllegalArgumentException(
13049                        "Receiver requested to register for pid " + callingPid
13050                        + " was previously registered for pid " + rl.pid);
13051            } else if (rl.userId != userId) {
13052                throw new IllegalArgumentException(
13053                        "Receiver requested to register for user " + userId
13054                        + " was previously registered for user " + rl.userId);
13055            }
13056            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13057                    permission, callingUid, userId);
13058            rl.add(bf);
13059            if (!bf.debugCheck()) {
13060                Slog.w(TAG, "==> For Dynamic broadast");
13061            }
13062            mReceiverResolver.addFilter(bf);
13063
13064            // Enqueue broadcasts for all existing stickies that match
13065            // this filter.
13066            if (allSticky != null) {
13067                ArrayList receivers = new ArrayList();
13068                receivers.add(bf);
13069
13070                int N = allSticky.size();
13071                for (int i=0; i<N; i++) {
13072                    Intent intent = (Intent)allSticky.get(i);
13073                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13074                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13075                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13076                            null, null, false, true, true, -1);
13077                    queue.enqueueParallelBroadcastLocked(r);
13078                    queue.scheduleBroadcastsLocked();
13079                }
13080            }
13081
13082            return sticky;
13083        }
13084    }
13085
13086    public void unregisterReceiver(IIntentReceiver receiver) {
13087        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13088
13089        final long origId = Binder.clearCallingIdentity();
13090        try {
13091            boolean doTrim = false;
13092
13093            synchronized(this) {
13094                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13095                if (rl != null) {
13096                    if (rl.curBroadcast != null) {
13097                        BroadcastRecord r = rl.curBroadcast;
13098                        final boolean doNext = finishReceiverLocked(
13099                                receiver.asBinder(), r.resultCode, r.resultData,
13100                                r.resultExtras, r.resultAbort);
13101                        if (doNext) {
13102                            doTrim = true;
13103                            r.queue.processNextBroadcast(false);
13104                        }
13105                    }
13106
13107                    if (rl.app != null) {
13108                        rl.app.receivers.remove(rl);
13109                    }
13110                    removeReceiverLocked(rl);
13111                    if (rl.linkedToDeath) {
13112                        rl.linkedToDeath = false;
13113                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13114                    }
13115                }
13116            }
13117
13118            // If we actually concluded any broadcasts, we might now be able
13119            // to trim the recipients' apps from our working set
13120            if (doTrim) {
13121                trimApplications();
13122                return;
13123            }
13124
13125        } finally {
13126            Binder.restoreCallingIdentity(origId);
13127        }
13128    }
13129
13130    void removeReceiverLocked(ReceiverList rl) {
13131        mRegisteredReceivers.remove(rl.receiver.asBinder());
13132        int N = rl.size();
13133        for (int i=0; i<N; i++) {
13134            mReceiverResolver.removeFilter(rl.get(i));
13135        }
13136    }
13137
13138    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13139        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13140            ProcessRecord r = mLruProcesses.get(i);
13141            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13142                try {
13143                    r.thread.dispatchPackageBroadcast(cmd, packages);
13144                } catch (RemoteException ex) {
13145                }
13146            }
13147        }
13148    }
13149
13150    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13151            int[] users) {
13152        List<ResolveInfo> receivers = null;
13153        try {
13154            HashSet<ComponentName> singleUserReceivers = null;
13155            boolean scannedFirstReceivers = false;
13156            for (int user : users) {
13157                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13158                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13159                if (user != 0 && newReceivers != null) {
13160                    // If this is not the primary user, we need to check for
13161                    // any receivers that should be filtered out.
13162                    for (int i=0; i<newReceivers.size(); i++) {
13163                        ResolveInfo ri = newReceivers.get(i);
13164                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13165                            newReceivers.remove(i);
13166                            i--;
13167                        }
13168                    }
13169                }
13170                if (newReceivers != null && newReceivers.size() == 0) {
13171                    newReceivers = null;
13172                }
13173                if (receivers == null) {
13174                    receivers = newReceivers;
13175                } else if (newReceivers != null) {
13176                    // We need to concatenate the additional receivers
13177                    // found with what we have do far.  This would be easy,
13178                    // but we also need to de-dup any receivers that are
13179                    // singleUser.
13180                    if (!scannedFirstReceivers) {
13181                        // Collect any single user receivers we had already retrieved.
13182                        scannedFirstReceivers = true;
13183                        for (int i=0; i<receivers.size(); i++) {
13184                            ResolveInfo ri = receivers.get(i);
13185                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13186                                ComponentName cn = new ComponentName(
13187                                        ri.activityInfo.packageName, ri.activityInfo.name);
13188                                if (singleUserReceivers == null) {
13189                                    singleUserReceivers = new HashSet<ComponentName>();
13190                                }
13191                                singleUserReceivers.add(cn);
13192                            }
13193                        }
13194                    }
13195                    // Add the new results to the existing results, tracking
13196                    // and de-dupping single user receivers.
13197                    for (int i=0; i<newReceivers.size(); i++) {
13198                        ResolveInfo ri = newReceivers.get(i);
13199                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13200                            ComponentName cn = new ComponentName(
13201                                    ri.activityInfo.packageName, ri.activityInfo.name);
13202                            if (singleUserReceivers == null) {
13203                                singleUserReceivers = new HashSet<ComponentName>();
13204                            }
13205                            if (!singleUserReceivers.contains(cn)) {
13206                                singleUserReceivers.add(cn);
13207                                receivers.add(ri);
13208                            }
13209                        } else {
13210                            receivers.add(ri);
13211                        }
13212                    }
13213                }
13214            }
13215        } catch (RemoteException ex) {
13216            // pm is in same process, this will never happen.
13217        }
13218        return receivers;
13219    }
13220
13221    private final int broadcastIntentLocked(ProcessRecord callerApp,
13222            String callerPackage, Intent intent, String resolvedType,
13223            IIntentReceiver resultTo, int resultCode, String resultData,
13224            Bundle map, String requiredPermission, int appOp,
13225            boolean ordered, boolean sticky, int callingPid, int callingUid,
13226            int userId) {
13227        intent = new Intent(intent);
13228
13229        // By default broadcasts do not go to stopped apps.
13230        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13231
13232        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13233            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13234            + " ordered=" + ordered + " userid=" + userId);
13235        if ((resultTo != null) && !ordered) {
13236            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13237        }
13238
13239        userId = handleIncomingUser(callingPid, callingUid, userId,
13240                true, false, "broadcast", callerPackage);
13241
13242        // Make sure that the user who is receiving this broadcast is started.
13243        // If not, we will just skip it.
13244        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13245            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13246                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13247                Slog.w(TAG, "Skipping broadcast of " + intent
13248                        + ": user " + userId + " is stopped");
13249                return ActivityManager.BROADCAST_SUCCESS;
13250            }
13251        }
13252
13253        /*
13254         * Prevent non-system code (defined here to be non-persistent
13255         * processes) from sending protected broadcasts.
13256         */
13257        int callingAppId = UserHandle.getAppId(callingUid);
13258        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13259            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13260            callingUid == 0) {
13261            // Always okay.
13262        } else if (callerApp == null || !callerApp.persistent) {
13263            try {
13264                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13265                        intent.getAction())) {
13266                    String msg = "Permission Denial: not allowed to send broadcast "
13267                            + intent.getAction() + " from pid="
13268                            + callingPid + ", uid=" + callingUid;
13269                    Slog.w(TAG, msg);
13270                    throw new SecurityException(msg);
13271                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13272                    // Special case for compatibility: we don't want apps to send this,
13273                    // but historically it has not been protected and apps may be using it
13274                    // to poke their own app widget.  So, instead of making it protected,
13275                    // just limit it to the caller.
13276                    if (callerApp == null) {
13277                        String msg = "Permission Denial: not allowed to send broadcast "
13278                                + intent.getAction() + " from unknown caller.";
13279                        Slog.w(TAG, msg);
13280                        throw new SecurityException(msg);
13281                    } else if (intent.getComponent() != null) {
13282                        // They are good enough to send to an explicit component...  verify
13283                        // it is being sent to the calling app.
13284                        if (!intent.getComponent().getPackageName().equals(
13285                                callerApp.info.packageName)) {
13286                            String msg = "Permission Denial: not allowed to send broadcast "
13287                                    + intent.getAction() + " to "
13288                                    + intent.getComponent().getPackageName() + " from "
13289                                    + callerApp.info.packageName;
13290                            Slog.w(TAG, msg);
13291                            throw new SecurityException(msg);
13292                        }
13293                    } else {
13294                        // Limit broadcast to their own package.
13295                        intent.setPackage(callerApp.info.packageName);
13296                    }
13297                }
13298            } catch (RemoteException e) {
13299                Slog.w(TAG, "Remote exception", e);
13300                return ActivityManager.BROADCAST_SUCCESS;
13301            }
13302        }
13303
13304        // Handle special intents: if this broadcast is from the package
13305        // manager about a package being removed, we need to remove all of
13306        // its activities from the history stack.
13307        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13308                intent.getAction());
13309        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13310                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13311                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13312                || uidRemoved) {
13313            if (checkComponentPermission(
13314                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13315                    callingPid, callingUid, -1, true)
13316                    == PackageManager.PERMISSION_GRANTED) {
13317                if (uidRemoved) {
13318                    final Bundle intentExtras = intent.getExtras();
13319                    final int uid = intentExtras != null
13320                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13321                    if (uid >= 0) {
13322                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13323                        synchronized (bs) {
13324                            bs.removeUidStatsLocked(uid);
13325                        }
13326                        mAppOpsService.uidRemoved(uid);
13327                    }
13328                } else {
13329                    // If resources are unavailable just force stop all
13330                    // those packages and flush the attribute cache as well.
13331                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13332                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13333                        if (list != null && (list.length > 0)) {
13334                            for (String pkg : list) {
13335                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13336                                        "storage unmount");
13337                            }
13338                            sendPackageBroadcastLocked(
13339                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13340                        }
13341                    } else {
13342                        Uri data = intent.getData();
13343                        String ssp;
13344                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13345                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13346                                    intent.getAction());
13347                            boolean fullUninstall = removed &&
13348                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13349                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13350                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13351                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13352                                        false, fullUninstall, userId,
13353                                        removed ? "pkg removed" : "pkg changed");
13354                            }
13355                            if (removed) {
13356                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13357                                        new String[] {ssp}, userId);
13358                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13359                                    mAppOpsService.packageRemoved(
13360                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13361
13362                                    // Remove all permissions granted from/to this package
13363                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13364                                }
13365                            }
13366                        }
13367                    }
13368                }
13369            } else {
13370                String msg = "Permission Denial: " + intent.getAction()
13371                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13372                        + ", uid=" + callingUid + ")"
13373                        + " requires "
13374                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13375                Slog.w(TAG, msg);
13376                throw new SecurityException(msg);
13377            }
13378
13379        // Special case for adding a package: by default turn on compatibility
13380        // mode.
13381        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13382            Uri data = intent.getData();
13383            String ssp;
13384            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13385                mCompatModePackages.handlePackageAddedLocked(ssp,
13386                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13387            }
13388        }
13389
13390        /*
13391         * If this is the time zone changed action, queue up a message that will reset the timezone
13392         * of all currently running processes. This message will get queued up before the broadcast
13393         * happens.
13394         */
13395        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13396            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13397        }
13398
13399        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13400            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13401        }
13402
13403        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13404            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13405            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13406        }
13407
13408        // Add to the sticky list if requested.
13409        if (sticky) {
13410            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13411                    callingPid, callingUid)
13412                    != PackageManager.PERMISSION_GRANTED) {
13413                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13414                        + callingPid + ", uid=" + callingUid
13415                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13416                Slog.w(TAG, msg);
13417                throw new SecurityException(msg);
13418            }
13419            if (requiredPermission != null) {
13420                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13421                        + " and enforce permission " + requiredPermission);
13422                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13423            }
13424            if (intent.getComponent() != null) {
13425                throw new SecurityException(
13426                        "Sticky broadcasts can't target a specific component");
13427            }
13428            // We use userId directly here, since the "all" target is maintained
13429            // as a separate set of sticky broadcasts.
13430            if (userId != UserHandle.USER_ALL) {
13431                // But first, if this is not a broadcast to all users, then
13432                // make sure it doesn't conflict with an existing broadcast to
13433                // all users.
13434                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13435                        UserHandle.USER_ALL);
13436                if (stickies != null) {
13437                    ArrayList<Intent> list = stickies.get(intent.getAction());
13438                    if (list != null) {
13439                        int N = list.size();
13440                        int i;
13441                        for (i=0; i<N; i++) {
13442                            if (intent.filterEquals(list.get(i))) {
13443                                throw new IllegalArgumentException(
13444                                        "Sticky broadcast " + intent + " for user "
13445                                        + userId + " conflicts with existing global broadcast");
13446                            }
13447                        }
13448                    }
13449                }
13450            }
13451            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13452            if (stickies == null) {
13453                stickies = new ArrayMap<String, ArrayList<Intent>>();
13454                mStickyBroadcasts.put(userId, stickies);
13455            }
13456            ArrayList<Intent> list = stickies.get(intent.getAction());
13457            if (list == null) {
13458                list = new ArrayList<Intent>();
13459                stickies.put(intent.getAction(), list);
13460            }
13461            int N = list.size();
13462            int i;
13463            for (i=0; i<N; i++) {
13464                if (intent.filterEquals(list.get(i))) {
13465                    // This sticky already exists, replace it.
13466                    list.set(i, new Intent(intent));
13467                    break;
13468                }
13469            }
13470            if (i >= N) {
13471                list.add(new Intent(intent));
13472            }
13473        }
13474
13475        int[] users;
13476        if (userId == UserHandle.USER_ALL) {
13477            // Caller wants broadcast to go to all started users.
13478            users = mStartedUserArray;
13479        } else {
13480            // Caller wants broadcast to go to one specific user.
13481            users = new int[] {userId};
13482        }
13483
13484        // Figure out who all will receive this broadcast.
13485        List receivers = null;
13486        List<BroadcastFilter> registeredReceivers = null;
13487        // Need to resolve the intent to interested receivers...
13488        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13489                 == 0) {
13490            receivers = collectReceiverComponents(intent, resolvedType, users);
13491        }
13492        if (intent.getComponent() == null) {
13493            registeredReceivers = mReceiverResolver.queryIntent(intent,
13494                    resolvedType, false, userId);
13495        }
13496
13497        final boolean replacePending =
13498                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13499
13500        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13501                + " replacePending=" + replacePending);
13502
13503        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13504        if (!ordered && NR > 0) {
13505            // If we are not serializing this broadcast, then send the
13506            // registered receivers separately so they don't wait for the
13507            // components to be launched.
13508            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13509            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13510                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13511                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13512                    ordered, sticky, false, userId);
13513            if (DEBUG_BROADCAST) Slog.v(
13514                    TAG, "Enqueueing parallel broadcast " + r);
13515            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13516            if (!replaced) {
13517                queue.enqueueParallelBroadcastLocked(r);
13518                queue.scheduleBroadcastsLocked();
13519            }
13520            registeredReceivers = null;
13521            NR = 0;
13522        }
13523
13524        // Merge into one list.
13525        int ir = 0;
13526        if (receivers != null) {
13527            // A special case for PACKAGE_ADDED: do not allow the package
13528            // being added to see this broadcast.  This prevents them from
13529            // using this as a back door to get run as soon as they are
13530            // installed.  Maybe in the future we want to have a special install
13531            // broadcast or such for apps, but we'd like to deliberately make
13532            // this decision.
13533            String skipPackages[] = null;
13534            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13535                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13536                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13537                Uri data = intent.getData();
13538                if (data != null) {
13539                    String pkgName = data.getSchemeSpecificPart();
13540                    if (pkgName != null) {
13541                        skipPackages = new String[] { pkgName };
13542                    }
13543                }
13544            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13545                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13546            }
13547            if (skipPackages != null && (skipPackages.length > 0)) {
13548                for (String skipPackage : skipPackages) {
13549                    if (skipPackage != null) {
13550                        int NT = receivers.size();
13551                        for (int it=0; it<NT; it++) {
13552                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13553                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13554                                receivers.remove(it);
13555                                it--;
13556                                NT--;
13557                            }
13558                        }
13559                    }
13560                }
13561            }
13562
13563            int NT = receivers != null ? receivers.size() : 0;
13564            int it = 0;
13565            ResolveInfo curt = null;
13566            BroadcastFilter curr = null;
13567            while (it < NT && ir < NR) {
13568                if (curt == null) {
13569                    curt = (ResolveInfo)receivers.get(it);
13570                }
13571                if (curr == null) {
13572                    curr = registeredReceivers.get(ir);
13573                }
13574                if (curr.getPriority() >= curt.priority) {
13575                    // Insert this broadcast record into the final list.
13576                    receivers.add(it, curr);
13577                    ir++;
13578                    curr = null;
13579                    it++;
13580                    NT++;
13581                } else {
13582                    // Skip to the next ResolveInfo in the final list.
13583                    it++;
13584                    curt = null;
13585                }
13586            }
13587        }
13588        while (ir < NR) {
13589            if (receivers == null) {
13590                receivers = new ArrayList();
13591            }
13592            receivers.add(registeredReceivers.get(ir));
13593            ir++;
13594        }
13595
13596        if ((receivers != null && receivers.size() > 0)
13597                || resultTo != null) {
13598            BroadcastQueue queue = broadcastQueueForIntent(intent);
13599            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13600                    callerPackage, callingPid, callingUid, resolvedType,
13601                    requiredPermission, appOp, receivers, resultTo, resultCode,
13602                    resultData, map, ordered, sticky, false, userId);
13603            if (DEBUG_BROADCAST) Slog.v(
13604                    TAG, "Enqueueing ordered broadcast " + r
13605                    + ": prev had " + queue.mOrderedBroadcasts.size());
13606            if (DEBUG_BROADCAST) {
13607                int seq = r.intent.getIntExtra("seq", -1);
13608                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13609            }
13610            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13611            if (!replaced) {
13612                queue.enqueueOrderedBroadcastLocked(r);
13613                queue.scheduleBroadcastsLocked();
13614            }
13615        }
13616
13617        return ActivityManager.BROADCAST_SUCCESS;
13618    }
13619
13620    final Intent verifyBroadcastLocked(Intent intent) {
13621        // Refuse possible leaked file descriptors
13622        if (intent != null && intent.hasFileDescriptors() == true) {
13623            throw new IllegalArgumentException("File descriptors passed in Intent");
13624        }
13625
13626        int flags = intent.getFlags();
13627
13628        if (!mProcessesReady) {
13629            // if the caller really truly claims to know what they're doing, go
13630            // ahead and allow the broadcast without launching any receivers
13631            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13632                intent = new Intent(intent);
13633                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13634            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13635                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13636                        + " before boot completion");
13637                throw new IllegalStateException("Cannot broadcast before boot completed");
13638            }
13639        }
13640
13641        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13642            throw new IllegalArgumentException(
13643                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13644        }
13645
13646        return intent;
13647    }
13648
13649    public final int broadcastIntent(IApplicationThread caller,
13650            Intent intent, String resolvedType, IIntentReceiver resultTo,
13651            int resultCode, String resultData, Bundle map,
13652            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13653        enforceNotIsolatedCaller("broadcastIntent");
13654        synchronized(this) {
13655            intent = verifyBroadcastLocked(intent);
13656
13657            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13658            final int callingPid = Binder.getCallingPid();
13659            final int callingUid = Binder.getCallingUid();
13660            final long origId = Binder.clearCallingIdentity();
13661            int res = broadcastIntentLocked(callerApp,
13662                    callerApp != null ? callerApp.info.packageName : null,
13663                    intent, resolvedType, resultTo,
13664                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13665                    callingPid, callingUid, userId);
13666            Binder.restoreCallingIdentity(origId);
13667            return res;
13668        }
13669    }
13670
13671    int broadcastIntentInPackage(String packageName, int uid,
13672            Intent intent, String resolvedType, IIntentReceiver resultTo,
13673            int resultCode, String resultData, Bundle map,
13674            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13675        synchronized(this) {
13676            intent = verifyBroadcastLocked(intent);
13677
13678            final long origId = Binder.clearCallingIdentity();
13679            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13680                    resultTo, resultCode, resultData, map, requiredPermission,
13681                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13682            Binder.restoreCallingIdentity(origId);
13683            return res;
13684        }
13685    }
13686
13687    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13688        // Refuse possible leaked file descriptors
13689        if (intent != null && intent.hasFileDescriptors() == true) {
13690            throw new IllegalArgumentException("File descriptors passed in Intent");
13691        }
13692
13693        userId = handleIncomingUser(Binder.getCallingPid(),
13694                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13695
13696        synchronized(this) {
13697            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13698                    != PackageManager.PERMISSION_GRANTED) {
13699                String msg = "Permission Denial: unbroadcastIntent() from pid="
13700                        + Binder.getCallingPid()
13701                        + ", uid=" + Binder.getCallingUid()
13702                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13703                Slog.w(TAG, msg);
13704                throw new SecurityException(msg);
13705            }
13706            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13707            if (stickies != null) {
13708                ArrayList<Intent> list = stickies.get(intent.getAction());
13709                if (list != null) {
13710                    int N = list.size();
13711                    int i;
13712                    for (i=0; i<N; i++) {
13713                        if (intent.filterEquals(list.get(i))) {
13714                            list.remove(i);
13715                            break;
13716                        }
13717                    }
13718                    if (list.size() <= 0) {
13719                        stickies.remove(intent.getAction());
13720                    }
13721                }
13722                if (stickies.size() <= 0) {
13723                    mStickyBroadcasts.remove(userId);
13724                }
13725            }
13726        }
13727    }
13728
13729    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13730            String resultData, Bundle resultExtras, boolean resultAbort) {
13731        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13732        if (r == null) {
13733            Slog.w(TAG, "finishReceiver called but not found on queue");
13734            return false;
13735        }
13736
13737        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13738    }
13739
13740    void backgroundServicesFinishedLocked(int userId) {
13741        for (BroadcastQueue queue : mBroadcastQueues) {
13742            queue.backgroundServicesFinishedLocked(userId);
13743        }
13744    }
13745
13746    public void finishReceiver(IBinder who, int resultCode, String resultData,
13747            Bundle resultExtras, boolean resultAbort) {
13748        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13749
13750        // Refuse possible leaked file descriptors
13751        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13752            throw new IllegalArgumentException("File descriptors passed in Bundle");
13753        }
13754
13755        final long origId = Binder.clearCallingIdentity();
13756        try {
13757            boolean doNext = false;
13758            BroadcastRecord r;
13759
13760            synchronized(this) {
13761                r = broadcastRecordForReceiverLocked(who);
13762                if (r != null) {
13763                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13764                        resultData, resultExtras, resultAbort, true);
13765                }
13766            }
13767
13768            if (doNext) {
13769                r.queue.processNextBroadcast(false);
13770            }
13771            trimApplications();
13772        } finally {
13773            Binder.restoreCallingIdentity(origId);
13774        }
13775    }
13776
13777    // =========================================================
13778    // INSTRUMENTATION
13779    // =========================================================
13780
13781    public boolean startInstrumentation(ComponentName className,
13782            String profileFile, int flags, Bundle arguments,
13783            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13784            int userId) {
13785        enforceNotIsolatedCaller("startInstrumentation");
13786        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13787                userId, false, true, "startInstrumentation", null);
13788        // Refuse possible leaked file descriptors
13789        if (arguments != null && arguments.hasFileDescriptors()) {
13790            throw new IllegalArgumentException("File descriptors passed in Bundle");
13791        }
13792
13793        synchronized(this) {
13794            InstrumentationInfo ii = null;
13795            ApplicationInfo ai = null;
13796            try {
13797                ii = mContext.getPackageManager().getInstrumentationInfo(
13798                    className, STOCK_PM_FLAGS);
13799                ai = AppGlobals.getPackageManager().getApplicationInfo(
13800                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13801            } catch (PackageManager.NameNotFoundException e) {
13802            } catch (RemoteException e) {
13803            }
13804            if (ii == null) {
13805                reportStartInstrumentationFailure(watcher, className,
13806                        "Unable to find instrumentation info for: " + className);
13807                return false;
13808            }
13809            if (ai == null) {
13810                reportStartInstrumentationFailure(watcher, className,
13811                        "Unable to find instrumentation target package: " + ii.targetPackage);
13812                return false;
13813            }
13814
13815            int match = mContext.getPackageManager().checkSignatures(
13816                    ii.targetPackage, ii.packageName);
13817            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13818                String msg = "Permission Denial: starting instrumentation "
13819                        + className + " from pid="
13820                        + Binder.getCallingPid()
13821                        + ", uid=" + Binder.getCallingPid()
13822                        + " not allowed because package " + ii.packageName
13823                        + " does not have a signature matching the target "
13824                        + ii.targetPackage;
13825                reportStartInstrumentationFailure(watcher, className, msg);
13826                throw new SecurityException(msg);
13827            }
13828
13829            final long origId = Binder.clearCallingIdentity();
13830            // Instrumentation can kill and relaunch even persistent processes
13831            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
13832                    "start instr");
13833            ProcessRecord app = addAppLocked(ai, false);
13834            app.instrumentationClass = className;
13835            app.instrumentationInfo = ai;
13836            app.instrumentationProfileFile = profileFile;
13837            app.instrumentationArguments = arguments;
13838            app.instrumentationWatcher = watcher;
13839            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13840            app.instrumentationResultClass = className;
13841            Binder.restoreCallingIdentity(origId);
13842        }
13843
13844        return true;
13845    }
13846
13847    /**
13848     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13849     * error to the logs, but if somebody is watching, send the report there too.  This enables
13850     * the "am" command to report errors with more information.
13851     *
13852     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13853     * @param cn The component name of the instrumentation.
13854     * @param report The error report.
13855     */
13856    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13857            ComponentName cn, String report) {
13858        Slog.w(TAG, report);
13859        try {
13860            if (watcher != null) {
13861                Bundle results = new Bundle();
13862                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13863                results.putString("Error", report);
13864                watcher.instrumentationStatus(cn, -1, results);
13865            }
13866        } catch (RemoteException e) {
13867            Slog.w(TAG, e);
13868        }
13869    }
13870
13871    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13872        if (app.instrumentationWatcher != null) {
13873            try {
13874                // NOTE:  IInstrumentationWatcher *must* be oneway here
13875                app.instrumentationWatcher.instrumentationFinished(
13876                    app.instrumentationClass,
13877                    resultCode,
13878                    results);
13879            } catch (RemoteException e) {
13880            }
13881        }
13882        if (app.instrumentationUiAutomationConnection != null) {
13883            try {
13884                app.instrumentationUiAutomationConnection.shutdown();
13885            } catch (RemoteException re) {
13886                /* ignore */
13887            }
13888            // Only a UiAutomation can set this flag and now that
13889            // it is finished we make sure it is reset to its default.
13890            mUserIsMonkey = false;
13891        }
13892        app.instrumentationWatcher = null;
13893        app.instrumentationUiAutomationConnection = null;
13894        app.instrumentationClass = null;
13895        app.instrumentationInfo = null;
13896        app.instrumentationProfileFile = null;
13897        app.instrumentationArguments = null;
13898
13899        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
13900                "finished inst");
13901    }
13902
13903    public void finishInstrumentation(IApplicationThread target,
13904            int resultCode, Bundle results) {
13905        int userId = UserHandle.getCallingUserId();
13906        // Refuse possible leaked file descriptors
13907        if (results != null && results.hasFileDescriptors()) {
13908            throw new IllegalArgumentException("File descriptors passed in Intent");
13909        }
13910
13911        synchronized(this) {
13912            ProcessRecord app = getRecordForAppLocked(target);
13913            if (app == null) {
13914                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13915                return;
13916            }
13917            final long origId = Binder.clearCallingIdentity();
13918            finishInstrumentationLocked(app, resultCode, results);
13919            Binder.restoreCallingIdentity(origId);
13920        }
13921    }
13922
13923    // =========================================================
13924    // CONFIGURATION
13925    // =========================================================
13926
13927    public ConfigurationInfo getDeviceConfigurationInfo() {
13928        ConfigurationInfo config = new ConfigurationInfo();
13929        synchronized (this) {
13930            config.reqTouchScreen = mConfiguration.touchscreen;
13931            config.reqKeyboardType = mConfiguration.keyboard;
13932            config.reqNavigation = mConfiguration.navigation;
13933            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13934                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13935                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13936            }
13937            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13938                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13939                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13940            }
13941            config.reqGlEsVersion = GL_ES_VERSION;
13942        }
13943        return config;
13944    }
13945
13946    ActivityStack getFocusedStack() {
13947        return mStackSupervisor.getFocusedStack();
13948    }
13949
13950    public Configuration getConfiguration() {
13951        Configuration ci;
13952        synchronized(this) {
13953            ci = new Configuration(mConfiguration);
13954        }
13955        return ci;
13956    }
13957
13958    public void updatePersistentConfiguration(Configuration values) {
13959        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13960                "updateConfiguration()");
13961        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13962                "updateConfiguration()");
13963        if (values == null) {
13964            throw new NullPointerException("Configuration must not be null");
13965        }
13966
13967        synchronized(this) {
13968            final long origId = Binder.clearCallingIdentity();
13969            updateConfigurationLocked(values, null, true, false);
13970            Binder.restoreCallingIdentity(origId);
13971        }
13972    }
13973
13974    public void updateConfiguration(Configuration values) {
13975        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13976                "updateConfiguration()");
13977
13978        synchronized(this) {
13979            if (values == null && mWindowManager != null) {
13980                // sentinel: fetch the current configuration from the window manager
13981                values = mWindowManager.computeNewConfiguration();
13982            }
13983
13984            if (mWindowManager != null) {
13985                mProcessList.applyDisplaySize(mWindowManager);
13986            }
13987
13988            final long origId = Binder.clearCallingIdentity();
13989            if (values != null) {
13990                Settings.System.clearConfiguration(values);
13991            }
13992            updateConfigurationLocked(values, null, false, false);
13993            Binder.restoreCallingIdentity(origId);
13994        }
13995    }
13996
13997    /**
13998     * Do either or both things: (1) change the current configuration, and (2)
13999     * make sure the given activity is running with the (now) current
14000     * configuration.  Returns true if the activity has been left running, or
14001     * false if <var>starting</var> is being destroyed to match the new
14002     * configuration.
14003     * @param persistent TODO
14004     */
14005    boolean updateConfigurationLocked(Configuration values,
14006            ActivityRecord starting, boolean persistent, boolean initLocale) {
14007        int changes = 0;
14008
14009        if (values != null) {
14010            Configuration newConfig = new Configuration(mConfiguration);
14011            changes = newConfig.updateFrom(values);
14012            if (changes != 0) {
14013                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14014                    Slog.i(TAG, "Updating configuration to: " + values);
14015                }
14016
14017                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14018
14019                if (values.locale != null && !initLocale) {
14020                    saveLocaleLocked(values.locale,
14021                                     !values.locale.equals(mConfiguration.locale),
14022                                     values.userSetLocale);
14023                }
14024
14025                mConfigurationSeq++;
14026                if (mConfigurationSeq <= 0) {
14027                    mConfigurationSeq = 1;
14028                }
14029                newConfig.seq = mConfigurationSeq;
14030                mConfiguration = newConfig;
14031                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14032
14033                final Configuration configCopy = new Configuration(mConfiguration);
14034
14035                // TODO: If our config changes, should we auto dismiss any currently
14036                // showing dialogs?
14037                mShowDialogs = shouldShowDialogs(newConfig);
14038
14039                AttributeCache ac = AttributeCache.instance();
14040                if (ac != null) {
14041                    ac.updateConfiguration(configCopy);
14042                }
14043
14044                // Make sure all resources in our process are updated
14045                // right now, so that anyone who is going to retrieve
14046                // resource values after we return will be sure to get
14047                // the new ones.  This is especially important during
14048                // boot, where the first config change needs to guarantee
14049                // all resources have that config before following boot
14050                // code is executed.
14051                mSystemThread.applyConfigurationToResources(configCopy);
14052
14053                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14054                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14055                    msg.obj = new Configuration(configCopy);
14056                    mHandler.sendMessage(msg);
14057                }
14058
14059                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14060                    ProcessRecord app = mLruProcesses.get(i);
14061                    try {
14062                        if (app.thread != null) {
14063                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14064                                    + app.processName + " new config " + mConfiguration);
14065                            app.thread.scheduleConfigurationChanged(configCopy);
14066                        }
14067                    } catch (Exception e) {
14068                    }
14069                }
14070                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14071                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14072                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14073                        | Intent.FLAG_RECEIVER_FOREGROUND);
14074                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14075                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14076                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14077                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14078                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14079                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14080                    broadcastIntentLocked(null, null, intent,
14081                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14082                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14083                }
14084            }
14085        }
14086
14087        boolean kept = true;
14088        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14089        // mainStack is null during startup.
14090        if (mainStack != null) {
14091            if (changes != 0 && starting == null) {
14092                // If the configuration changed, and the caller is not already
14093                // in the process of starting an activity, then find the top
14094                // activity to check if its configuration needs to change.
14095                starting = mainStack.topRunningActivityLocked(null);
14096            }
14097
14098            if (starting != null) {
14099                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14100                // And we need to make sure at this point that all other activities
14101                // are made visible with the correct configuration.
14102                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14103            }
14104        }
14105
14106        if (values != null && mWindowManager != null) {
14107            mWindowManager.setNewConfiguration(mConfiguration);
14108        }
14109
14110        return kept;
14111    }
14112
14113    /**
14114     * Decide based on the configuration whether we should shouw the ANR,
14115     * crash, etc dialogs.  The idea is that if there is no affordnace to
14116     * press the on-screen buttons, we shouldn't show the dialog.
14117     *
14118     * A thought: SystemUI might also want to get told about this, the Power
14119     * dialog / global actions also might want different behaviors.
14120     */
14121    private static final boolean shouldShowDialogs(Configuration config) {
14122        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14123                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14124    }
14125
14126    /**
14127     * Save the locale.  You must be inside a synchronized (this) block.
14128     */
14129    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14130        if(isDiff) {
14131            SystemProperties.set("user.language", l.getLanguage());
14132            SystemProperties.set("user.region", l.getCountry());
14133        }
14134
14135        if(isPersist) {
14136            SystemProperties.set("persist.sys.language", l.getLanguage());
14137            SystemProperties.set("persist.sys.country", l.getCountry());
14138            SystemProperties.set("persist.sys.localevar", l.getVariant());
14139        }
14140    }
14141
14142    @Override
14143    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14144        ActivityRecord srec = ActivityRecord.forToken(token);
14145        return srec != null && srec.task.affinity != null &&
14146                srec.task.affinity.equals(destAffinity);
14147    }
14148
14149    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14150            Intent resultData) {
14151
14152        synchronized (this) {
14153            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14154            if (stack != null) {
14155                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14156            }
14157            return false;
14158        }
14159    }
14160
14161    public int getLaunchedFromUid(IBinder activityToken) {
14162        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14163        if (srec == null) {
14164            return -1;
14165        }
14166        return srec.launchedFromUid;
14167    }
14168
14169    public String getLaunchedFromPackage(IBinder activityToken) {
14170        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14171        if (srec == null) {
14172            return null;
14173        }
14174        return srec.launchedFromPackage;
14175    }
14176
14177    // =========================================================
14178    // LIFETIME MANAGEMENT
14179    // =========================================================
14180
14181    // Returns which broadcast queue the app is the current [or imminent] receiver
14182    // on, or 'null' if the app is not an active broadcast recipient.
14183    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14184        BroadcastRecord r = app.curReceiver;
14185        if (r != null) {
14186            return r.queue;
14187        }
14188
14189        // It's not the current receiver, but it might be starting up to become one
14190        synchronized (this) {
14191            for (BroadcastQueue queue : mBroadcastQueues) {
14192                r = queue.mPendingBroadcast;
14193                if (r != null && r.curApp == app) {
14194                    // found it; report which queue it's in
14195                    return queue;
14196                }
14197            }
14198        }
14199
14200        return null;
14201    }
14202
14203    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14204            boolean doingAll, long now) {
14205        if (mAdjSeq == app.adjSeq) {
14206            // This adjustment has already been computed.
14207            return app.curRawAdj;
14208        }
14209
14210        if (app.thread == null) {
14211            app.adjSeq = mAdjSeq;
14212            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14213            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14214            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14215        }
14216
14217        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14218        app.adjSource = null;
14219        app.adjTarget = null;
14220        app.empty = false;
14221        app.cached = false;
14222
14223        final int activitiesSize = app.activities.size();
14224
14225        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14226            // The max adjustment doesn't allow this app to be anything
14227            // below foreground, so it is not worth doing work for it.
14228            app.adjType = "fixed";
14229            app.adjSeq = mAdjSeq;
14230            app.curRawAdj = app.maxAdj;
14231            app.foregroundActivities = false;
14232            app.keeping = true;
14233            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14234            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14235            // System process can do UI, and when they do we want to have
14236            // them trim their memory after the user leaves the UI.  To
14237            // facilitate this, here we need to determine whether or not it
14238            // is currently showing UI.
14239            app.systemNoUi = true;
14240            if (app == TOP_APP) {
14241                app.systemNoUi = false;
14242            } else if (activitiesSize > 0) {
14243                for (int j = 0; j < activitiesSize; j++) {
14244                    final ActivityRecord r = app.activities.get(j);
14245                    if (r.visible) {
14246                        app.systemNoUi = false;
14247                    }
14248                }
14249            }
14250            if (!app.systemNoUi) {
14251                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14252            }
14253            return (app.curAdj=app.maxAdj);
14254        }
14255
14256        app.keeping = false;
14257        app.systemNoUi = false;
14258
14259        // Determine the importance of the process, starting with most
14260        // important to least, and assign an appropriate OOM adjustment.
14261        int adj;
14262        int schedGroup;
14263        int procState;
14264        boolean foregroundActivities = false;
14265        boolean interesting = false;
14266        BroadcastQueue queue;
14267        if (app == TOP_APP) {
14268            // The last app on the list is the foreground app.
14269            adj = ProcessList.FOREGROUND_APP_ADJ;
14270            schedGroup = Process.THREAD_GROUP_DEFAULT;
14271            app.adjType = "top-activity";
14272            foregroundActivities = true;
14273            interesting = true;
14274            procState = ActivityManager.PROCESS_STATE_TOP;
14275        } else if (app.instrumentationClass != null) {
14276            // Don't want to kill running instrumentation.
14277            adj = ProcessList.FOREGROUND_APP_ADJ;
14278            schedGroup = Process.THREAD_GROUP_DEFAULT;
14279            app.adjType = "instrumentation";
14280            interesting = true;
14281            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14282        } else if ((queue = isReceivingBroadcast(app)) != null) {
14283            // An app that is currently receiving a broadcast also
14284            // counts as being in the foreground for OOM killer purposes.
14285            // It's placed in a sched group based on the nature of the
14286            // broadcast as reflected by which queue it's active in.
14287            adj = ProcessList.FOREGROUND_APP_ADJ;
14288            schedGroup = (queue == mFgBroadcastQueue)
14289                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14290            app.adjType = "broadcast";
14291            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14292        } else if (app.executingServices.size() > 0) {
14293            // An app that is currently executing a service callback also
14294            // counts as being in the foreground.
14295            adj = ProcessList.FOREGROUND_APP_ADJ;
14296            schedGroup = app.execServicesFg ?
14297                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14298            app.adjType = "exec-service";
14299            procState = ActivityManager.PROCESS_STATE_SERVICE;
14300            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14301        } else {
14302            // As far as we know the process is empty.  We may change our mind later.
14303            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14304            // At this point we don't actually know the adjustment.  Use the cached adj
14305            // value that the caller wants us to.
14306            adj = cachedAdj;
14307            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14308            app.cached = true;
14309            app.empty = true;
14310            app.adjType = "cch-empty";
14311        }
14312
14313        // Examine all activities if not already foreground.
14314        if (!foregroundActivities && activitiesSize > 0) {
14315            for (int j = 0; j < activitiesSize; j++) {
14316                final ActivityRecord r = app.activities.get(j);
14317                if (r.app != app) {
14318                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14319                            + app + "?!?");
14320                    continue;
14321                }
14322                if (r.visible) {
14323                    // App has a visible activity; only upgrade adjustment.
14324                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14325                        adj = ProcessList.VISIBLE_APP_ADJ;
14326                        app.adjType = "visible";
14327                    }
14328                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14329                        procState = ActivityManager.PROCESS_STATE_TOP;
14330                    }
14331                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14332                    app.cached = false;
14333                    app.empty = false;
14334                    foregroundActivities = true;
14335                    break;
14336                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14337                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14338                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14339                        app.adjType = "pausing";
14340                    }
14341                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14342                        procState = ActivityManager.PROCESS_STATE_TOP;
14343                    }
14344                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14345                    app.cached = false;
14346                    app.empty = false;
14347                    foregroundActivities = true;
14348                } else if (r.state == ActivityState.STOPPING) {
14349                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14350                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14351                        app.adjType = "stopping";
14352                    }
14353                    // For the process state, we will at this point consider the
14354                    // process to be cached.  It will be cached either as an activity
14355                    // or empty depending on whether the activity is finishing.  We do
14356                    // this so that we can treat the process as cached for purposes of
14357                    // memory trimming (determing current memory level, trim command to
14358                    // send to process) since there can be an arbitrary number of stopping
14359                    // processes and they should soon all go into the cached state.
14360                    if (!r.finishing) {
14361                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14362                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14363                        }
14364                    }
14365                    app.cached = false;
14366                    app.empty = false;
14367                    foregroundActivities = true;
14368                } else {
14369                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14370                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14371                        app.adjType = "cch-act";
14372                    }
14373                }
14374            }
14375        }
14376
14377        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14378            if (app.foregroundServices) {
14379                // The user is aware of this app, so make it visible.
14380                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14381                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14382                app.cached = false;
14383                app.adjType = "fg-service";
14384                schedGroup = Process.THREAD_GROUP_DEFAULT;
14385            } else if (app.forcingToForeground != null) {
14386                // The user is aware of this app, so make it visible.
14387                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14388                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14389                app.cached = false;
14390                app.adjType = "force-fg";
14391                app.adjSource = app.forcingToForeground;
14392                schedGroup = Process.THREAD_GROUP_DEFAULT;
14393            }
14394        }
14395
14396        if (app.foregroundServices) {
14397            interesting = true;
14398        }
14399
14400        if (app == mHeavyWeightProcess) {
14401            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14402                // We don't want to kill the current heavy-weight process.
14403                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14404                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14405                app.cached = false;
14406                app.adjType = "heavy";
14407            }
14408            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14409                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14410            }
14411        }
14412
14413        if (app == mHomeProcess) {
14414            if (adj > ProcessList.HOME_APP_ADJ) {
14415                // This process is hosting what we currently consider to be the
14416                // home app, so we don't want to let it go into the background.
14417                adj = ProcessList.HOME_APP_ADJ;
14418                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14419                app.cached = false;
14420                app.adjType = "home";
14421            }
14422            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14423                procState = ActivityManager.PROCESS_STATE_HOME;
14424            }
14425        }
14426
14427        if (app == mPreviousProcess && app.activities.size() > 0) {
14428            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14429                // This was the previous process that showed UI to the user.
14430                // We want to try to keep it around more aggressively, to give
14431                // a good experience around switching between two apps.
14432                adj = ProcessList.PREVIOUS_APP_ADJ;
14433                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14434                app.cached = false;
14435                app.adjType = "previous";
14436            }
14437            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14438                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14439            }
14440        }
14441
14442        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14443                + " reason=" + app.adjType);
14444
14445        // By default, we use the computed adjustment.  It may be changed if
14446        // there are applications dependent on our services or providers, but
14447        // this gives us a baseline and makes sure we don't get into an
14448        // infinite recursion.
14449        app.adjSeq = mAdjSeq;
14450        app.curRawAdj = adj;
14451        app.hasStartedServices = false;
14452
14453        if (mBackupTarget != null && app == mBackupTarget.app) {
14454            // If possible we want to avoid killing apps while they're being backed up
14455            if (adj > ProcessList.BACKUP_APP_ADJ) {
14456                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14457                adj = ProcessList.BACKUP_APP_ADJ;
14458                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14459                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14460                }
14461                app.adjType = "backup";
14462                app.cached = false;
14463            }
14464            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14465                procState = ActivityManager.PROCESS_STATE_BACKUP;
14466            }
14467        }
14468
14469        boolean mayBeTop = false;
14470
14471        for (int is = app.services.size()-1;
14472                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14473                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14474                        || procState > ActivityManager.PROCESS_STATE_TOP);
14475                is--) {
14476            ServiceRecord s = app.services.valueAt(is);
14477            if (s.startRequested) {
14478                app.hasStartedServices = true;
14479                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14480                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14481                }
14482                if (app.hasShownUi && app != mHomeProcess) {
14483                    // If this process has shown some UI, let it immediately
14484                    // go to the LRU list because it may be pretty heavy with
14485                    // UI stuff.  We'll tag it with a label just to help
14486                    // debug and understand what is going on.
14487                    if (adj > ProcessList.SERVICE_ADJ) {
14488                        app.adjType = "cch-started-ui-services";
14489                    }
14490                } else {
14491                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14492                        // This service has seen some activity within
14493                        // recent memory, so we will keep its process ahead
14494                        // of the background processes.
14495                        if (adj > ProcessList.SERVICE_ADJ) {
14496                            adj = ProcessList.SERVICE_ADJ;
14497                            app.adjType = "started-services";
14498                            app.cached = false;
14499                        }
14500                    }
14501                    // If we have let the service slide into the background
14502                    // state, still have some text describing what it is doing
14503                    // even though the service no longer has an impact.
14504                    if (adj > ProcessList.SERVICE_ADJ) {
14505                        app.adjType = "cch-started-services";
14506                    }
14507                }
14508                // Don't kill this process because it is doing work; it
14509                // has said it is doing work.
14510                app.keeping = true;
14511            }
14512            for (int conni = s.connections.size()-1;
14513                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14514                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14515                            || procState > ActivityManager.PROCESS_STATE_TOP);
14516                    conni--) {
14517                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14518                for (int i = 0;
14519                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14520                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14521                                || procState > ActivityManager.PROCESS_STATE_TOP);
14522                        i++) {
14523                    // XXX should compute this based on the max of
14524                    // all connected clients.
14525                    ConnectionRecord cr = clist.get(i);
14526                    if (cr.binding.client == app) {
14527                        // Binding to ourself is not interesting.
14528                        continue;
14529                    }
14530                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14531                        ProcessRecord client = cr.binding.client;
14532                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14533                                TOP_APP, doingAll, now);
14534                        int clientProcState = client.curProcState;
14535                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14536                            // If the other app is cached for any reason, for purposes here
14537                            // we are going to consider it empty.  The specific cached state
14538                            // doesn't propagate except under certain conditions.
14539                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14540                        }
14541                        String adjType = null;
14542                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14543                            // Not doing bind OOM management, so treat
14544                            // this guy more like a started service.
14545                            if (app.hasShownUi && app != mHomeProcess) {
14546                                // If this process has shown some UI, let it immediately
14547                                // go to the LRU list because it may be pretty heavy with
14548                                // UI stuff.  We'll tag it with a label just to help
14549                                // debug and understand what is going on.
14550                                if (adj > clientAdj) {
14551                                    adjType = "cch-bound-ui-services";
14552                                }
14553                                app.cached = false;
14554                                clientAdj = adj;
14555                                clientProcState = procState;
14556                            } else {
14557                                if (now >= (s.lastActivity
14558                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14559                                    // This service has not seen activity within
14560                                    // recent memory, so allow it to drop to the
14561                                    // LRU list if there is no other reason to keep
14562                                    // it around.  We'll also tag it with a label just
14563                                    // to help debug and undertand what is going on.
14564                                    if (adj > clientAdj) {
14565                                        adjType = "cch-bound-services";
14566                                    }
14567                                    clientAdj = adj;
14568                                }
14569                            }
14570                        }
14571                        if (adj > clientAdj) {
14572                            // If this process has recently shown UI, and
14573                            // the process that is binding to it is less
14574                            // important than being visible, then we don't
14575                            // care about the binding as much as we care
14576                            // about letting this process get into the LRU
14577                            // list to be killed and restarted if needed for
14578                            // memory.
14579                            if (app.hasShownUi && app != mHomeProcess
14580                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14581                                adjType = "cch-bound-ui-services";
14582                            } else {
14583                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14584                                        |Context.BIND_IMPORTANT)) != 0) {
14585                                    adj = clientAdj;
14586                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14587                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14588                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14589                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14590                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14591                                    adj = clientAdj;
14592                                } else {
14593                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14594                                        adj = ProcessList.VISIBLE_APP_ADJ;
14595                                    }
14596                                }
14597                                if (!client.cached) {
14598                                    app.cached = false;
14599                                }
14600                                if (client.keeping) {
14601                                    app.keeping = true;
14602                                }
14603                                adjType = "service";
14604                            }
14605                        }
14606                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14607                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14608                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14609                            }
14610                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14611                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14612                                    // Special handling of clients who are in the top state.
14613                                    // We *may* want to consider this process to be in the
14614                                    // top state as well, but only if there is not another
14615                                    // reason for it to be running.  Being on the top is a
14616                                    // special state, meaning you are specifically running
14617                                    // for the current top app.  If the process is already
14618                                    // running in the background for some other reason, it
14619                                    // is more important to continue considering it to be
14620                                    // in the background state.
14621                                    mayBeTop = true;
14622                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14623                                } else {
14624                                    // Special handling for above-top states (persistent
14625                                    // processes).  These should not bring the current process
14626                                    // into the top state, since they are not on top.  Instead
14627                                    // give them the best state after that.
14628                                    clientProcState =
14629                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14630                                }
14631                            }
14632                        } else {
14633                            if (clientProcState <
14634                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14635                                clientProcState =
14636                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14637                            }
14638                        }
14639                        if (procState > clientProcState) {
14640                            procState = clientProcState;
14641                        }
14642                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14643                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14644                            app.pendingUiClean = true;
14645                        }
14646                        if (adjType != null) {
14647                            app.adjType = adjType;
14648                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14649                                    .REASON_SERVICE_IN_USE;
14650                            app.adjSource = cr.binding.client;
14651                            app.adjSourceOom = clientAdj;
14652                            app.adjTarget = s.name;
14653                        }
14654                    }
14655                    final ActivityRecord a = cr.activity;
14656                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14657                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14658                                (a.visible || a.state == ActivityState.RESUMED
14659                                 || a.state == ActivityState.PAUSING)) {
14660                            adj = ProcessList.FOREGROUND_APP_ADJ;
14661                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14662                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14663                            }
14664                            app.cached = false;
14665                            app.adjType = "service";
14666                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14667                                    .REASON_SERVICE_IN_USE;
14668                            app.adjSource = a;
14669                            app.adjSourceOom = adj;
14670                            app.adjTarget = s.name;
14671                        }
14672                    }
14673                }
14674            }
14675        }
14676
14677        for (int provi = app.pubProviders.size()-1;
14678                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14679                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14680                        || procState > ActivityManager.PROCESS_STATE_TOP);
14681                provi--) {
14682            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14683            for (int i = cpr.connections.size()-1;
14684                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14685                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14686                            || procState > ActivityManager.PROCESS_STATE_TOP);
14687                    i--) {
14688                ContentProviderConnection conn = cpr.connections.get(i);
14689                ProcessRecord client = conn.client;
14690                if (client == app) {
14691                    // Being our own client is not interesting.
14692                    continue;
14693                }
14694                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14695                int clientProcState = client.curProcState;
14696                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14697                    // If the other app is cached for any reason, for purposes here
14698                    // we are going to consider it empty.
14699                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14700                }
14701                if (adj > clientAdj) {
14702                    if (app.hasShownUi && app != mHomeProcess
14703                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14704                        app.adjType = "cch-ui-provider";
14705                    } else {
14706                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14707                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14708                        app.adjType = "provider";
14709                    }
14710                    app.cached &= client.cached;
14711                    app.keeping |= client.keeping;
14712                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14713                            .REASON_PROVIDER_IN_USE;
14714                    app.adjSource = client;
14715                    app.adjSourceOom = clientAdj;
14716                    app.adjTarget = cpr.name;
14717                }
14718                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14719                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14720                        // Special handling of clients who are in the top state.
14721                        // We *may* want to consider this process to be in the
14722                        // top state as well, but only if there is not another
14723                        // reason for it to be running.  Being on the top is a
14724                        // special state, meaning you are specifically running
14725                        // for the current top app.  If the process is already
14726                        // running in the background for some other reason, it
14727                        // is more important to continue considering it to be
14728                        // in the background state.
14729                        mayBeTop = true;
14730                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14731                    } else {
14732                        // Special handling for above-top states (persistent
14733                        // processes).  These should not bring the current process
14734                        // into the top state, since they are not on top.  Instead
14735                        // give them the best state after that.
14736                        clientProcState =
14737                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14738                    }
14739                }
14740                if (procState > clientProcState) {
14741                    procState = clientProcState;
14742                }
14743                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14744                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14745                }
14746            }
14747            // If the provider has external (non-framework) process
14748            // dependencies, ensure that its adjustment is at least
14749            // FOREGROUND_APP_ADJ.
14750            if (cpr.hasExternalProcessHandles()) {
14751                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14752                    adj = ProcessList.FOREGROUND_APP_ADJ;
14753                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14754                    app.cached = false;
14755                    app.keeping = true;
14756                    app.adjType = "provider";
14757                    app.adjTarget = cpr.name;
14758                }
14759                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14760                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14761                }
14762            }
14763        }
14764
14765        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14766            // A client of one of our services or providers is in the top state.  We
14767            // *may* want to be in the top state, but not if we are already running in
14768            // the background for some other reason.  For the decision here, we are going
14769            // to pick out a few specific states that we want to remain in when a client
14770            // is top (states that tend to be longer-term) and otherwise allow it to go
14771            // to the top state.
14772            switch (procState) {
14773                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14774                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14775                case ActivityManager.PROCESS_STATE_SERVICE:
14776                    // These all are longer-term states, so pull them up to the top
14777                    // of the background states, but not all the way to the top state.
14778                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14779                    break;
14780                default:
14781                    // Otherwise, top is a better choice, so take it.
14782                    procState = ActivityManager.PROCESS_STATE_TOP;
14783                    break;
14784            }
14785        }
14786
14787        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14788            // This is a cached process, but with client activities.  Mark it so.
14789            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14790            app.adjType = "cch-client-act";
14791        }
14792
14793        if (adj == ProcessList.SERVICE_ADJ) {
14794            if (doingAll) {
14795                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14796                mNewNumServiceProcs++;
14797                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14798                if (!app.serviceb) {
14799                    // This service isn't far enough down on the LRU list to
14800                    // normally be a B service, but if we are low on RAM and it
14801                    // is large we want to force it down since we would prefer to
14802                    // keep launcher over it.
14803                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14804                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14805                        app.serviceHighRam = true;
14806                        app.serviceb = true;
14807                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14808                    } else {
14809                        mNewNumAServiceProcs++;
14810                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14811                    }
14812                } else {
14813                    app.serviceHighRam = false;
14814                }
14815            }
14816            if (app.serviceb) {
14817                adj = ProcessList.SERVICE_B_ADJ;
14818            }
14819        }
14820
14821        app.curRawAdj = adj;
14822
14823        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14824        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14825        if (adj > app.maxAdj) {
14826            adj = app.maxAdj;
14827            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14828                schedGroup = Process.THREAD_GROUP_DEFAULT;
14829            }
14830        }
14831        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14832            app.keeping = true;
14833        }
14834
14835        // Do final modification to adj.  Everything we do between here and applying
14836        // the final setAdj must be done in this function, because we will also use
14837        // it when computing the final cached adj later.  Note that we don't need to
14838        // worry about this for max adj above, since max adj will always be used to
14839        // keep it out of the cached vaues.
14840        adj = app.modifyRawOomAdj(adj);
14841
14842        app.curProcState = procState;
14843
14844        int importance = app.memImportance;
14845        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14846            app.curAdj = adj;
14847            app.curSchedGroup = schedGroup;
14848            if (!interesting) {
14849                // For this reporting, if there is not something explicitly
14850                // interesting in this process then we will push it to the
14851                // background importance.
14852                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14853            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14854                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14855            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14856                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14857            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14858                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14859            } else if (adj >= ProcessList.SERVICE_ADJ) {
14860                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14861            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14862                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14863            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14864                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14865            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14866                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14867            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14868                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14869            } else {
14870                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14871            }
14872        }
14873
14874        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14875        if (foregroundActivities != app.foregroundActivities) {
14876            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14877        }
14878        if (changes != 0) {
14879            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14880            app.memImportance = importance;
14881            app.foregroundActivities = foregroundActivities;
14882            int i = mPendingProcessChanges.size()-1;
14883            ProcessChangeItem item = null;
14884            while (i >= 0) {
14885                item = mPendingProcessChanges.get(i);
14886                if (item.pid == app.pid) {
14887                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14888                    break;
14889                }
14890                i--;
14891            }
14892            if (i < 0) {
14893                // No existing item in pending changes; need a new one.
14894                final int NA = mAvailProcessChanges.size();
14895                if (NA > 0) {
14896                    item = mAvailProcessChanges.remove(NA-1);
14897                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14898                } else {
14899                    item = new ProcessChangeItem();
14900                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14901                }
14902                item.changes = 0;
14903                item.pid = app.pid;
14904                item.uid = app.info.uid;
14905                if (mPendingProcessChanges.size() == 0) {
14906                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14907                            "*** Enqueueing dispatch processes changed!");
14908                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14909                }
14910                mPendingProcessChanges.add(item);
14911            }
14912            item.changes |= changes;
14913            item.importance = importance;
14914            item.foregroundActivities = foregroundActivities;
14915            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14916                    + Integer.toHexString(System.identityHashCode(item))
14917                    + " " + app.toShortString() + ": changes=" + item.changes
14918                    + " importance=" + item.importance
14919                    + " foreground=" + item.foregroundActivities
14920                    + " type=" + app.adjType + " source=" + app.adjSource
14921                    + " target=" + app.adjTarget);
14922        }
14923
14924        return app.curRawAdj;
14925    }
14926
14927    /**
14928     * Schedule PSS collection of a process.
14929     */
14930    void requestPssLocked(ProcessRecord proc, int procState) {
14931        if (mPendingPssProcesses.contains(proc)) {
14932            return;
14933        }
14934        if (mPendingPssProcesses.size() == 0) {
14935            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14936        }
14937        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14938        proc.pssProcState = procState;
14939        mPendingPssProcesses.add(proc);
14940    }
14941
14942    /**
14943     * Schedule PSS collection of all processes.
14944     */
14945    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14946        if (!always) {
14947            if (now < (mLastFullPssTime +
14948                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14949                return;
14950            }
14951        }
14952        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14953        mLastFullPssTime = now;
14954        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14955        mPendingPssProcesses.clear();
14956        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14957            ProcessRecord app = mLruProcesses.get(i);
14958            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14959                app.pssProcState = app.setProcState;
14960                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14961                        mSleeping, now);
14962                mPendingPssProcesses.add(app);
14963            }
14964        }
14965        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14966    }
14967
14968    /**
14969     * Ask a given process to GC right now.
14970     */
14971    final void performAppGcLocked(ProcessRecord app) {
14972        try {
14973            app.lastRequestedGc = SystemClock.uptimeMillis();
14974            if (app.thread != null) {
14975                if (app.reportLowMemory) {
14976                    app.reportLowMemory = false;
14977                    app.thread.scheduleLowMemory();
14978                } else {
14979                    app.thread.processInBackground();
14980                }
14981            }
14982        } catch (Exception e) {
14983            // whatever.
14984        }
14985    }
14986
14987    /**
14988     * Returns true if things are idle enough to perform GCs.
14989     */
14990    private final boolean canGcNowLocked() {
14991        boolean processingBroadcasts = false;
14992        for (BroadcastQueue q : mBroadcastQueues) {
14993            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14994                processingBroadcasts = true;
14995            }
14996        }
14997        return !processingBroadcasts
14998                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14999    }
15000
15001    /**
15002     * Perform GCs on all processes that are waiting for it, but only
15003     * if things are idle.
15004     */
15005    final void performAppGcsLocked() {
15006        final int N = mProcessesToGc.size();
15007        if (N <= 0) {
15008            return;
15009        }
15010        if (canGcNowLocked()) {
15011            while (mProcessesToGc.size() > 0) {
15012                ProcessRecord proc = mProcessesToGc.remove(0);
15013                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15014                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15015                            <= SystemClock.uptimeMillis()) {
15016                        // To avoid spamming the system, we will GC processes one
15017                        // at a time, waiting a few seconds between each.
15018                        performAppGcLocked(proc);
15019                        scheduleAppGcsLocked();
15020                        return;
15021                    } else {
15022                        // It hasn't been long enough since we last GCed this
15023                        // process...  put it in the list to wait for its time.
15024                        addProcessToGcListLocked(proc);
15025                        break;
15026                    }
15027                }
15028            }
15029
15030            scheduleAppGcsLocked();
15031        }
15032    }
15033
15034    /**
15035     * If all looks good, perform GCs on all processes waiting for them.
15036     */
15037    final void performAppGcsIfAppropriateLocked() {
15038        if (canGcNowLocked()) {
15039            performAppGcsLocked();
15040            return;
15041        }
15042        // Still not idle, wait some more.
15043        scheduleAppGcsLocked();
15044    }
15045
15046    /**
15047     * Schedule the execution of all pending app GCs.
15048     */
15049    final void scheduleAppGcsLocked() {
15050        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15051
15052        if (mProcessesToGc.size() > 0) {
15053            // Schedule a GC for the time to the next process.
15054            ProcessRecord proc = mProcessesToGc.get(0);
15055            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15056
15057            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15058            long now = SystemClock.uptimeMillis();
15059            if (when < (now+GC_TIMEOUT)) {
15060                when = now + GC_TIMEOUT;
15061            }
15062            mHandler.sendMessageAtTime(msg, when);
15063        }
15064    }
15065
15066    /**
15067     * Add a process to the array of processes waiting to be GCed.  Keeps the
15068     * list in sorted order by the last GC time.  The process can't already be
15069     * on the list.
15070     */
15071    final void addProcessToGcListLocked(ProcessRecord proc) {
15072        boolean added = false;
15073        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15074            if (mProcessesToGc.get(i).lastRequestedGc <
15075                    proc.lastRequestedGc) {
15076                added = true;
15077                mProcessesToGc.add(i+1, proc);
15078                break;
15079            }
15080        }
15081        if (!added) {
15082            mProcessesToGc.add(0, proc);
15083        }
15084    }
15085
15086    /**
15087     * Set up to ask a process to GC itself.  This will either do it
15088     * immediately, or put it on the list of processes to gc the next
15089     * time things are idle.
15090     */
15091    final void scheduleAppGcLocked(ProcessRecord app) {
15092        long now = SystemClock.uptimeMillis();
15093        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15094            return;
15095        }
15096        if (!mProcessesToGc.contains(app)) {
15097            addProcessToGcListLocked(app);
15098            scheduleAppGcsLocked();
15099        }
15100    }
15101
15102    final void checkExcessivePowerUsageLocked(boolean doKills) {
15103        updateCpuStatsNow();
15104
15105        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15106        boolean doWakeKills = doKills;
15107        boolean doCpuKills = doKills;
15108        if (mLastPowerCheckRealtime == 0) {
15109            doWakeKills = false;
15110        }
15111        if (mLastPowerCheckUptime == 0) {
15112            doCpuKills = false;
15113        }
15114        if (stats.isScreenOn()) {
15115            doWakeKills = false;
15116        }
15117        final long curRealtime = SystemClock.elapsedRealtime();
15118        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15119        final long curUptime = SystemClock.uptimeMillis();
15120        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15121        mLastPowerCheckRealtime = curRealtime;
15122        mLastPowerCheckUptime = curUptime;
15123        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15124            doWakeKills = false;
15125        }
15126        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15127            doCpuKills = false;
15128        }
15129        int i = mLruProcesses.size();
15130        while (i > 0) {
15131            i--;
15132            ProcessRecord app = mLruProcesses.get(i);
15133            if (!app.keeping) {
15134                long wtime;
15135                synchronized (stats) {
15136                    wtime = stats.getProcessWakeTime(app.info.uid,
15137                            app.pid, curRealtime);
15138                }
15139                long wtimeUsed = wtime - app.lastWakeTime;
15140                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15141                if (DEBUG_POWER) {
15142                    StringBuilder sb = new StringBuilder(128);
15143                    sb.append("Wake for ");
15144                    app.toShortString(sb);
15145                    sb.append(": over ");
15146                    TimeUtils.formatDuration(realtimeSince, sb);
15147                    sb.append(" used ");
15148                    TimeUtils.formatDuration(wtimeUsed, sb);
15149                    sb.append(" (");
15150                    sb.append((wtimeUsed*100)/realtimeSince);
15151                    sb.append("%)");
15152                    Slog.i(TAG, sb.toString());
15153                    sb.setLength(0);
15154                    sb.append("CPU for ");
15155                    app.toShortString(sb);
15156                    sb.append(": over ");
15157                    TimeUtils.formatDuration(uptimeSince, sb);
15158                    sb.append(" used ");
15159                    TimeUtils.formatDuration(cputimeUsed, sb);
15160                    sb.append(" (");
15161                    sb.append((cputimeUsed*100)/uptimeSince);
15162                    sb.append("%)");
15163                    Slog.i(TAG, sb.toString());
15164                }
15165                // If a process has held a wake lock for more
15166                // than 50% of the time during this period,
15167                // that sounds bad.  Kill!
15168                if (doWakeKills && realtimeSince > 0
15169                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15170                    synchronized (stats) {
15171                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15172                                realtimeSince, wtimeUsed);
15173                    }
15174                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15175                            + " during " + realtimeSince);
15176                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15177                } else if (doCpuKills && uptimeSince > 0
15178                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15179                    synchronized (stats) {
15180                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15181                                uptimeSince, cputimeUsed);
15182                    }
15183                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15184                            + " during " + uptimeSince);
15185                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15186                } else {
15187                    app.lastWakeTime = wtime;
15188                    app.lastCpuTime = app.curCpuTime;
15189                }
15190            }
15191        }
15192    }
15193
15194    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15195            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15196        boolean success = true;
15197
15198        if (app.curRawAdj != app.setRawAdj) {
15199            if (wasKeeping && !app.keeping) {
15200                // This app is no longer something we want to keep.  Note
15201                // its current wake lock time to later know to kill it if
15202                // it is not behaving well.
15203                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15204                synchronized (stats) {
15205                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15206                            app.pid, SystemClock.elapsedRealtime());
15207                }
15208                app.lastCpuTime = app.curCpuTime;
15209            }
15210
15211            app.setRawAdj = app.curRawAdj;
15212        }
15213
15214        if (app.curAdj != app.setAdj) {
15215            ProcessList.setOomAdj(app.pid, app.curAdj);
15216            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15217                TAG, "Set " + app.pid + " " + app.processName +
15218                " adj " + app.curAdj + ": " + app.adjType);
15219            app.setAdj = app.curAdj;
15220        }
15221
15222        if (app.setSchedGroup != app.curSchedGroup) {
15223            app.setSchedGroup = app.curSchedGroup;
15224            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15225                    "Setting process group of " + app.processName
15226                    + " to " + app.curSchedGroup);
15227            if (app.waitingToKill != null &&
15228                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15229                killUnneededProcessLocked(app, app.waitingToKill);
15230                success = false;
15231            } else {
15232                if (true) {
15233                    long oldId = Binder.clearCallingIdentity();
15234                    try {
15235                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15236                    } catch (Exception e) {
15237                        Slog.w(TAG, "Failed setting process group of " + app.pid
15238                                + " to " + app.curSchedGroup);
15239                        e.printStackTrace();
15240                    } finally {
15241                        Binder.restoreCallingIdentity(oldId);
15242                    }
15243                } else {
15244                    if (app.thread != null) {
15245                        try {
15246                            app.thread.setSchedulingGroup(app.curSchedGroup);
15247                        } catch (RemoteException e) {
15248                        }
15249                    }
15250                }
15251                Process.setSwappiness(app.pid,
15252                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15253            }
15254        }
15255        if (app.repProcState != app.curProcState) {
15256            app.repProcState = app.curProcState;
15257            if (!reportingProcessState && app.thread != null) {
15258                try {
15259                    if (false) {
15260                        //RuntimeException h = new RuntimeException("here");
15261                        Slog.i(TAG, "Sending new process state " + app.repProcState
15262                                + " to " + app /*, h*/);
15263                    }
15264                    app.thread.setProcessState(app.repProcState);
15265                } catch (RemoteException e) {
15266                }
15267            }
15268        }
15269        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15270                app.setProcState)) {
15271            app.lastStateTime = now;
15272            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15273                    mSleeping, now);
15274            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15275                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15276                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15277                    + (app.nextPssTime-now) + ": " + app);
15278        } else {
15279            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15280                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15281                requestPssLocked(app, app.setProcState);
15282                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15283                        mSleeping, now);
15284            } else if (false && DEBUG_PSS) {
15285                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15286            }
15287        }
15288        if (app.setProcState != app.curProcState) {
15289            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15290                    "Proc state change of " + app.processName
15291                    + " to " + app.curProcState);
15292            app.setProcState = app.curProcState;
15293            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15294                app.notCachedSinceIdle = false;
15295            }
15296            if (!doingAll) {
15297                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15298            } else {
15299                app.procStateChanged = true;
15300            }
15301        }
15302        return success;
15303    }
15304
15305    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15306        if (proc.thread != null && proc.baseProcessTracker != null) {
15307            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15308        }
15309    }
15310
15311    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15312            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15313        if (app.thread == null) {
15314            return false;
15315        }
15316
15317        final boolean wasKeeping = app.keeping;
15318
15319        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15320
15321        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15322                reportingProcessState, now);
15323    }
15324
15325    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15326            boolean oomAdj) {
15327        if (isForeground != proc.foregroundServices) {
15328            proc.foregroundServices = isForeground;
15329            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15330                    proc.info.uid);
15331            if (isForeground) {
15332                if (curProcs == null) {
15333                    curProcs = new ArrayList<ProcessRecord>();
15334                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15335                }
15336                if (!curProcs.contains(proc)) {
15337                    curProcs.add(proc);
15338                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15339                            proc.info.packageName, proc.info.uid);
15340                }
15341            } else {
15342                if (curProcs != null) {
15343                    if (curProcs.remove(proc)) {
15344                        mBatteryStatsService.noteEvent(
15345                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15346                                proc.info.packageName, proc.info.uid);
15347                        if (curProcs.size() <= 0) {
15348                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15349                        }
15350                    }
15351                }
15352            }
15353            if (oomAdj) {
15354                updateOomAdjLocked();
15355            }
15356        }
15357    }
15358
15359    private final ActivityRecord resumedAppLocked() {
15360        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15361        String pkg;
15362        int uid;
15363        if (act != null) {
15364            pkg = act.packageName;
15365            uid = act.info.applicationInfo.uid;
15366        } else {
15367            pkg = null;
15368            uid = -1;
15369        }
15370        // Has the UID or resumed package name changed?
15371        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15372                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15373            if (mCurResumedPackage != null) {
15374                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15375                        mCurResumedPackage, mCurResumedUid);
15376            }
15377            mCurResumedPackage = pkg;
15378            mCurResumedUid = uid;
15379            if (mCurResumedPackage != null) {
15380                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15381                        mCurResumedPackage, mCurResumedUid);
15382            }
15383        }
15384        return act;
15385    }
15386
15387    final boolean updateOomAdjLocked(ProcessRecord app) {
15388        return updateOomAdjLocked(app, false);
15389    }
15390
15391    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15392        final ActivityRecord TOP_ACT = resumedAppLocked();
15393        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15394        final boolean wasCached = app.cached;
15395
15396        mAdjSeq++;
15397
15398        // This is the desired cached adjusment we want to tell it to use.
15399        // If our app is currently cached, we know it, and that is it.  Otherwise,
15400        // we don't know it yet, and it needs to now be cached we will then
15401        // need to do a complete oom adj.
15402        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15403                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15404        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15405                SystemClock.uptimeMillis());
15406        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15407            // Changed to/from cached state, so apps after it in the LRU
15408            // list may also be changed.
15409            updateOomAdjLocked();
15410        }
15411        return success;
15412    }
15413
15414    final void updateOomAdjLocked() {
15415        final ActivityRecord TOP_ACT = resumedAppLocked();
15416        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15417        final long now = SystemClock.uptimeMillis();
15418        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15419        final int N = mLruProcesses.size();
15420
15421        if (false) {
15422            RuntimeException e = new RuntimeException();
15423            e.fillInStackTrace();
15424            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15425        }
15426
15427        mAdjSeq++;
15428        mNewNumServiceProcs = 0;
15429        mNewNumAServiceProcs = 0;
15430
15431        final int emptyProcessLimit;
15432        final int cachedProcessLimit;
15433        if (mProcessLimit <= 0) {
15434            emptyProcessLimit = cachedProcessLimit = 0;
15435        } else if (mProcessLimit == 1) {
15436            emptyProcessLimit = 1;
15437            cachedProcessLimit = 0;
15438        } else {
15439            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15440            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15441        }
15442
15443        // Let's determine how many processes we have running vs.
15444        // how many slots we have for background processes; we may want
15445        // to put multiple processes in a slot of there are enough of
15446        // them.
15447        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15448                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15449        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15450        if (numEmptyProcs > cachedProcessLimit) {
15451            // If there are more empty processes than our limit on cached
15452            // processes, then use the cached process limit for the factor.
15453            // This ensures that the really old empty processes get pushed
15454            // down to the bottom, so if we are running low on memory we will
15455            // have a better chance at keeping around more cached processes
15456            // instead of a gazillion empty processes.
15457            numEmptyProcs = cachedProcessLimit;
15458        }
15459        int emptyFactor = numEmptyProcs/numSlots;
15460        if (emptyFactor < 1) emptyFactor = 1;
15461        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15462        if (cachedFactor < 1) cachedFactor = 1;
15463        int stepCached = 0;
15464        int stepEmpty = 0;
15465        int numCached = 0;
15466        int numEmpty = 0;
15467        int numTrimming = 0;
15468
15469        mNumNonCachedProcs = 0;
15470        mNumCachedHiddenProcs = 0;
15471
15472        // First update the OOM adjustment for each of the
15473        // application processes based on their current state.
15474        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15475        int nextCachedAdj = curCachedAdj+1;
15476        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15477        int nextEmptyAdj = curEmptyAdj+2;
15478        for (int i=N-1; i>=0; i--) {
15479            ProcessRecord app = mLruProcesses.get(i);
15480            if (!app.killedByAm && app.thread != null) {
15481                app.procStateChanged = false;
15482                final boolean wasKeeping = app.keeping;
15483                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15484
15485                // If we haven't yet assigned the final cached adj
15486                // to the process, do that now.
15487                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15488                    switch (app.curProcState) {
15489                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15490                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15491                            // This process is a cached process holding activities...
15492                            // assign it the next cached value for that type, and then
15493                            // step that cached level.
15494                            app.curRawAdj = curCachedAdj;
15495                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15496                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15497                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15498                                    + ")");
15499                            if (curCachedAdj != nextCachedAdj) {
15500                                stepCached++;
15501                                if (stepCached >= cachedFactor) {
15502                                    stepCached = 0;
15503                                    curCachedAdj = nextCachedAdj;
15504                                    nextCachedAdj += 2;
15505                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15506                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15507                                    }
15508                                }
15509                            }
15510                            break;
15511                        default:
15512                            // For everything else, assign next empty cached process
15513                            // level and bump that up.  Note that this means that
15514                            // long-running services that have dropped down to the
15515                            // cached level will be treated as empty (since their process
15516                            // state is still as a service), which is what we want.
15517                            app.curRawAdj = curEmptyAdj;
15518                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15519                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15520                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15521                                    + ")");
15522                            if (curEmptyAdj != nextEmptyAdj) {
15523                                stepEmpty++;
15524                                if (stepEmpty >= emptyFactor) {
15525                                    stepEmpty = 0;
15526                                    curEmptyAdj = nextEmptyAdj;
15527                                    nextEmptyAdj += 2;
15528                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15529                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15530                                    }
15531                                }
15532                            }
15533                            break;
15534                    }
15535                }
15536
15537                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15538
15539                // Count the number of process types.
15540                switch (app.curProcState) {
15541                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15542                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15543                        mNumCachedHiddenProcs++;
15544                        numCached++;
15545                        if (numCached > cachedProcessLimit) {
15546                            killUnneededProcessLocked(app, "cached #" + numCached);
15547                        }
15548                        break;
15549                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15550                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15551                                && app.lastActivityTime < oldTime) {
15552                            killUnneededProcessLocked(app, "empty for "
15553                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15554                                    / 1000) + "s");
15555                        } else {
15556                            numEmpty++;
15557                            if (numEmpty > emptyProcessLimit) {
15558                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15559                            }
15560                        }
15561                        break;
15562                    default:
15563                        mNumNonCachedProcs++;
15564                        break;
15565                }
15566
15567                if (app.isolated && app.services.size() <= 0) {
15568                    // If this is an isolated process, and there are no
15569                    // services running in it, then the process is no longer
15570                    // needed.  We agressively kill these because we can by
15571                    // definition not re-use the same process again, and it is
15572                    // good to avoid having whatever code was running in them
15573                    // left sitting around after no longer needed.
15574                    killUnneededProcessLocked(app, "isolated not needed");
15575                }
15576
15577                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15578                        && !app.killedByAm) {
15579                    numTrimming++;
15580                }
15581            }
15582        }
15583
15584        mNumServiceProcs = mNewNumServiceProcs;
15585
15586        // Now determine the memory trimming level of background processes.
15587        // Unfortunately we need to start at the back of the list to do this
15588        // properly.  We only do this if the number of background apps we
15589        // are managing to keep around is less than half the maximum we desire;
15590        // if we are keeping a good number around, we'll let them use whatever
15591        // memory they want.
15592        final int numCachedAndEmpty = numCached + numEmpty;
15593        int memFactor;
15594        if (numCached <= ProcessList.TRIM_CACHED_APPS
15595                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15596            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15597                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15598            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15599                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15600            } else {
15601                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15602            }
15603        } else {
15604            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15605        }
15606        // We always allow the memory level to go up (better).  We only allow it to go
15607        // down if we are in a state where that is allowed, *and* the total number of processes
15608        // has gone down since last time.
15609        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15610                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15611                + " last=" + mLastNumProcesses);
15612        if (memFactor > mLastMemoryLevel) {
15613            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15614                memFactor = mLastMemoryLevel;
15615                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15616            }
15617        }
15618        mLastMemoryLevel = memFactor;
15619        mLastNumProcesses = mLruProcesses.size();
15620        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15621        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15622        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15623            if (mLowRamStartTime == 0) {
15624                mLowRamStartTime = now;
15625            }
15626            int step = 0;
15627            int fgTrimLevel;
15628            switch (memFactor) {
15629                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15630                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15631                    break;
15632                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15633                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15634                    break;
15635                default:
15636                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15637                    break;
15638            }
15639            int factor = numTrimming/3;
15640            int minFactor = 2;
15641            if (mHomeProcess != null) minFactor++;
15642            if (mPreviousProcess != null) minFactor++;
15643            if (factor < minFactor) factor = minFactor;
15644            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15645            for (int i=N-1; i>=0; i--) {
15646                ProcessRecord app = mLruProcesses.get(i);
15647                if (allChanged || app.procStateChanged) {
15648                    setProcessTrackerState(app, trackerMemFactor, now);
15649                    app.procStateChanged = false;
15650                }
15651                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15652                        && !app.killedByAm) {
15653                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15654                        try {
15655                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15656                                    "Trimming memory of " + app.processName
15657                                    + " to " + curLevel);
15658                            app.thread.scheduleTrimMemory(curLevel);
15659                        } catch (RemoteException e) {
15660                        }
15661                        if (false) {
15662                            // For now we won't do this; our memory trimming seems
15663                            // to be good enough at this point that destroying
15664                            // activities causes more harm than good.
15665                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15666                                    && app != mHomeProcess && app != mPreviousProcess) {
15667                                // Need to do this on its own message because the stack may not
15668                                // be in a consistent state at this point.
15669                                // For these apps we will also finish their activities
15670                                // to help them free memory.
15671                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15672                            }
15673                        }
15674                    }
15675                    app.trimMemoryLevel = curLevel;
15676                    step++;
15677                    if (step >= factor) {
15678                        step = 0;
15679                        switch (curLevel) {
15680                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15681                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15682                                break;
15683                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15684                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15685                                break;
15686                        }
15687                    }
15688                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15689                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15690                            && app.thread != null) {
15691                        try {
15692                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15693                                    "Trimming memory of heavy-weight " + app.processName
15694                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15695                            app.thread.scheduleTrimMemory(
15696                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15697                        } catch (RemoteException e) {
15698                        }
15699                    }
15700                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15701                } else {
15702                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15703                            || app.systemNoUi) && app.pendingUiClean) {
15704                        // If this application is now in the background and it
15705                        // had done UI, then give it the special trim level to
15706                        // have it free UI resources.
15707                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15708                        if (app.trimMemoryLevel < level && app.thread != null) {
15709                            try {
15710                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15711                                        "Trimming memory of bg-ui " + app.processName
15712                                        + " to " + level);
15713                                app.thread.scheduleTrimMemory(level);
15714                            } catch (RemoteException e) {
15715                            }
15716                        }
15717                        app.pendingUiClean = false;
15718                    }
15719                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15720                        try {
15721                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15722                                    "Trimming memory of fg " + app.processName
15723                                    + " to " + fgTrimLevel);
15724                            app.thread.scheduleTrimMemory(fgTrimLevel);
15725                        } catch (RemoteException e) {
15726                        }
15727                    }
15728                    app.trimMemoryLevel = fgTrimLevel;
15729                }
15730            }
15731        } else {
15732            if (mLowRamStartTime != 0) {
15733                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15734                mLowRamStartTime = 0;
15735            }
15736            for (int i=N-1; i>=0; i--) {
15737                ProcessRecord app = mLruProcesses.get(i);
15738                if (allChanged || app.procStateChanged) {
15739                    setProcessTrackerState(app, trackerMemFactor, now);
15740                    app.procStateChanged = false;
15741                }
15742                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15743                        || app.systemNoUi) && app.pendingUiClean) {
15744                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15745                            && app.thread != null) {
15746                        try {
15747                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15748                                    "Trimming memory of ui hidden " + app.processName
15749                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15750                            app.thread.scheduleTrimMemory(
15751                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15752                        } catch (RemoteException e) {
15753                        }
15754                    }
15755                    app.pendingUiClean = false;
15756                }
15757                app.trimMemoryLevel = 0;
15758            }
15759        }
15760
15761        if (mAlwaysFinishActivities) {
15762            // Need to do this on its own message because the stack may not
15763            // be in a consistent state at this point.
15764            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15765        }
15766
15767        if (allChanged) {
15768            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15769        }
15770
15771        if (mProcessStats.shouldWriteNowLocked(now)) {
15772            mHandler.post(new Runnable() {
15773                @Override public void run() {
15774                    synchronized (ActivityManagerService.this) {
15775                        mProcessStats.writeStateAsyncLocked();
15776                    }
15777                }
15778            });
15779        }
15780
15781        if (DEBUG_OOM_ADJ) {
15782            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15783        }
15784    }
15785
15786    final void trimApplications() {
15787        synchronized (this) {
15788            int i;
15789
15790            // First remove any unused application processes whose package
15791            // has been removed.
15792            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15793                final ProcessRecord app = mRemovedProcesses.get(i);
15794                if (app.activities.size() == 0
15795                        && app.curReceiver == null && app.services.size() == 0) {
15796                    Slog.i(
15797                        TAG, "Exiting empty application process "
15798                        + app.processName + " ("
15799                        + (app.thread != null ? app.thread.asBinder() : null)
15800                        + ")\n");
15801                    if (app.pid > 0 && app.pid != MY_PID) {
15802                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15803                                app.processName, app.setAdj, "empty");
15804                        app.killedByAm = true;
15805                        Process.killProcessQuiet(app.pid);
15806                    } else {
15807                        try {
15808                            app.thread.scheduleExit();
15809                        } catch (Exception e) {
15810                            // Ignore exceptions.
15811                        }
15812                    }
15813                    cleanUpApplicationRecordLocked(app, false, true, -1);
15814                    mRemovedProcesses.remove(i);
15815
15816                    if (app.persistent) {
15817                        if (app.persistent) {
15818                            addAppLocked(app.info, false);
15819                        }
15820                    }
15821                }
15822            }
15823
15824            // Now update the oom adj for all processes.
15825            updateOomAdjLocked();
15826        }
15827    }
15828
15829    /** This method sends the specified signal to each of the persistent apps */
15830    public void signalPersistentProcesses(int sig) throws RemoteException {
15831        if (sig != Process.SIGNAL_USR1) {
15832            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15833        }
15834
15835        synchronized (this) {
15836            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15837                    != PackageManager.PERMISSION_GRANTED) {
15838                throw new SecurityException("Requires permission "
15839                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15840            }
15841
15842            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15843                ProcessRecord r = mLruProcesses.get(i);
15844                if (r.thread != null && r.persistent) {
15845                    Process.sendSignal(r.pid, sig);
15846                }
15847            }
15848        }
15849    }
15850
15851    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15852        if (proc == null || proc == mProfileProc) {
15853            proc = mProfileProc;
15854            path = mProfileFile;
15855            profileType = mProfileType;
15856            clearProfilerLocked();
15857        }
15858        if (proc == null) {
15859            return;
15860        }
15861        try {
15862            proc.thread.profilerControl(false, path, null, profileType);
15863        } catch (RemoteException e) {
15864            throw new IllegalStateException("Process disappeared");
15865        }
15866    }
15867
15868    private void clearProfilerLocked() {
15869        if (mProfileFd != null) {
15870            try {
15871                mProfileFd.close();
15872            } catch (IOException e) {
15873            }
15874        }
15875        mProfileApp = null;
15876        mProfileProc = null;
15877        mProfileFile = null;
15878        mProfileType = 0;
15879        mAutoStopProfiler = false;
15880    }
15881
15882    public boolean profileControl(String process, int userId, boolean start,
15883            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15884
15885        try {
15886            synchronized (this) {
15887                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15888                // its own permission.
15889                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15890                        != PackageManager.PERMISSION_GRANTED) {
15891                    throw new SecurityException("Requires permission "
15892                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15893                }
15894
15895                if (start && fd == null) {
15896                    throw new IllegalArgumentException("null fd");
15897                }
15898
15899                ProcessRecord proc = null;
15900                if (process != null) {
15901                    proc = findProcessLocked(process, userId, "profileControl");
15902                }
15903
15904                if (start && (proc == null || proc.thread == null)) {
15905                    throw new IllegalArgumentException("Unknown process: " + process);
15906                }
15907
15908                if (start) {
15909                    stopProfilerLocked(null, null, 0);
15910                    setProfileApp(proc.info, proc.processName, path, fd, false);
15911                    mProfileProc = proc;
15912                    mProfileType = profileType;
15913                    try {
15914                        fd = fd.dup();
15915                    } catch (IOException e) {
15916                        fd = null;
15917                    }
15918                    proc.thread.profilerControl(start, path, fd, profileType);
15919                    fd = null;
15920                    mProfileFd = null;
15921                } else {
15922                    stopProfilerLocked(proc, path, profileType);
15923                    if (fd != null) {
15924                        try {
15925                            fd.close();
15926                        } catch (IOException e) {
15927                        }
15928                    }
15929                }
15930
15931                return true;
15932            }
15933        } catch (RemoteException e) {
15934            throw new IllegalStateException("Process disappeared");
15935        } finally {
15936            if (fd != null) {
15937                try {
15938                    fd.close();
15939                } catch (IOException e) {
15940                }
15941            }
15942        }
15943    }
15944
15945    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15946        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15947                userId, true, true, callName, null);
15948        ProcessRecord proc = null;
15949        try {
15950            int pid = Integer.parseInt(process);
15951            synchronized (mPidsSelfLocked) {
15952                proc = mPidsSelfLocked.get(pid);
15953            }
15954        } catch (NumberFormatException e) {
15955        }
15956
15957        if (proc == null) {
15958            ArrayMap<String, SparseArray<ProcessRecord>> all
15959                    = mProcessNames.getMap();
15960            SparseArray<ProcessRecord> procs = all.get(process);
15961            if (procs != null && procs.size() > 0) {
15962                proc = procs.valueAt(0);
15963                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15964                    for (int i=1; i<procs.size(); i++) {
15965                        ProcessRecord thisProc = procs.valueAt(i);
15966                        if (thisProc.userId == userId) {
15967                            proc = thisProc;
15968                            break;
15969                        }
15970                    }
15971                }
15972            }
15973        }
15974
15975        return proc;
15976    }
15977
15978    public boolean dumpHeap(String process, int userId, boolean managed,
15979            String path, ParcelFileDescriptor fd) throws RemoteException {
15980
15981        try {
15982            synchronized (this) {
15983                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15984                // its own permission (same as profileControl).
15985                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15986                        != PackageManager.PERMISSION_GRANTED) {
15987                    throw new SecurityException("Requires permission "
15988                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15989                }
15990
15991                if (fd == null) {
15992                    throw new IllegalArgumentException("null fd");
15993                }
15994
15995                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15996                if (proc == null || proc.thread == null) {
15997                    throw new IllegalArgumentException("Unknown process: " + process);
15998                }
15999
16000                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16001                if (!isDebuggable) {
16002                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16003                        throw new SecurityException("Process not debuggable: " + proc);
16004                    }
16005                }
16006
16007                proc.thread.dumpHeap(managed, path, fd);
16008                fd = null;
16009                return true;
16010            }
16011        } catch (RemoteException e) {
16012            throw new IllegalStateException("Process disappeared");
16013        } finally {
16014            if (fd != null) {
16015                try {
16016                    fd.close();
16017                } catch (IOException e) {
16018                }
16019            }
16020        }
16021    }
16022
16023    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16024    public void monitor() {
16025        synchronized (this) { }
16026    }
16027
16028    void onCoreSettingsChange(Bundle settings) {
16029        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16030            ProcessRecord processRecord = mLruProcesses.get(i);
16031            try {
16032                if (processRecord.thread != null) {
16033                    processRecord.thread.setCoreSettings(settings);
16034                }
16035            } catch (RemoteException re) {
16036                /* ignore */
16037            }
16038        }
16039    }
16040
16041    // Multi-user methods
16042
16043    @Override
16044    public boolean switchUser(final int userId) {
16045        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16046                != PackageManager.PERMISSION_GRANTED) {
16047            String msg = "Permission Denial: switchUser() from pid="
16048                    + Binder.getCallingPid()
16049                    + ", uid=" + Binder.getCallingUid()
16050                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16051            Slog.w(TAG, msg);
16052            throw new SecurityException(msg);
16053        }
16054
16055        final long ident = Binder.clearCallingIdentity();
16056        try {
16057            synchronized (this) {
16058                final int oldUserId = mCurrentUserId;
16059                if (oldUserId == userId) {
16060                    return true;
16061                }
16062
16063                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16064                if (userInfo == null) {
16065                    Slog.w(TAG, "No user info for user #" + userId);
16066                    return false;
16067                }
16068
16069                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16070                        R.anim.screen_user_enter);
16071
16072                boolean needStart = false;
16073
16074                // If the user we are switching to is not currently started, then
16075                // we need to start it now.
16076                if (mStartedUsers.get(userId) == null) {
16077                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16078                    updateStartedUserArrayLocked();
16079                    needStart = true;
16080                }
16081
16082                mCurrentUserId = userId;
16083                final Integer userIdInt = Integer.valueOf(userId);
16084                mUserLru.remove(userIdInt);
16085                mUserLru.add(userIdInt);
16086
16087                mWindowManager.setCurrentUser(userId);
16088
16089                // Once the internal notion of the active user has switched, we lock the device
16090                // with the option to show the user switcher on the keyguard.
16091                mWindowManager.lockNow(null);
16092
16093                final UserStartedState uss = mStartedUsers.get(userId);
16094
16095                // Make sure user is in the started state.  If it is currently
16096                // stopping, we need to knock that off.
16097                if (uss.mState == UserStartedState.STATE_STOPPING) {
16098                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16099                    // so we can just fairly silently bring the user back from
16100                    // the almost-dead.
16101                    uss.mState = UserStartedState.STATE_RUNNING;
16102                    updateStartedUserArrayLocked();
16103                    needStart = true;
16104                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16105                    // This means ACTION_SHUTDOWN has been sent, so we will
16106                    // need to treat this as a new boot of the user.
16107                    uss.mState = UserStartedState.STATE_BOOTING;
16108                    updateStartedUserArrayLocked();
16109                    needStart = true;
16110                }
16111
16112                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16113                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16114                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16115                        oldUserId, userId, uss));
16116                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16117                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16118                if (needStart) {
16119                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16120                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16121                            | Intent.FLAG_RECEIVER_FOREGROUND);
16122                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16123                    broadcastIntentLocked(null, null, intent,
16124                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16125                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16126                }
16127
16128                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16129                    if (userId != 0) {
16130                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16131                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16132                        broadcastIntentLocked(null, null, intent, null,
16133                                new IIntentReceiver.Stub() {
16134                                    public void performReceive(Intent intent, int resultCode,
16135                                            String data, Bundle extras, boolean ordered,
16136                                            boolean sticky, int sendingUser) {
16137                                        userInitialized(uss, userId);
16138                                    }
16139                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16140                                true, false, MY_PID, Process.SYSTEM_UID,
16141                                userId);
16142                        uss.initializing = true;
16143                    } else {
16144                        getUserManagerLocked().makeInitialized(userInfo.id);
16145                    }
16146                }
16147
16148                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16149                if (homeInFront) {
16150                    startHomeActivityLocked(userId);
16151                } else {
16152                    mStackSupervisor.resumeTopActivitiesLocked();
16153                }
16154
16155                EventLogTags.writeAmSwitchUser(userId);
16156                getUserManagerLocked().userForeground(userId);
16157                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16158                if (needStart) {
16159                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16160                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16161                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16162                    broadcastIntentLocked(null, null, intent,
16163                            null, new IIntentReceiver.Stub() {
16164                                @Override
16165                                public void performReceive(Intent intent, int resultCode, String data,
16166                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16167                                        throws RemoteException {
16168                                }
16169                            }, 0, null, null,
16170                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16171                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16172                }
16173            }
16174        } finally {
16175            Binder.restoreCallingIdentity(ident);
16176        }
16177
16178        return true;
16179    }
16180
16181    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16182        long ident = Binder.clearCallingIdentity();
16183        try {
16184            Intent intent;
16185            if (oldUserId >= 0) {
16186                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16187                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16188                        | Intent.FLAG_RECEIVER_FOREGROUND);
16189                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16190                broadcastIntentLocked(null, null, intent,
16191                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16192                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16193            }
16194            if (newUserId >= 0) {
16195                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16196                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16197                        | Intent.FLAG_RECEIVER_FOREGROUND);
16198                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16199                broadcastIntentLocked(null, null, intent,
16200                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16201                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16202                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16203                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16204                        | Intent.FLAG_RECEIVER_FOREGROUND);
16205                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16206                broadcastIntentLocked(null, null, intent,
16207                        null, null, 0, null, null,
16208                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16209                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16210            }
16211        } finally {
16212            Binder.restoreCallingIdentity(ident);
16213        }
16214    }
16215
16216    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16217            final int newUserId) {
16218        final int N = mUserSwitchObservers.beginBroadcast();
16219        if (N > 0) {
16220            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16221                int mCount = 0;
16222                @Override
16223                public void sendResult(Bundle data) throws RemoteException {
16224                    synchronized (ActivityManagerService.this) {
16225                        if (mCurUserSwitchCallback == this) {
16226                            mCount++;
16227                            if (mCount == N) {
16228                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16229                            }
16230                        }
16231                    }
16232                }
16233            };
16234            synchronized (this) {
16235                uss.switching = true;
16236                mCurUserSwitchCallback = callback;
16237            }
16238            for (int i=0; i<N; i++) {
16239                try {
16240                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16241                            newUserId, callback);
16242                } catch (RemoteException e) {
16243                }
16244            }
16245        } else {
16246            synchronized (this) {
16247                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16248            }
16249        }
16250        mUserSwitchObservers.finishBroadcast();
16251    }
16252
16253    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16254        synchronized (this) {
16255            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16256            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16257        }
16258    }
16259
16260    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16261        mCurUserSwitchCallback = null;
16262        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16263        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16264                oldUserId, newUserId, uss));
16265    }
16266
16267    void userInitialized(UserStartedState uss, int newUserId) {
16268        completeSwitchAndInitalize(uss, newUserId, true, false);
16269    }
16270
16271    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16272        completeSwitchAndInitalize(uss, newUserId, false, true);
16273    }
16274
16275    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16276            boolean clearInitializing, boolean clearSwitching) {
16277        boolean unfrozen = false;
16278        synchronized (this) {
16279            if (clearInitializing) {
16280                uss.initializing = false;
16281                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16282            }
16283            if (clearSwitching) {
16284                uss.switching = false;
16285            }
16286            if (!uss.switching && !uss.initializing) {
16287                mWindowManager.stopFreezingScreen();
16288                unfrozen = true;
16289            }
16290        }
16291        if (unfrozen) {
16292            final int N = mUserSwitchObservers.beginBroadcast();
16293            for (int i=0; i<N; i++) {
16294                try {
16295                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16296                } catch (RemoteException e) {
16297                }
16298            }
16299            mUserSwitchObservers.finishBroadcast();
16300        }
16301    }
16302
16303    void finishUserSwitch(UserStartedState uss) {
16304        synchronized (this) {
16305            if (uss.mState == UserStartedState.STATE_BOOTING
16306                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16307                uss.mState = UserStartedState.STATE_RUNNING;
16308                final int userId = uss.mHandle.getIdentifier();
16309                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16310                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16311                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16312                broadcastIntentLocked(null, null, intent,
16313                        null, null, 0, null, null,
16314                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16315                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16316            }
16317            int num = mUserLru.size();
16318            int i = 0;
16319            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16320                Integer oldUserId = mUserLru.get(i);
16321                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16322                if (oldUss == null) {
16323                    // Shouldn't happen, but be sane if it does.
16324                    mUserLru.remove(i);
16325                    num--;
16326                    continue;
16327                }
16328                if (oldUss.mState == UserStartedState.STATE_STOPPING
16329                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16330                    // This user is already stopping, doesn't count.
16331                    num--;
16332                    i++;
16333                    continue;
16334                }
16335                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16336                    // Owner and current can't be stopped, but count as running.
16337                    i++;
16338                    continue;
16339                }
16340                // This is a user to be stopped.
16341                stopUserLocked(oldUserId, null);
16342                num--;
16343                i++;
16344            }
16345        }
16346    }
16347
16348    @Override
16349    public int stopUser(final int userId, final IStopUserCallback callback) {
16350        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16351                != PackageManager.PERMISSION_GRANTED) {
16352            String msg = "Permission Denial: switchUser() from pid="
16353                    + Binder.getCallingPid()
16354                    + ", uid=" + Binder.getCallingUid()
16355                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16356            Slog.w(TAG, msg);
16357            throw new SecurityException(msg);
16358        }
16359        if (userId <= 0) {
16360            throw new IllegalArgumentException("Can't stop primary user " + userId);
16361        }
16362        synchronized (this) {
16363            return stopUserLocked(userId, callback);
16364        }
16365    }
16366
16367    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16368        if (mCurrentUserId == userId) {
16369            return ActivityManager.USER_OP_IS_CURRENT;
16370        }
16371
16372        final UserStartedState uss = mStartedUsers.get(userId);
16373        if (uss == null) {
16374            // User is not started, nothing to do...  but we do need to
16375            // callback if requested.
16376            if (callback != null) {
16377                mHandler.post(new Runnable() {
16378                    @Override
16379                    public void run() {
16380                        try {
16381                            callback.userStopped(userId);
16382                        } catch (RemoteException e) {
16383                        }
16384                    }
16385                });
16386            }
16387            return ActivityManager.USER_OP_SUCCESS;
16388        }
16389
16390        if (callback != null) {
16391            uss.mStopCallbacks.add(callback);
16392        }
16393
16394        if (uss.mState != UserStartedState.STATE_STOPPING
16395                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16396            uss.mState = UserStartedState.STATE_STOPPING;
16397            updateStartedUserArrayLocked();
16398
16399            long ident = Binder.clearCallingIdentity();
16400            try {
16401                // We are going to broadcast ACTION_USER_STOPPING and then
16402                // once that is done send a final ACTION_SHUTDOWN and then
16403                // stop the user.
16404                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16405                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16406                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16407                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16408                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16409                // This is the result receiver for the final shutdown broadcast.
16410                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16411                    @Override
16412                    public void performReceive(Intent intent, int resultCode, String data,
16413                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16414                        finishUserStop(uss);
16415                    }
16416                };
16417                // This is the result receiver for the initial stopping broadcast.
16418                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16419                    @Override
16420                    public void performReceive(Intent intent, int resultCode, String data,
16421                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16422                        // On to the next.
16423                        synchronized (ActivityManagerService.this) {
16424                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16425                                // Whoops, we are being started back up.  Abort, abort!
16426                                return;
16427                            }
16428                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16429                        }
16430                        broadcastIntentLocked(null, null, shutdownIntent,
16431                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16432                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16433                    }
16434                };
16435                // Kick things off.
16436                broadcastIntentLocked(null, null, stoppingIntent,
16437                        null, stoppingReceiver, 0, null, null,
16438                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16439                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16440            } finally {
16441                Binder.restoreCallingIdentity(ident);
16442            }
16443        }
16444
16445        return ActivityManager.USER_OP_SUCCESS;
16446    }
16447
16448    void finishUserStop(UserStartedState uss) {
16449        final int userId = uss.mHandle.getIdentifier();
16450        boolean stopped;
16451        ArrayList<IStopUserCallback> callbacks;
16452        synchronized (this) {
16453            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16454            if (mStartedUsers.get(userId) != uss) {
16455                stopped = false;
16456            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16457                stopped = false;
16458            } else {
16459                stopped = true;
16460                // User can no longer run.
16461                mStartedUsers.remove(userId);
16462                mUserLru.remove(Integer.valueOf(userId));
16463                updateStartedUserArrayLocked();
16464
16465                // Clean up all state and processes associated with the user.
16466                // Kill all the processes for the user.
16467                forceStopUserLocked(userId, "finish user");
16468            }
16469        }
16470
16471        for (int i=0; i<callbacks.size(); i++) {
16472            try {
16473                if (stopped) callbacks.get(i).userStopped(userId);
16474                else callbacks.get(i).userStopAborted(userId);
16475            } catch (RemoteException e) {
16476            }
16477        }
16478
16479        mStackSupervisor.removeUserLocked(userId);
16480    }
16481
16482    @Override
16483    public UserInfo getCurrentUser() {
16484        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16485                != PackageManager.PERMISSION_GRANTED) && (
16486                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16487                != PackageManager.PERMISSION_GRANTED)) {
16488            String msg = "Permission Denial: getCurrentUser() from pid="
16489                    + Binder.getCallingPid()
16490                    + ", uid=" + Binder.getCallingUid()
16491                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16492            Slog.w(TAG, msg);
16493            throw new SecurityException(msg);
16494        }
16495        synchronized (this) {
16496            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16497        }
16498    }
16499
16500    int getCurrentUserIdLocked() {
16501        return mCurrentUserId;
16502    }
16503
16504    @Override
16505    public boolean isUserRunning(int userId, boolean orStopped) {
16506        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16507                != PackageManager.PERMISSION_GRANTED) {
16508            String msg = "Permission Denial: isUserRunning() from pid="
16509                    + Binder.getCallingPid()
16510                    + ", uid=" + Binder.getCallingUid()
16511                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16512            Slog.w(TAG, msg);
16513            throw new SecurityException(msg);
16514        }
16515        synchronized (this) {
16516            return isUserRunningLocked(userId, orStopped);
16517        }
16518    }
16519
16520    boolean isUserRunningLocked(int userId, boolean orStopped) {
16521        UserStartedState state = mStartedUsers.get(userId);
16522        if (state == null) {
16523            return false;
16524        }
16525        if (orStopped) {
16526            return true;
16527        }
16528        return state.mState != UserStartedState.STATE_STOPPING
16529                && state.mState != UserStartedState.STATE_SHUTDOWN;
16530    }
16531
16532    @Override
16533    public int[] getRunningUserIds() {
16534        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16535                != PackageManager.PERMISSION_GRANTED) {
16536            String msg = "Permission Denial: isUserRunning() from pid="
16537                    + Binder.getCallingPid()
16538                    + ", uid=" + Binder.getCallingUid()
16539                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16540            Slog.w(TAG, msg);
16541            throw new SecurityException(msg);
16542        }
16543        synchronized (this) {
16544            return mStartedUserArray;
16545        }
16546    }
16547
16548    private void updateStartedUserArrayLocked() {
16549        int num = 0;
16550        for (int i=0; i<mStartedUsers.size();  i++) {
16551            UserStartedState uss = mStartedUsers.valueAt(i);
16552            // This list does not include stopping users.
16553            if (uss.mState != UserStartedState.STATE_STOPPING
16554                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16555                num++;
16556            }
16557        }
16558        mStartedUserArray = new int[num];
16559        num = 0;
16560        for (int i=0; i<mStartedUsers.size();  i++) {
16561            UserStartedState uss = mStartedUsers.valueAt(i);
16562            if (uss.mState != UserStartedState.STATE_STOPPING
16563                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16564                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16565                num++;
16566            }
16567        }
16568    }
16569
16570    @Override
16571    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16572        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16573                != PackageManager.PERMISSION_GRANTED) {
16574            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16575                    + Binder.getCallingPid()
16576                    + ", uid=" + Binder.getCallingUid()
16577                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16578            Slog.w(TAG, msg);
16579            throw new SecurityException(msg);
16580        }
16581
16582        mUserSwitchObservers.register(observer);
16583    }
16584
16585    @Override
16586    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16587        mUserSwitchObservers.unregister(observer);
16588    }
16589
16590    private boolean userExists(int userId) {
16591        if (userId == 0) {
16592            return true;
16593        }
16594        UserManagerService ums = getUserManagerLocked();
16595        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16596    }
16597
16598    int[] getUsersLocked() {
16599        UserManagerService ums = getUserManagerLocked();
16600        return ums != null ? ums.getUserIds() : new int[] { 0 };
16601    }
16602
16603    UserManagerService getUserManagerLocked() {
16604        if (mUserManager == null) {
16605            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16606            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16607        }
16608        return mUserManager;
16609    }
16610
16611    private int applyUserId(int uid, int userId) {
16612        return UserHandle.getUid(userId, uid);
16613    }
16614
16615    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16616        if (info == null) return null;
16617        ApplicationInfo newInfo = new ApplicationInfo(info);
16618        newInfo.uid = applyUserId(info.uid, userId);
16619        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16620                + info.packageName;
16621        return newInfo;
16622    }
16623
16624    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16625        if (aInfo == null
16626                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16627            return aInfo;
16628        }
16629
16630        ActivityInfo info = new ActivityInfo(aInfo);
16631        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16632        return info;
16633    }
16634}
16635