ActivityManagerService.java revision df88d73092c62a1a3cd2b2056ca63ae2e70cc238
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.util.ArrayMap;
36import com.android.internal.R;
37import com.android.internal.annotations.GuardedBy;
38import com.android.internal.app.IAppOpsService;
39import com.android.internal.app.ProcessMap;
40import com.android.internal.app.ProcessStats;
41import com.android.internal.os.BackgroundThread;
42import com.android.internal.os.BatteryStatsImpl;
43import com.android.internal.os.ProcessCpuTracker;
44import com.android.internal.os.TransferPipe;
45import com.android.internal.util.FastPrintWriter;
46import com.android.internal.util.FastXmlSerializer;
47import com.android.internal.util.MemInfoReader;
48import com.android.internal.util.Preconditions;
49import com.android.server.AppOpsService;
50import com.android.server.AttributeCache;
51import com.android.server.IntentResolver;
52import com.android.server.ServiceThread;
53import com.android.server.SystemServer;
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 situatin started.
925     */
926    long mLowRamStartTime = 0;
927
928    /**
929     * This is set if we had to do a delayed dexopt of an app before launching
930     * it, to increasing the ANR timeouts in that case.
931     */
932    boolean mDidDexOpt;
933
934    String mDebugApp = null;
935    boolean mWaitForDebugger = false;
936    boolean mDebugTransient = false;
937    String mOrigDebugApp = null;
938    boolean mOrigWaitForDebugger = false;
939    boolean mAlwaysFinishActivities = false;
940    IActivityController mController = null;
941    String mProfileApp = null;
942    ProcessRecord mProfileProc = null;
943    String mProfileFile;
944    ParcelFileDescriptor mProfileFd;
945    int mProfileType = 0;
946    boolean mAutoStopProfiler = false;
947    String mOpenGlTraceApp = null;
948
949    static class ProcessChangeItem {
950        static final int CHANGE_ACTIVITIES = 1<<0;
951        static final int CHANGE_IMPORTANCE= 1<<1;
952        int changes;
953        int uid;
954        int pid;
955        int importance;
956        boolean foregroundActivities;
957    }
958
959    final RemoteCallbackList<IProcessObserver> mProcessObservers
960            = new RemoteCallbackList<IProcessObserver>();
961    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
962
963    final ArrayList<ProcessChangeItem> mPendingProcessChanges
964            = new ArrayList<ProcessChangeItem>();
965    final ArrayList<ProcessChangeItem> mAvailProcessChanges
966            = new ArrayList<ProcessChangeItem>();
967
968    /**
969     * Runtime CPU use collection thread.  This object's lock is used to
970     * protect all related state.
971     */
972    final Thread mProcessCpuThread;
973
974    /**
975     * Used to collect process stats when showing not responding dialog.
976     * Protected by mProcessCpuThread.
977     */
978    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
979            MONITOR_THREAD_CPU_USAGE);
980    final AtomicLong mLastCpuTime = new AtomicLong(0);
981    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
982
983    long mLastWriteTime = 0;
984
985    /**
986     * Used to retain an update lock when the foreground activity is in
987     * immersive mode.
988     */
989    final UpdateLock mUpdateLock = new UpdateLock("immersive");
990
991    /**
992     * Set to true after the system has finished booting.
993     */
994    boolean mBooted = false;
995
996    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
997    int mProcessLimitOverride = -1;
998
999    WindowManagerService mWindowManager;
1000
1001    final ActivityThread mSystemThread;
1002
1003    int mCurrentUserId = 0;
1004    private UserManagerService mUserManager;
1005
1006    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1007        final ProcessRecord mApp;
1008        final int mPid;
1009        final IApplicationThread mAppThread;
1010
1011        AppDeathRecipient(ProcessRecord app, int pid,
1012                IApplicationThread thread) {
1013            if (localLOGV) Slog.v(
1014                TAG, "New death recipient " + this
1015                + " for thread " + thread.asBinder());
1016            mApp = app;
1017            mPid = pid;
1018            mAppThread = thread;
1019        }
1020
1021        @Override
1022        public void binderDied() {
1023            if (localLOGV) Slog.v(
1024                TAG, "Death received in " + this
1025                + " for thread " + mAppThread.asBinder());
1026            synchronized(ActivityManagerService.this) {
1027                appDiedLocked(mApp, mPid, mAppThread);
1028            }
1029        }
1030    }
1031
1032    static final int SHOW_ERROR_MSG = 1;
1033    static final int SHOW_NOT_RESPONDING_MSG = 2;
1034    static final int SHOW_FACTORY_ERROR_MSG = 3;
1035    static final int UPDATE_CONFIGURATION_MSG = 4;
1036    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1037    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1038    static final int SERVICE_TIMEOUT_MSG = 12;
1039    static final int UPDATE_TIME_ZONE = 13;
1040    static final int SHOW_UID_ERROR_MSG = 14;
1041    static final int IM_FEELING_LUCKY_MSG = 15;
1042    static final int PROC_START_TIMEOUT_MSG = 20;
1043    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1044    static final int KILL_APPLICATION_MSG = 22;
1045    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1046    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1047    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1048    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1049    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1050    static final int CLEAR_DNS_CACHE_MSG = 28;
1051    static final int UPDATE_HTTP_PROXY_MSG = 29;
1052    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1053    static final int DISPATCH_PROCESSES_CHANGED = 31;
1054    static final int DISPATCH_PROCESS_DIED = 32;
1055    static final int REPORT_MEM_USAGE_MSG = 33;
1056    static final int REPORT_USER_SWITCH_MSG = 34;
1057    static final int CONTINUE_USER_SWITCH_MSG = 35;
1058    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1059    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1060    static final int PERSIST_URI_GRANTS_MSG = 38;
1061    static final int REQUEST_ALL_PSS_MSG = 39;
1062
1063    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1064    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1065    static final int FIRST_COMPAT_MODE_MSG = 300;
1066    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1067
1068    AlertDialog mUidAlert;
1069    CompatModeDialog mCompatModeDialog;
1070    long mLastMemUsageReportTime = 0;
1071
1072    /**
1073     * Flag whether the current user is a "monkey", i.e. whether
1074     * the UI is driven by a UI automation tool.
1075     */
1076    private boolean mUserIsMonkey;
1077
1078    final ServiceThread mHandlerThread;
1079    final MainHandler mHandler;
1080
1081    final class MainHandler extends Handler {
1082        public MainHandler(Looper looper) {
1083            super(looper, null, true);
1084        }
1085
1086        @Override
1087        public void handleMessage(Message msg) {
1088            switch (msg.what) {
1089            case SHOW_ERROR_MSG: {
1090                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1091                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1092                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1093                synchronized (ActivityManagerService.this) {
1094                    ProcessRecord proc = (ProcessRecord)data.get("app");
1095                    AppErrorResult res = (AppErrorResult) data.get("result");
1096                    if (proc != null && proc.crashDialog != null) {
1097                        Slog.e(TAG, "App already has crash dialog: " + proc);
1098                        if (res != null) {
1099                            res.set(0);
1100                        }
1101                        return;
1102                    }
1103                    if (!showBackground && UserHandle.getAppId(proc.uid)
1104                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1105                            && proc.pid != MY_PID) {
1106                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1107                        if (res != null) {
1108                            res.set(0);
1109                        }
1110                        return;
1111                    }
1112                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1113                        Dialog d = new AppErrorDialog(mContext,
1114                                ActivityManagerService.this, res, proc);
1115                        d.show();
1116                        proc.crashDialog = d;
1117                    } else {
1118                        // The device is asleep, so just pretend that the user
1119                        // saw a crash dialog and hit "force quit".
1120                        if (res != null) {
1121                            res.set(0);
1122                        }
1123                    }
1124                }
1125
1126                ensureBootCompleted();
1127            } break;
1128            case SHOW_NOT_RESPONDING_MSG: {
1129                synchronized (ActivityManagerService.this) {
1130                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1131                    ProcessRecord proc = (ProcessRecord)data.get("app");
1132                    if (proc != null && proc.anrDialog != null) {
1133                        Slog.e(TAG, "App already has anr dialog: " + proc);
1134                        return;
1135                    }
1136
1137                    Intent intent = new Intent("android.intent.action.ANR");
1138                    if (!mProcessesReady) {
1139                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1140                                | Intent.FLAG_RECEIVER_FOREGROUND);
1141                    }
1142                    broadcastIntentLocked(null, null, intent,
1143                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1144                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1145
1146                    if (mShowDialogs) {
1147                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1148                                mContext, proc, (ActivityRecord)data.get("activity"),
1149                                msg.arg1 != 0);
1150                        d.show();
1151                        proc.anrDialog = d;
1152                    } else {
1153                        // Just kill the app if there is no dialog to be shown.
1154                        killAppAtUsersRequest(proc, null);
1155                    }
1156                }
1157
1158                ensureBootCompleted();
1159            } break;
1160            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1161                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1162                synchronized (ActivityManagerService.this) {
1163                    ProcessRecord proc = (ProcessRecord) data.get("app");
1164                    if (proc == null) {
1165                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1166                        break;
1167                    }
1168                    if (proc.crashDialog != null) {
1169                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1170                        return;
1171                    }
1172                    AppErrorResult res = (AppErrorResult) data.get("result");
1173                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1174                        Dialog d = new StrictModeViolationDialog(mContext,
1175                                ActivityManagerService.this, res, proc);
1176                        d.show();
1177                        proc.crashDialog = d;
1178                    } else {
1179                        // The device is asleep, so just pretend that the user
1180                        // saw a crash dialog and hit "force quit".
1181                        res.set(0);
1182                    }
1183                }
1184                ensureBootCompleted();
1185            } break;
1186            case SHOW_FACTORY_ERROR_MSG: {
1187                Dialog d = new FactoryErrorDialog(
1188                    mContext, msg.getData().getCharSequence("msg"));
1189                d.show();
1190                ensureBootCompleted();
1191            } break;
1192            case UPDATE_CONFIGURATION_MSG: {
1193                final ContentResolver resolver = mContext.getContentResolver();
1194                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1195            } break;
1196            case GC_BACKGROUND_PROCESSES_MSG: {
1197                synchronized (ActivityManagerService.this) {
1198                    performAppGcsIfAppropriateLocked();
1199                }
1200            } break;
1201            case WAIT_FOR_DEBUGGER_MSG: {
1202                synchronized (ActivityManagerService.this) {
1203                    ProcessRecord app = (ProcessRecord)msg.obj;
1204                    if (msg.arg1 != 0) {
1205                        if (!app.waitedForDebugger) {
1206                            Dialog d = new AppWaitingForDebuggerDialog(
1207                                    ActivityManagerService.this,
1208                                    mContext, app);
1209                            app.waitDialog = d;
1210                            app.waitedForDebugger = true;
1211                            d.show();
1212                        }
1213                    } else {
1214                        if (app.waitDialog != null) {
1215                            app.waitDialog.dismiss();
1216                            app.waitDialog = null;
1217                        }
1218                    }
1219                }
1220            } break;
1221            case SERVICE_TIMEOUT_MSG: {
1222                if (mDidDexOpt) {
1223                    mDidDexOpt = false;
1224                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1225                    nmsg.obj = msg.obj;
1226                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1227                    return;
1228                }
1229                mServices.serviceTimeout((ProcessRecord)msg.obj);
1230            } break;
1231            case UPDATE_TIME_ZONE: {
1232                synchronized (ActivityManagerService.this) {
1233                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1234                        ProcessRecord r = mLruProcesses.get(i);
1235                        if (r.thread != null) {
1236                            try {
1237                                r.thread.updateTimeZone();
1238                            } catch (RemoteException ex) {
1239                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1240                            }
1241                        }
1242                    }
1243                }
1244            } break;
1245            case CLEAR_DNS_CACHE_MSG: {
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.clearDnsCache();
1252                            } catch (RemoteException ex) {
1253                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1254                            }
1255                        }
1256                    }
1257                }
1258            } break;
1259            case UPDATE_HTTP_PROXY_MSG: {
1260                ProxyProperties proxy = (ProxyProperties)msg.obj;
1261                String host = "";
1262                String port = "";
1263                String exclList = "";
1264                String pacFileUrl = null;
1265                if (proxy != null) {
1266                    host = proxy.getHost();
1267                    port = Integer.toString(proxy.getPort());
1268                    exclList = proxy.getExclusionList();
1269                    pacFileUrl = proxy.getPacFileUrl();
1270                }
1271                synchronized (ActivityManagerService.this) {
1272                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1273                        ProcessRecord r = mLruProcesses.get(i);
1274                        if (r.thread != null) {
1275                            try {
1276                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1277                            } catch (RemoteException ex) {
1278                                Slog.w(TAG, "Failed to update http proxy for: " +
1279                                        r.info.processName);
1280                            }
1281                        }
1282                    }
1283                }
1284            } break;
1285            case SHOW_UID_ERROR_MSG: {
1286                String title = "System UIDs Inconsistent";
1287                String text = "UIDs on the system are inconsistent, you need to wipe your"
1288                        + " data partition or your device will be unstable.";
1289                Log.e(TAG, title + ": " + text);
1290                if (mShowDialogs) {
1291                    // XXX This is a temporary dialog, no need to localize.
1292                    AlertDialog d = new BaseErrorDialog(mContext);
1293                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1294                    d.setCancelable(false);
1295                    d.setTitle(title);
1296                    d.setMessage(text);
1297                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1298                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1299                    mUidAlert = d;
1300                    d.show();
1301                }
1302            } break;
1303            case IM_FEELING_LUCKY_MSG: {
1304                if (mUidAlert != null) {
1305                    mUidAlert.dismiss();
1306                    mUidAlert = null;
1307                }
1308            } break;
1309            case PROC_START_TIMEOUT_MSG: {
1310                if (mDidDexOpt) {
1311                    mDidDexOpt = false;
1312                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1313                    nmsg.obj = msg.obj;
1314                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1315                    return;
1316                }
1317                ProcessRecord app = (ProcessRecord)msg.obj;
1318                synchronized (ActivityManagerService.this) {
1319                    processStartTimedOutLocked(app);
1320                }
1321            } break;
1322            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1323                synchronized (ActivityManagerService.this) {
1324                    doPendingActivityLaunchesLocked(true);
1325                }
1326            } break;
1327            case KILL_APPLICATION_MSG: {
1328                synchronized (ActivityManagerService.this) {
1329                    int appid = msg.arg1;
1330                    boolean restart = (msg.arg2 == 1);
1331                    Bundle bundle = (Bundle)msg.obj;
1332                    String pkg = bundle.getString("pkg");
1333                    String reason = bundle.getString("reason");
1334                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1335                            UserHandle.USER_ALL, reason);
1336                }
1337            } break;
1338            case FINALIZE_PENDING_INTENT_MSG: {
1339                ((PendingIntentRecord)msg.obj).completeFinalize();
1340            } break;
1341            case POST_HEAVY_NOTIFICATION_MSG: {
1342                INotificationManager inm = NotificationManager.getService();
1343                if (inm == null) {
1344                    return;
1345                }
1346
1347                ActivityRecord root = (ActivityRecord)msg.obj;
1348                ProcessRecord process = root.app;
1349                if (process == null) {
1350                    return;
1351                }
1352
1353                try {
1354                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1355                    String text = mContext.getString(R.string.heavy_weight_notification,
1356                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1357                    Notification notification = new Notification();
1358                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1359                    notification.when = 0;
1360                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1361                    notification.tickerText = text;
1362                    notification.defaults = 0; // please be quiet
1363                    notification.sound = null;
1364                    notification.vibrate = null;
1365                    notification.setLatestEventInfo(context, text,
1366                            mContext.getText(R.string.heavy_weight_notification_detail),
1367                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1368                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1369                                    new UserHandle(root.userId)));
1370
1371                    try {
1372                        int[] outId = new int[1];
1373                        inm.enqueueNotificationWithTag("android", "android", null,
1374                                R.string.heavy_weight_notification,
1375                                notification, outId, root.userId);
1376                    } catch (RuntimeException e) {
1377                        Slog.w(ActivityManagerService.TAG,
1378                                "Error showing notification for heavy-weight app", e);
1379                    } catch (RemoteException e) {
1380                    }
1381                } catch (NameNotFoundException e) {
1382                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1383                }
1384            } break;
1385            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1386                INotificationManager inm = NotificationManager.getService();
1387                if (inm == null) {
1388                    return;
1389                }
1390                try {
1391                    inm.cancelNotificationWithTag("android", null,
1392                            R.string.heavy_weight_notification,  msg.arg1);
1393                } catch (RuntimeException e) {
1394                    Slog.w(ActivityManagerService.TAG,
1395                            "Error canceling notification for service", e);
1396                } catch (RemoteException e) {
1397                }
1398            } break;
1399            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1400                synchronized (ActivityManagerService.this) {
1401                    checkExcessivePowerUsageLocked(true);
1402                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1403                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1404                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1405                }
1406            } break;
1407            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1408                synchronized (ActivityManagerService.this) {
1409                    ActivityRecord ar = (ActivityRecord)msg.obj;
1410                    if (mCompatModeDialog != null) {
1411                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1412                                ar.info.applicationInfo.packageName)) {
1413                            return;
1414                        }
1415                        mCompatModeDialog.dismiss();
1416                        mCompatModeDialog = null;
1417                    }
1418                    if (ar != null && false) {
1419                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1420                                ar.packageName)) {
1421                            int mode = mCompatModePackages.computeCompatModeLocked(
1422                                    ar.info.applicationInfo);
1423                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1424                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1425                                mCompatModeDialog = new CompatModeDialog(
1426                                        ActivityManagerService.this, mContext,
1427                                        ar.info.applicationInfo);
1428                                mCompatModeDialog.show();
1429                            }
1430                        }
1431                    }
1432                }
1433                break;
1434            }
1435            case DISPATCH_PROCESSES_CHANGED: {
1436                dispatchProcessesChanged();
1437                break;
1438            }
1439            case DISPATCH_PROCESS_DIED: {
1440                final int pid = msg.arg1;
1441                final int uid = msg.arg2;
1442                dispatchProcessDied(pid, uid);
1443                break;
1444            }
1445            case REPORT_MEM_USAGE_MSG: {
1446                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1447                Thread thread = new Thread() {
1448                    @Override public void run() {
1449                        final SparseArray<ProcessMemInfo> infoMap
1450                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1451                        for (int i=0, N=memInfos.size(); i<N; i++) {
1452                            ProcessMemInfo mi = memInfos.get(i);
1453                            infoMap.put(mi.pid, mi);
1454                        }
1455                        updateCpuStatsNow();
1456                        synchronized (mProcessCpuThread) {
1457                            final int N = mProcessCpuTracker.countStats();
1458                            for (int i=0; i<N; i++) {
1459                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1460                                if (st.vsize > 0) {
1461                                    long pss = Debug.getPss(st.pid, null);
1462                                    if (pss > 0) {
1463                                        if (infoMap.indexOfKey(st.pid) < 0) {
1464                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1465                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1466                                            mi.pss = pss;
1467                                            memInfos.add(mi);
1468                                        }
1469                                    }
1470                                }
1471                            }
1472                        }
1473
1474                        long totalPss = 0;
1475                        for (int i=0, N=memInfos.size(); i<N; i++) {
1476                            ProcessMemInfo mi = memInfos.get(i);
1477                            if (mi.pss == 0) {
1478                                mi.pss = Debug.getPss(mi.pid, null);
1479                            }
1480                            totalPss += mi.pss;
1481                        }
1482                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1483                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1484                                if (lhs.oomAdj != rhs.oomAdj) {
1485                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1486                                }
1487                                if (lhs.pss != rhs.pss) {
1488                                    return lhs.pss < rhs.pss ? 1 : -1;
1489                                }
1490                                return 0;
1491                            }
1492                        });
1493
1494                        StringBuilder tag = new StringBuilder(128);
1495                        StringBuilder stack = new StringBuilder(128);
1496                        tag.append("Low on memory -- ");
1497                        appendMemBucket(tag, totalPss, "total", false);
1498                        appendMemBucket(stack, totalPss, "total", true);
1499
1500                        StringBuilder logBuilder = new StringBuilder(1024);
1501                        logBuilder.append("Low on memory:\n");
1502
1503                        boolean firstLine = true;
1504                        int lastOomAdj = Integer.MIN_VALUE;
1505                        for (int i=0, N=memInfos.size(); i<N; i++) {
1506                            ProcessMemInfo mi = memInfos.get(i);
1507
1508                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1509                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1510                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1511                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1512                                if (lastOomAdj != mi.oomAdj) {
1513                                    lastOomAdj = mi.oomAdj;
1514                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1515                                        tag.append(" / ");
1516                                    }
1517                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1518                                        if (firstLine) {
1519                                            stack.append(":");
1520                                            firstLine = false;
1521                                        }
1522                                        stack.append("\n\t at ");
1523                                    } else {
1524                                        stack.append("$");
1525                                    }
1526                                } else {
1527                                    tag.append(" ");
1528                                    stack.append("$");
1529                                }
1530                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1531                                    appendMemBucket(tag, mi.pss, mi.name, false);
1532                                }
1533                                appendMemBucket(stack, mi.pss, mi.name, true);
1534                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1535                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1536                                    stack.append("(");
1537                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1538                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1539                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1540                                            stack.append(":");
1541                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1542                                        }
1543                                    }
1544                                    stack.append(")");
1545                                }
1546                            }
1547
1548                            logBuilder.append("  ");
1549                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1550                            logBuilder.append(' ');
1551                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1552                            logBuilder.append(' ');
1553                            ProcessList.appendRamKb(logBuilder, mi.pss);
1554                            logBuilder.append(" kB: ");
1555                            logBuilder.append(mi.name);
1556                            logBuilder.append(" (");
1557                            logBuilder.append(mi.pid);
1558                            logBuilder.append(") ");
1559                            logBuilder.append(mi.adjType);
1560                            logBuilder.append('\n');
1561                            if (mi.adjReason != null) {
1562                                logBuilder.append("                      ");
1563                                logBuilder.append(mi.adjReason);
1564                                logBuilder.append('\n');
1565                            }
1566                        }
1567
1568                        logBuilder.append("           ");
1569                        ProcessList.appendRamKb(logBuilder, totalPss);
1570                        logBuilder.append(" kB: TOTAL\n");
1571
1572                        long[] infos = new long[Debug.MEMINFO_COUNT];
1573                        Debug.getMemInfo(infos);
1574                        logBuilder.append("  MemInfo: ");
1575                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1576                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1577                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1578                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1579                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1580                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1581                            logBuilder.append("  ZRAM: ");
1582                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1583                            logBuilder.append(" kB RAM, ");
1584                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1585                            logBuilder.append(" kB swap total, ");
1586                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1587                            logBuilder.append(" kB swap free\n");
1588                        }
1589                        Slog.i(TAG, logBuilder.toString());
1590
1591                        StringBuilder dropBuilder = new StringBuilder(1024);
1592                        /*
1593                        StringWriter oomSw = new StringWriter();
1594                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1595                        StringWriter catSw = new StringWriter();
1596                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1597                        String[] emptyArgs = new String[] { };
1598                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1599                        oomPw.flush();
1600                        String oomString = oomSw.toString();
1601                        */
1602                        dropBuilder.append(stack);
1603                        dropBuilder.append('\n');
1604                        dropBuilder.append('\n');
1605                        dropBuilder.append(logBuilder);
1606                        dropBuilder.append('\n');
1607                        /*
1608                        dropBuilder.append(oomString);
1609                        dropBuilder.append('\n');
1610                        */
1611                        StringWriter catSw = new StringWriter();
1612                        synchronized (ActivityManagerService.this) {
1613                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1614                            String[] emptyArgs = new String[] { };
1615                            catPw.println();
1616                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1617                            catPw.println();
1618                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1619                                    false, false, null);
1620                            catPw.println();
1621                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1622                            catPw.flush();
1623                        }
1624                        dropBuilder.append(catSw.toString());
1625                        addErrorToDropBox("lowmem", null, "system_server", null,
1626                                null, tag.toString(), dropBuilder.toString(), null, null);
1627                        //Slog.i(TAG, "Sent to dropbox:");
1628                        //Slog.i(TAG, dropBuilder.toString());
1629                        synchronized (ActivityManagerService.this) {
1630                            long now = SystemClock.uptimeMillis();
1631                            if (mLastMemUsageReportTime < now) {
1632                                mLastMemUsageReportTime = now;
1633                            }
1634                        }
1635                    }
1636                };
1637                thread.start();
1638                break;
1639            }
1640            case REPORT_USER_SWITCH_MSG: {
1641                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1642                break;
1643            }
1644            case CONTINUE_USER_SWITCH_MSG: {
1645                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1646                break;
1647            }
1648            case USER_SWITCH_TIMEOUT_MSG: {
1649                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1650                break;
1651            }
1652            case IMMERSIVE_MODE_LOCK_MSG: {
1653                final boolean nextState = (msg.arg1 != 0);
1654                if (mUpdateLock.isHeld() != nextState) {
1655                    if (DEBUG_IMMERSIVE) {
1656                        final ActivityRecord r = (ActivityRecord) msg.obj;
1657                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1658                    }
1659                    if (nextState) {
1660                        mUpdateLock.acquire();
1661                    } else {
1662                        mUpdateLock.release();
1663                    }
1664                }
1665                break;
1666            }
1667            case PERSIST_URI_GRANTS_MSG: {
1668                writeGrantedUriPermissions();
1669                break;
1670            }
1671            case REQUEST_ALL_PSS_MSG: {
1672                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1673                break;
1674            }
1675            }
1676        }
1677    };
1678
1679    static final int COLLECT_PSS_BG_MSG = 1;
1680
1681    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1682        @Override
1683        public void handleMessage(Message msg) {
1684            switch (msg.what) {
1685            case COLLECT_PSS_BG_MSG: {
1686                int i=0, num=0;
1687                long start = SystemClock.uptimeMillis();
1688                long[] tmp = new long[1];
1689                do {
1690                    ProcessRecord proc;
1691                    int procState;
1692                    int pid;
1693                    synchronized (ActivityManagerService.this) {
1694                        if (i >= mPendingPssProcesses.size()) {
1695                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1696                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1697                            mPendingPssProcesses.clear();
1698                            return;
1699                        }
1700                        proc = mPendingPssProcesses.get(i);
1701                        procState = proc.pssProcState;
1702                        if (proc.thread != null && procState == proc.setProcState) {
1703                            pid = proc.pid;
1704                        } else {
1705                            proc = null;
1706                            pid = 0;
1707                        }
1708                        i++;
1709                    }
1710                    if (proc != null) {
1711                        long pss = Debug.getPss(pid, tmp);
1712                        synchronized (ActivityManagerService.this) {
1713                            if (proc.thread != null && proc.setProcState == procState
1714                                    && proc.pid == pid) {
1715                                num++;
1716                                proc.lastPssTime = SystemClock.uptimeMillis();
1717                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1718                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1719                                        + ": " + pss + " lastPss=" + proc.lastPss
1720                                        + " state=" + ProcessList.makeProcStateString(procState));
1721                                if (proc.initialIdlePss == 0) {
1722                                    proc.initialIdlePss = pss;
1723                                }
1724                                proc.lastPss = pss;
1725                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1726                                    proc.lastCachedPss = pss;
1727                                }
1728                            }
1729                        }
1730                    }
1731                } while (true);
1732            }
1733            }
1734        }
1735    };
1736
1737    public void setSystemProcess() {
1738        try {
1739            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1740            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1741            ServiceManager.addService("meminfo", new MemBinder(this));
1742            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1743            ServiceManager.addService("dbinfo", new DbBinder(this));
1744            if (MONITOR_CPU_USAGE) {
1745                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1746            }
1747            ServiceManager.addService("permission", new PermissionController(this));
1748
1749            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1750                    "android", STOCK_PM_FLAGS);
1751            mSystemThread.installSystemApplicationInfo(info);
1752
1753            synchronized (this) {
1754                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1755                app.persistent = true;
1756                app.pid = MY_PID;
1757                app.maxAdj = ProcessList.SYSTEM_ADJ;
1758                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1759                mProcessNames.put(app.processName, app.uid, app);
1760                synchronized (mPidsSelfLocked) {
1761                    mPidsSelfLocked.put(app.pid, app);
1762                }
1763                updateLruProcessLocked(app, false, null);
1764                updateOomAdjLocked();
1765            }
1766        } catch (PackageManager.NameNotFoundException e) {
1767            throw new RuntimeException(
1768                    "Unable to find android system package", e);
1769        }
1770    }
1771
1772    public void setWindowManager(WindowManagerService wm) {
1773        mWindowManager = wm;
1774        mStackSupervisor.setWindowManager(wm);
1775    }
1776
1777    public void startObservingNativeCrashes() {
1778        final NativeCrashListener ncl = new NativeCrashListener(this);
1779        ncl.start();
1780    }
1781
1782    public IAppOpsService getAppOpsService() {
1783        return mAppOpsService;
1784    }
1785
1786    static class MemBinder extends Binder {
1787        ActivityManagerService mActivityManagerService;
1788        MemBinder(ActivityManagerService activityManagerService) {
1789            mActivityManagerService = activityManagerService;
1790        }
1791
1792        @Override
1793        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1794            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1795                    != PackageManager.PERMISSION_GRANTED) {
1796                pw.println("Permission Denial: can't dump meminfo from from pid="
1797                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1798                        + " without permission " + android.Manifest.permission.DUMP);
1799                return;
1800            }
1801
1802            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1803        }
1804    }
1805
1806    static class GraphicsBinder extends Binder {
1807        ActivityManagerService mActivityManagerService;
1808        GraphicsBinder(ActivityManagerService activityManagerService) {
1809            mActivityManagerService = activityManagerService;
1810        }
1811
1812        @Override
1813        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1814            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1815                    != PackageManager.PERMISSION_GRANTED) {
1816                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1817                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1818                        + " without permission " + android.Manifest.permission.DUMP);
1819                return;
1820            }
1821
1822            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1823        }
1824    }
1825
1826    static class DbBinder extends Binder {
1827        ActivityManagerService mActivityManagerService;
1828        DbBinder(ActivityManagerService activityManagerService) {
1829            mActivityManagerService = activityManagerService;
1830        }
1831
1832        @Override
1833        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1834            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1835                    != PackageManager.PERMISSION_GRANTED) {
1836                pw.println("Permission Denial: can't dump dbinfo from from pid="
1837                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1838                        + " without permission " + android.Manifest.permission.DUMP);
1839                return;
1840            }
1841
1842            mActivityManagerService.dumpDbInfo(fd, pw, args);
1843        }
1844    }
1845
1846    static class CpuBinder extends Binder {
1847        ActivityManagerService mActivityManagerService;
1848        CpuBinder(ActivityManagerService activityManagerService) {
1849            mActivityManagerService = activityManagerService;
1850        }
1851
1852        @Override
1853        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1854            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1855                    != PackageManager.PERMISSION_GRANTED) {
1856                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1857                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1858                        + " without permission " + android.Manifest.permission.DUMP);
1859                return;
1860            }
1861
1862            synchronized (mActivityManagerService.mProcessCpuThread) {
1863                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1864                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1865                        SystemClock.uptimeMillis()));
1866            }
1867        }
1868    }
1869
1870    public static class Lifecycle extends SystemService {
1871        private ActivityManagerService mService;
1872
1873        @Override
1874        public void onCreate(Context context) {
1875            mService = new ActivityManagerService(context);
1876        }
1877
1878        @Override
1879        public void onStart() {
1880            mService.start();
1881        }
1882
1883        public ActivityManagerService getService() {
1884            return mService;
1885        }
1886    }
1887
1888    // Note: This method is invoked on the main thread but may need to attach various
1889    // handlers to other threads.  So take care to be explicit about the looper.
1890    public ActivityManagerService(Context systemContext) {
1891        mContext = systemContext;
1892        mFactoryTest = FactoryTest.getMode();
1893        mSystemThread = ActivityThread.currentActivityThread();
1894
1895        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1896
1897        mHandlerThread = new ServiceThread(TAG,
1898                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1899        mHandlerThread.start();
1900        mHandler = new MainHandler(mHandlerThread.getLooper());
1901
1902        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1903                "foreground", BROADCAST_FG_TIMEOUT, false);
1904        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1905                "background", BROADCAST_BG_TIMEOUT, true);
1906        mBroadcastQueues[0] = mFgBroadcastQueue;
1907        mBroadcastQueues[1] = mBgBroadcastQueue;
1908
1909        mServices = new ActiveServices(this);
1910        mProviderMap = new ProviderMap(this);
1911
1912        // TODO: Move creation of battery stats service outside of activity manager service.
1913        File dataDir = Environment.getDataDirectory();
1914        File systemDir = new File(dataDir, "system");
1915        systemDir.mkdirs();
1916        mBatteryStatsService = new BatteryStatsService(new File(
1917                systemDir, "batterystats.bin").toString(), mHandler);
1918        mBatteryStatsService.getActiveStatistics().readLocked();
1919        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1920        mOnBattery = DEBUG_POWER ? true
1921                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1922        mBatteryStatsService.getActiveStatistics().setCallback(this);
1923
1924        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1925
1926        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1927        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1928
1929        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1930
1931        // User 0 is the first and only user that runs at boot.
1932        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1933        mUserLru.add(Integer.valueOf(0));
1934        updateStartedUserArrayLocked();
1935
1936        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1937            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1938
1939        mConfiguration.setToDefaults();
1940        mConfiguration.setLocale(Locale.getDefault());
1941
1942        mConfigurationSeq = mConfiguration.seq = 1;
1943        mProcessCpuTracker.init();
1944
1945        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1946        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1947        mStackSupervisor = new ActivityStackSupervisor(this);
1948
1949        mProcessCpuThread = new Thread("CpuTracker") {
1950            @Override
1951            public void run() {
1952                while (true) {
1953                    try {
1954                        try {
1955                            synchronized(this) {
1956                                final long now = SystemClock.uptimeMillis();
1957                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1958                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1959                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1960                                //        + ", write delay=" + nextWriteDelay);
1961                                if (nextWriteDelay < nextCpuDelay) {
1962                                    nextCpuDelay = nextWriteDelay;
1963                                }
1964                                if (nextCpuDelay > 0) {
1965                                    mProcessCpuMutexFree.set(true);
1966                                    this.wait(nextCpuDelay);
1967                                }
1968                            }
1969                        } catch (InterruptedException e) {
1970                        }
1971                        updateCpuStatsNow();
1972                    } catch (Exception e) {
1973                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1974                    }
1975                }
1976            }
1977        };
1978
1979        Watchdog.getInstance().addMonitor(this);
1980        Watchdog.getInstance().addThread(mHandler);
1981    }
1982
1983    private void start() {
1984        mProcessCpuThread.start();
1985
1986        mBatteryStatsService.publish(mContext);
1987        mUsageStatsService.publish(mContext);
1988        mAppOpsService.publish(mContext);
1989        startRunning(null, null, null, null);
1990    }
1991
1992    @Override
1993    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1994            throws RemoteException {
1995        if (code == SYSPROPS_TRANSACTION) {
1996            // We need to tell all apps about the system property change.
1997            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1998            synchronized(this) {
1999                final int NP = mProcessNames.getMap().size();
2000                for (int ip=0; ip<NP; ip++) {
2001                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2002                    final int NA = apps.size();
2003                    for (int ia=0; ia<NA; ia++) {
2004                        ProcessRecord app = apps.valueAt(ia);
2005                        if (app.thread != null) {
2006                            procs.add(app.thread.asBinder());
2007                        }
2008                    }
2009                }
2010            }
2011
2012            int N = procs.size();
2013            for (int i=0; i<N; i++) {
2014                Parcel data2 = Parcel.obtain();
2015                try {
2016                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2017                } catch (RemoteException e) {
2018                }
2019                data2.recycle();
2020            }
2021        }
2022        try {
2023            return super.onTransact(code, data, reply, flags);
2024        } catch (RuntimeException e) {
2025            // The activity manager only throws security exceptions, so let's
2026            // log all others.
2027            if (!(e instanceof SecurityException)) {
2028                Slog.wtf(TAG, "Activity Manager Crash", e);
2029            }
2030            throw e;
2031        }
2032    }
2033
2034    void updateCpuStats() {
2035        final long now = SystemClock.uptimeMillis();
2036        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2037            return;
2038        }
2039        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2040            synchronized (mProcessCpuThread) {
2041                mProcessCpuThread.notify();
2042            }
2043        }
2044    }
2045
2046    void updateCpuStatsNow() {
2047        synchronized (mProcessCpuThread) {
2048            mProcessCpuMutexFree.set(false);
2049            final long now = SystemClock.uptimeMillis();
2050            boolean haveNewCpuStats = false;
2051
2052            if (MONITOR_CPU_USAGE &&
2053                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2054                mLastCpuTime.set(now);
2055                haveNewCpuStats = true;
2056                mProcessCpuTracker.update();
2057                //Slog.i(TAG, mProcessCpu.printCurrentState());
2058                //Slog.i(TAG, "Total CPU usage: "
2059                //        + mProcessCpu.getTotalCpuPercent() + "%");
2060
2061                // Slog the cpu usage if the property is set.
2062                if ("true".equals(SystemProperties.get("events.cpu"))) {
2063                    int user = mProcessCpuTracker.getLastUserTime();
2064                    int system = mProcessCpuTracker.getLastSystemTime();
2065                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2066                    int irq = mProcessCpuTracker.getLastIrqTime();
2067                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2068                    int idle = mProcessCpuTracker.getLastIdleTime();
2069
2070                    int total = user + system + iowait + irq + softIrq + idle;
2071                    if (total == 0) total = 1;
2072
2073                    EventLog.writeEvent(EventLogTags.CPU,
2074                            ((user+system+iowait+irq+softIrq) * 100) / total,
2075                            (user * 100) / total,
2076                            (system * 100) / total,
2077                            (iowait * 100) / total,
2078                            (irq * 100) / total,
2079                            (softIrq * 100) / total);
2080                }
2081            }
2082
2083            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2084            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2085            synchronized(bstats) {
2086                synchronized(mPidsSelfLocked) {
2087                    if (haveNewCpuStats) {
2088                        if (mOnBattery) {
2089                            int perc = bstats.startAddingCpuLocked();
2090                            int totalUTime = 0;
2091                            int totalSTime = 0;
2092                            final int N = mProcessCpuTracker.countStats();
2093                            for (int i=0; i<N; i++) {
2094                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2095                                if (!st.working) {
2096                                    continue;
2097                                }
2098                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2099                                int otherUTime = (st.rel_utime*perc)/100;
2100                                int otherSTime = (st.rel_stime*perc)/100;
2101                                totalUTime += otherUTime;
2102                                totalSTime += otherSTime;
2103                                if (pr != null) {
2104                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
2105                                            st.name, st.pid);
2106                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2107                                            st.rel_stime-otherSTime);
2108                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2109                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2110                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
2111                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2112                                    if (ps == null) {
2113                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
2114                                                "(Unknown)");
2115                                    }
2116                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2117                                            st.rel_stime-otherSTime);
2118                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2119                                } else {
2120                                    BatteryStatsImpl.Uid.Proc ps =
2121                                            bstats.getProcessStatsLocked(st.name, st.pid);
2122                                    if (ps != null) {
2123                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2124                                                st.rel_stime-otherSTime);
2125                                        ps.addSpeedStepTimes(cpuSpeedTimes);
2126                                    }
2127                                }
2128                            }
2129                            bstats.finishAddingCpuLocked(perc, totalUTime,
2130                                    totalSTime, cpuSpeedTimes);
2131                        }
2132                    }
2133                }
2134
2135                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2136                    mLastWriteTime = now;
2137                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2138                }
2139            }
2140        }
2141    }
2142
2143    @Override
2144    public void batteryNeedsCpuUpdate() {
2145        updateCpuStatsNow();
2146    }
2147
2148    @Override
2149    public void batteryPowerChanged(boolean onBattery) {
2150        // When plugging in, update the CPU stats first before changing
2151        // the plug state.
2152        updateCpuStatsNow();
2153        synchronized (this) {
2154            synchronized(mPidsSelfLocked) {
2155                mOnBattery = DEBUG_POWER ? true : onBattery;
2156            }
2157        }
2158    }
2159
2160    /**
2161     * Initialize the application bind args. These are passed to each
2162     * process when the bindApplication() IPC is sent to the process. They're
2163     * lazily setup to make sure the services are running when they're asked for.
2164     */
2165    private HashMap<String, IBinder> getCommonServicesLocked() {
2166        if (mAppBindArgs == null) {
2167            mAppBindArgs = new HashMap<String, IBinder>();
2168
2169            // Setup the application init args
2170            mAppBindArgs.put("package", ServiceManager.getService("package"));
2171            mAppBindArgs.put("window", ServiceManager.getService("window"));
2172            mAppBindArgs.put(Context.ALARM_SERVICE,
2173                    ServiceManager.getService(Context.ALARM_SERVICE));
2174        }
2175        return mAppBindArgs;
2176    }
2177
2178    final void setFocusedActivityLocked(ActivityRecord r) {
2179        if (mFocusedActivity != r) {
2180            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2181            mFocusedActivity = r;
2182            mStackSupervisor.setFocusedStack(r);
2183            if (r != null) {
2184                mWindowManager.setFocusedApp(r.appToken, true);
2185            }
2186            applyUpdateLockStateLocked(r);
2187        }
2188    }
2189
2190    @Override
2191    public void setFocusedStack(int stackId) {
2192        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2193        synchronized (ActivityManagerService.this) {
2194            ActivityStack stack = mStackSupervisor.getStack(stackId);
2195            if (stack != null) {
2196                ActivityRecord r = stack.topRunningActivityLocked(null);
2197                if (r != null) {
2198                    setFocusedActivityLocked(r);
2199                }
2200            }
2201        }
2202    }
2203
2204    @Override
2205    public void notifyActivityDrawn(IBinder token) {
2206        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2207        synchronized (this) {
2208            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2209            if (r != null) {
2210                r.task.stack.notifyActivityDrawnLocked(r);
2211            }
2212        }
2213    }
2214
2215    final void applyUpdateLockStateLocked(ActivityRecord r) {
2216        // Modifications to the UpdateLock state are done on our handler, outside
2217        // the activity manager's locks.  The new state is determined based on the
2218        // state *now* of the relevant activity record.  The object is passed to
2219        // the handler solely for logging detail, not to be consulted/modified.
2220        final boolean nextState = r != null && r.immersive;
2221        mHandler.sendMessage(
2222                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2223    }
2224
2225    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2226        Message msg = Message.obtain();
2227        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2228        msg.obj = r.task.askedCompatMode ? null : r;
2229        mHandler.sendMessage(msg);
2230    }
2231
2232    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2233            String what, Object obj, ProcessRecord srcApp) {
2234        app.lastActivityTime = now;
2235
2236        if (app.activities.size() > 0) {
2237            // Don't want to touch dependent processes that are hosting activities.
2238            return index;
2239        }
2240
2241        int lrui = mLruProcesses.lastIndexOf(app);
2242        if (lrui < 0) {
2243            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2244                    + what + " " + obj + " from " + srcApp);
2245            return index;
2246        }
2247
2248        if (lrui >= index) {
2249            // Don't want to cause this to move dependent processes *back* in the
2250            // list as if they were less frequently used.
2251            return index;
2252        }
2253
2254        if (lrui >= mLruProcessActivityStart) {
2255            // Don't want to touch dependent processes that are hosting activities.
2256            return index;
2257        }
2258
2259        mLruProcesses.remove(lrui);
2260        if (index > 0) {
2261            index--;
2262        }
2263        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2264                + " in LRU list: " + app);
2265        mLruProcesses.add(index, app);
2266        return index;
2267    }
2268
2269    final void removeLruProcessLocked(ProcessRecord app) {
2270        int lrui = mLruProcesses.lastIndexOf(app);
2271        if (lrui >= 0) {
2272            if (lrui <= mLruProcessActivityStart) {
2273                mLruProcessActivityStart--;
2274            }
2275            if (lrui <= mLruProcessServiceStart) {
2276                mLruProcessServiceStart--;
2277            }
2278            mLruProcesses.remove(lrui);
2279        }
2280    }
2281
2282    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2283            ProcessRecord client) {
2284        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2285        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2286        if (!activityChange && hasActivity) {
2287            // The process has activties, so we are only going to allow activity-based
2288            // adjustments move it.  It should be kept in the front of the list with other
2289            // processes that have activities, and we don't want those to change their
2290            // order except due to activity operations.
2291            return;
2292        }
2293
2294        mLruSeq++;
2295        final long now = SystemClock.uptimeMillis();
2296        app.lastActivityTime = now;
2297
2298        // First a quick reject: if the app is already at the position we will
2299        // put it, then there is nothing to do.
2300        if (hasActivity) {
2301            final int N = mLruProcesses.size();
2302            if (N > 0 && mLruProcesses.get(N-1) == app) {
2303                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2304                return;
2305            }
2306        } else {
2307            if (mLruProcessServiceStart > 0
2308                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2309                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2310                return;
2311            }
2312        }
2313
2314        int lrui = mLruProcesses.lastIndexOf(app);
2315
2316        if (app.persistent && lrui >= 0) {
2317            // We don't care about the position of persistent processes, as long as
2318            // they are in the list.
2319            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2320            return;
2321        }
2322
2323        /* In progress: compute new position first, so we can avoid doing work
2324           if the process is not actually going to move.  Not yet working.
2325        int addIndex;
2326        int nextIndex;
2327        boolean inActivity = false, inService = false;
2328        if (hasActivity) {
2329            // Process has activities, put it at the very tipsy-top.
2330            addIndex = mLruProcesses.size();
2331            nextIndex = mLruProcessServiceStart;
2332            inActivity = true;
2333        } else if (hasService) {
2334            // Process has services, put it at the top of the service list.
2335            addIndex = mLruProcessActivityStart;
2336            nextIndex = mLruProcessServiceStart;
2337            inActivity = true;
2338            inService = true;
2339        } else  {
2340            // Process not otherwise of interest, it goes to the top of the non-service area.
2341            addIndex = mLruProcessServiceStart;
2342            if (client != null) {
2343                int clientIndex = mLruProcesses.lastIndexOf(client);
2344                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2345                        + app);
2346                if (clientIndex >= 0 && addIndex > clientIndex) {
2347                    addIndex = clientIndex;
2348                }
2349            }
2350            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2351        }
2352
2353        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2354                + mLruProcessActivityStart + "): " + app);
2355        */
2356
2357        if (lrui >= 0) {
2358            if (lrui < mLruProcessActivityStart) {
2359                mLruProcessActivityStart--;
2360            }
2361            if (lrui < mLruProcessServiceStart) {
2362                mLruProcessServiceStart--;
2363            }
2364            /*
2365            if (addIndex > lrui) {
2366                addIndex--;
2367            }
2368            if (nextIndex > lrui) {
2369                nextIndex--;
2370            }
2371            */
2372            mLruProcesses.remove(lrui);
2373        }
2374
2375        /*
2376        mLruProcesses.add(addIndex, app);
2377        if (inActivity) {
2378            mLruProcessActivityStart++;
2379        }
2380        if (inService) {
2381            mLruProcessActivityStart++;
2382        }
2383        */
2384
2385        int nextIndex;
2386        if (hasActivity) {
2387            final int N = mLruProcesses.size();
2388            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2389                // Process doesn't have activities, but has clients with
2390                // activities...  move it up, but one below the top (the top
2391                // should always have a real activity).
2392                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2393                mLruProcesses.add(N-1, app);
2394                // To keep it from spamming the LRU list (by making a bunch of clients),
2395                // we will push down any other entries owned by the app.
2396                final int uid = app.info.uid;
2397                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2398                    ProcessRecord subProc = mLruProcesses.get(i);
2399                    if (subProc.info.uid == uid) {
2400                        // We want to push this one down the list.  If the process after
2401                        // it is for the same uid, however, don't do so, because we don't
2402                        // want them internally to be re-ordered.
2403                        if (mLruProcesses.get(i-1).info.uid != uid) {
2404                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2405                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2406                            ProcessRecord tmp = mLruProcesses.get(i);
2407                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2408                            mLruProcesses.set(i-1, tmp);
2409                            i--;
2410                        }
2411                    } else {
2412                        // A gap, we can stop here.
2413                        break;
2414                    }
2415                }
2416            } else {
2417                // Process has activities, put it at the very tipsy-top.
2418                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2419                mLruProcesses.add(app);
2420            }
2421            nextIndex = mLruProcessServiceStart;
2422        } else if (hasService) {
2423            // Process has services, put it at the top of the service list.
2424            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2425            mLruProcesses.add(mLruProcessActivityStart, app);
2426            nextIndex = mLruProcessServiceStart;
2427            mLruProcessActivityStart++;
2428        } else  {
2429            // Process not otherwise of interest, it goes to the top of the non-service area.
2430            int index = mLruProcessServiceStart;
2431            if (client != null) {
2432                // If there is a client, don't allow the process to be moved up higher
2433                // in the list than that client.
2434                int clientIndex = mLruProcesses.lastIndexOf(client);
2435                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2436                        + " when updating " + app);
2437                if (clientIndex <= lrui) {
2438                    // Don't allow the client index restriction to push it down farther in the
2439                    // list than it already is.
2440                    clientIndex = lrui;
2441                }
2442                if (clientIndex >= 0 && index > clientIndex) {
2443                    index = clientIndex;
2444                }
2445            }
2446            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2447            mLruProcesses.add(index, app);
2448            nextIndex = index-1;
2449            mLruProcessActivityStart++;
2450            mLruProcessServiceStart++;
2451        }
2452
2453        // If the app is currently using a content provider or service,
2454        // bump those processes as well.
2455        for (int j=app.connections.size()-1; j>=0; j--) {
2456            ConnectionRecord cr = app.connections.valueAt(j);
2457            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2458                    && cr.binding.service.app != null
2459                    && cr.binding.service.app.lruSeq != mLruSeq
2460                    && !cr.binding.service.app.persistent) {
2461                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2462                        "service connection", cr, app);
2463            }
2464        }
2465        for (int j=app.conProviders.size()-1; j>=0; j--) {
2466            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2467            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2468                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2469                        "provider reference", cpr, app);
2470            }
2471        }
2472    }
2473
2474    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2475        if (uid == Process.SYSTEM_UID) {
2476            // The system gets to run in any process.  If there are multiple
2477            // processes with the same uid, just pick the first (this
2478            // should never happen).
2479            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2480            if (procs == null) return null;
2481            final int N = procs.size();
2482            for (int i = 0; i < N; i++) {
2483                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2484            }
2485        }
2486        ProcessRecord proc = mProcessNames.get(processName, uid);
2487        if (false && proc != null && !keepIfLarge
2488                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2489                && proc.lastCachedPss >= 4000) {
2490            // Turn this condition on to cause killing to happen regularly, for testing.
2491            if (proc.baseProcessTracker != null) {
2492                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2493            }
2494            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2495                    + "k from cached");
2496        } else if (proc != null && !keepIfLarge
2497                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2498                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2499            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2500            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2501                if (proc.baseProcessTracker != null) {
2502                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2503                }
2504                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2505                        + "k from cached");
2506            }
2507        }
2508        return proc;
2509    }
2510
2511    void ensurePackageDexOpt(String packageName) {
2512        IPackageManager pm = AppGlobals.getPackageManager();
2513        try {
2514            if (pm.performDexOpt(packageName)) {
2515                mDidDexOpt = true;
2516            }
2517        } catch (RemoteException e) {
2518        }
2519    }
2520
2521    boolean isNextTransitionForward() {
2522        int transit = mWindowManager.getPendingAppTransition();
2523        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2524                || transit == AppTransition.TRANSIT_TASK_OPEN
2525                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2526    }
2527
2528    final ProcessRecord startProcessLocked(String processName,
2529            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2530            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2531            boolean isolated, boolean keepIfLarge) {
2532        ProcessRecord app;
2533        if (!isolated) {
2534            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2535        } else {
2536            // If this is an isolated process, it can't re-use an existing process.
2537            app = null;
2538        }
2539        // We don't have to do anything more if:
2540        // (1) There is an existing application record; and
2541        // (2) The caller doesn't think it is dead, OR there is no thread
2542        //     object attached to it so we know it couldn't have crashed; and
2543        // (3) There is a pid assigned to it, so it is either starting or
2544        //     already running.
2545        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2546                + " app=" + app + " knownToBeDead=" + knownToBeDead
2547                + " thread=" + (app != null ? app.thread : null)
2548                + " pid=" + (app != null ? app.pid : -1));
2549        if (app != null && app.pid > 0) {
2550            if (!knownToBeDead || app.thread == null) {
2551                // We already have the app running, or are waiting for it to
2552                // come up (we have a pid but not yet its thread), so keep it.
2553                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2554                // If this is a new package in the process, add the package to the list
2555                app.addPackage(info.packageName, mProcessStats);
2556                return app;
2557            }
2558
2559            // An application record is attached to a previous process,
2560            // clean it up now.
2561            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2562            handleAppDiedLocked(app, true, true);
2563        }
2564
2565        String hostingNameStr = hostingName != null
2566                ? hostingName.flattenToShortString() : null;
2567
2568        if (!isolated) {
2569            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2570                // If we are in the background, then check to see if this process
2571                // is bad.  If so, we will just silently fail.
2572                if (mBadProcesses.get(info.processName, info.uid) != null) {
2573                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2574                            + "/" + info.processName);
2575                    return null;
2576                }
2577            } else {
2578                // When the user is explicitly starting a process, then clear its
2579                // crash count so that we won't make it bad until they see at
2580                // least one crash dialog again, and make the process good again
2581                // if it had been bad.
2582                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2583                        + "/" + info.processName);
2584                mProcessCrashTimes.remove(info.processName, info.uid);
2585                if (mBadProcesses.get(info.processName, info.uid) != null) {
2586                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2587                            UserHandle.getUserId(info.uid), info.uid,
2588                            info.processName);
2589                    mBadProcesses.remove(info.processName, info.uid);
2590                    if (app != null) {
2591                        app.bad = false;
2592                    }
2593                }
2594            }
2595        }
2596
2597        if (app == null) {
2598            app = newProcessRecordLocked(info, processName, isolated);
2599            if (app == null) {
2600                Slog.w(TAG, "Failed making new process record for "
2601                        + processName + "/" + info.uid + " isolated=" + isolated);
2602                return null;
2603            }
2604            mProcessNames.put(processName, app.uid, app);
2605            if (isolated) {
2606                mIsolatedProcesses.put(app.uid, app);
2607            }
2608        } else {
2609            // If this is a new package in the process, add the package to the list
2610            app.addPackage(info.packageName, mProcessStats);
2611        }
2612
2613        // If the system is not ready yet, then hold off on starting this
2614        // process until it is.
2615        if (!mProcessesReady
2616                && !isAllowedWhileBooting(info)
2617                && !allowWhileBooting) {
2618            if (!mProcessesOnHold.contains(app)) {
2619                mProcessesOnHold.add(app);
2620            }
2621            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2622            return app;
2623        }
2624
2625        startProcessLocked(app, hostingType, hostingNameStr);
2626        return (app.pid != 0) ? app : null;
2627    }
2628
2629    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2630        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2631    }
2632
2633    private final void startProcessLocked(ProcessRecord app,
2634            String hostingType, String hostingNameStr) {
2635        if (app.pid > 0 && app.pid != MY_PID) {
2636            synchronized (mPidsSelfLocked) {
2637                mPidsSelfLocked.remove(app.pid);
2638                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2639            }
2640            app.setPid(0);
2641        }
2642
2643        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2644                "startProcessLocked removing on hold: " + app);
2645        mProcessesOnHold.remove(app);
2646
2647        updateCpuStats();
2648
2649        try {
2650            int uid = app.uid;
2651
2652            int[] gids = null;
2653            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2654            if (!app.isolated) {
2655                int[] permGids = null;
2656                try {
2657                    final PackageManager pm = mContext.getPackageManager();
2658                    permGids = pm.getPackageGids(app.info.packageName);
2659
2660                    if (Environment.isExternalStorageEmulated()) {
2661                        if (pm.checkPermission(
2662                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2663                                app.info.packageName) == PERMISSION_GRANTED) {
2664                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2665                        } else {
2666                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2667                        }
2668                    }
2669                } catch (PackageManager.NameNotFoundException e) {
2670                    Slog.w(TAG, "Unable to retrieve gids", e);
2671                }
2672
2673                /*
2674                 * Add shared application GID so applications can share some
2675                 * resources like shared libraries
2676                 */
2677                if (permGids == null) {
2678                    gids = new int[1];
2679                } else {
2680                    gids = new int[permGids.length + 1];
2681                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2682                }
2683                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2684            }
2685            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2686                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2687                        && mTopComponent != null
2688                        && app.processName.equals(mTopComponent.getPackageName())) {
2689                    uid = 0;
2690                }
2691                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2692                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2693                    uid = 0;
2694                }
2695            }
2696            int debugFlags = 0;
2697            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2698                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2699                // Also turn on CheckJNI for debuggable apps. It's quite
2700                // awkward to turn on otherwise.
2701                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2702            }
2703            // Run the app in safe mode if its manifest requests so or the
2704            // system is booted in safe mode.
2705            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2706                Zygote.systemInSafeMode == true) {
2707                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2708            }
2709            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2710                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2711            }
2712            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2713                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2714            }
2715            if ("1".equals(SystemProperties.get("debug.assert"))) {
2716                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2717            }
2718
2719            // Start the process.  It will either succeed and return a result containing
2720            // the PID of the new process, or else throw a RuntimeException.
2721            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2722                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2723                    app.info.targetSdkVersion, app.info.seinfo, null);
2724
2725            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2726            synchronized (bs) {
2727                if (bs.isOnBattery()) {
2728                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2729                }
2730            }
2731
2732            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2733                    UserHandle.getUserId(uid), startResult.pid, uid,
2734                    app.processName, hostingType,
2735                    hostingNameStr != null ? hostingNameStr : "");
2736
2737            if (app.persistent) {
2738                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2739            }
2740
2741            StringBuilder buf = mStringBuilder;
2742            buf.setLength(0);
2743            buf.append("Start proc ");
2744            buf.append(app.processName);
2745            buf.append(" for ");
2746            buf.append(hostingType);
2747            if (hostingNameStr != null) {
2748                buf.append(" ");
2749                buf.append(hostingNameStr);
2750            }
2751            buf.append(": pid=");
2752            buf.append(startResult.pid);
2753            buf.append(" uid=");
2754            buf.append(uid);
2755            buf.append(" gids={");
2756            if (gids != null) {
2757                for (int gi=0; gi<gids.length; gi++) {
2758                    if (gi != 0) buf.append(", ");
2759                    buf.append(gids[gi]);
2760
2761                }
2762            }
2763            buf.append("}");
2764            Slog.i(TAG, buf.toString());
2765            app.setPid(startResult.pid);
2766            app.usingWrapper = startResult.usingWrapper;
2767            app.removed = false;
2768            synchronized (mPidsSelfLocked) {
2769                this.mPidsSelfLocked.put(startResult.pid, app);
2770                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2771                msg.obj = app;
2772                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2773                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2774            }
2775        } catch (RuntimeException e) {
2776            // XXX do better error recovery.
2777            app.setPid(0);
2778            Slog.e(TAG, "Failure starting process " + app.processName, e);
2779        }
2780    }
2781
2782    void updateUsageStats(ActivityRecord component, boolean resumed) {
2783        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2784        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2785        if (resumed) {
2786            mUsageStatsService.noteResumeComponent(component.realActivity);
2787            synchronized (stats) {
2788                stats.noteActivityResumedLocked(component.app.uid);
2789            }
2790        } else {
2791            mUsageStatsService.notePauseComponent(component.realActivity);
2792            synchronized (stats) {
2793                stats.noteActivityPausedLocked(component.app.uid);
2794            }
2795        }
2796    }
2797
2798    Intent getHomeIntent() {
2799        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2800        intent.setComponent(mTopComponent);
2801        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2802            intent.addCategory(Intent.CATEGORY_HOME);
2803        }
2804        return intent;
2805    }
2806
2807    boolean startHomeActivityLocked(int userId) {
2808        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2809                && mTopAction == null) {
2810            // We are running in factory test mode, but unable to find
2811            // the factory test app, so just sit around displaying the
2812            // error message and don't try to start anything.
2813            return false;
2814        }
2815        Intent intent = getHomeIntent();
2816        ActivityInfo aInfo =
2817            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2818        if (aInfo != null) {
2819            intent.setComponent(new ComponentName(
2820                    aInfo.applicationInfo.packageName, aInfo.name));
2821            // Don't do this if the home app is currently being
2822            // instrumented.
2823            aInfo = new ActivityInfo(aInfo);
2824            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2825            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2826                    aInfo.applicationInfo.uid, true);
2827            if (app == null || app.instrumentationClass == null) {
2828                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2829                mStackSupervisor.startHomeActivity(intent, aInfo);
2830            }
2831        }
2832
2833        return true;
2834    }
2835
2836    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2837        ActivityInfo ai = null;
2838        ComponentName comp = intent.getComponent();
2839        try {
2840            if (comp != null) {
2841                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2842            } else {
2843                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2844                        intent,
2845                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2846                            flags, userId);
2847
2848                if (info != null) {
2849                    ai = info.activityInfo;
2850                }
2851            }
2852        } catch (RemoteException e) {
2853            // ignore
2854        }
2855
2856        return ai;
2857    }
2858
2859    /**
2860     * Starts the "new version setup screen" if appropriate.
2861     */
2862    void startSetupActivityLocked() {
2863        // Only do this once per boot.
2864        if (mCheckedForSetup) {
2865            return;
2866        }
2867
2868        // We will show this screen if the current one is a different
2869        // version than the last one shown, and we are not running in
2870        // low-level factory test mode.
2871        final ContentResolver resolver = mContext.getContentResolver();
2872        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2873                Settings.Global.getInt(resolver,
2874                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2875            mCheckedForSetup = true;
2876
2877            // See if we should be showing the platform update setup UI.
2878            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2879            List<ResolveInfo> ris = mContext.getPackageManager()
2880                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2881
2882            // We don't allow third party apps to replace this.
2883            ResolveInfo ri = null;
2884            for (int i=0; ris != null && i<ris.size(); i++) {
2885                if ((ris.get(i).activityInfo.applicationInfo.flags
2886                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2887                    ri = ris.get(i);
2888                    break;
2889                }
2890            }
2891
2892            if (ri != null) {
2893                String vers = ri.activityInfo.metaData != null
2894                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2895                        : null;
2896                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2897                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2898                            Intent.METADATA_SETUP_VERSION);
2899                }
2900                String lastVers = Settings.Secure.getString(
2901                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2902                if (vers != null && !vers.equals(lastVers)) {
2903                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2904                    intent.setComponent(new ComponentName(
2905                            ri.activityInfo.packageName, ri.activityInfo.name));
2906                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2907                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2908                }
2909            }
2910        }
2911    }
2912
2913    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2914        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2915    }
2916
2917    void enforceNotIsolatedCaller(String caller) {
2918        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2919            throw new SecurityException("Isolated process not allowed to call " + caller);
2920        }
2921    }
2922
2923    @Override
2924    public int getFrontActivityScreenCompatMode() {
2925        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2926        synchronized (this) {
2927            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2928        }
2929    }
2930
2931    @Override
2932    public void setFrontActivityScreenCompatMode(int mode) {
2933        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2934                "setFrontActivityScreenCompatMode");
2935        synchronized (this) {
2936            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2937        }
2938    }
2939
2940    @Override
2941    public int getPackageScreenCompatMode(String packageName) {
2942        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2943        synchronized (this) {
2944            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2945        }
2946    }
2947
2948    @Override
2949    public void setPackageScreenCompatMode(String packageName, int mode) {
2950        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2951                "setPackageScreenCompatMode");
2952        synchronized (this) {
2953            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2954        }
2955    }
2956
2957    @Override
2958    public boolean getPackageAskScreenCompat(String packageName) {
2959        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2960        synchronized (this) {
2961            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2962        }
2963    }
2964
2965    @Override
2966    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2967        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2968                "setPackageAskScreenCompat");
2969        synchronized (this) {
2970            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2971        }
2972    }
2973
2974    private void dispatchProcessesChanged() {
2975        int N;
2976        synchronized (this) {
2977            N = mPendingProcessChanges.size();
2978            if (mActiveProcessChanges.length < N) {
2979                mActiveProcessChanges = new ProcessChangeItem[N];
2980            }
2981            mPendingProcessChanges.toArray(mActiveProcessChanges);
2982            mAvailProcessChanges.addAll(mPendingProcessChanges);
2983            mPendingProcessChanges.clear();
2984            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2985        }
2986
2987        int i = mProcessObservers.beginBroadcast();
2988        while (i > 0) {
2989            i--;
2990            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2991            if (observer != null) {
2992                try {
2993                    for (int j=0; j<N; j++) {
2994                        ProcessChangeItem item = mActiveProcessChanges[j];
2995                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2996                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2997                                    + item.pid + " uid=" + item.uid + ": "
2998                                    + item.foregroundActivities);
2999                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3000                                    item.foregroundActivities);
3001                        }
3002                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3003                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3004                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3005                            observer.onImportanceChanged(item.pid, item.uid,
3006                                    item.importance);
3007                        }
3008                    }
3009                } catch (RemoteException e) {
3010                }
3011            }
3012        }
3013        mProcessObservers.finishBroadcast();
3014    }
3015
3016    private void dispatchProcessDied(int pid, int uid) {
3017        int i = mProcessObservers.beginBroadcast();
3018        while (i > 0) {
3019            i--;
3020            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3021            if (observer != null) {
3022                try {
3023                    observer.onProcessDied(pid, uid);
3024                } catch (RemoteException e) {
3025                }
3026            }
3027        }
3028        mProcessObservers.finishBroadcast();
3029    }
3030
3031    final void doPendingActivityLaunchesLocked(boolean doResume) {
3032        final int N = mPendingActivityLaunches.size();
3033        if (N <= 0) {
3034            return;
3035        }
3036        for (int i=0; i<N; i++) {
3037            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3038            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3039                    doResume && i == (N-1), null);
3040        }
3041        mPendingActivityLaunches.clear();
3042    }
3043
3044    @Override
3045    public final int startActivity(IApplicationThread caller, String callingPackage,
3046            Intent intent, String resolvedType, IBinder resultTo,
3047            String resultWho, int requestCode, int startFlags,
3048            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3049        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3050                resultWho, requestCode,
3051                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3052    }
3053
3054    @Override
3055    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3056            Intent intent, String resolvedType, IBinder resultTo,
3057            String resultWho, int requestCode, int startFlags,
3058            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3059        enforceNotIsolatedCaller("startActivity");
3060        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3061                false, true, "startActivity", null);
3062        // TODO: Switch to user app stacks here.
3063        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3064                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3065                null, null, options, userId, null);
3066    }
3067
3068    @Override
3069    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3070            Intent intent, String resolvedType, IBinder resultTo,
3071            String resultWho, int requestCode, int startFlags, String profileFile,
3072            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3073        enforceNotIsolatedCaller("startActivityAndWait");
3074        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3075                false, true, "startActivityAndWait", null);
3076        WaitResult res = new WaitResult();
3077        // TODO: Switch to user app stacks here.
3078        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3079                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3080                res, null, options, UserHandle.getCallingUserId(), null);
3081        return res;
3082    }
3083
3084    @Override
3085    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3086            Intent intent, String resolvedType, IBinder resultTo,
3087            String resultWho, int requestCode, int startFlags, Configuration config,
3088            Bundle options, int userId) {
3089        enforceNotIsolatedCaller("startActivityWithConfig");
3090        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3091                false, true, "startActivityWithConfig", null);
3092        // TODO: Switch to user app stacks here.
3093        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3094                resolvedType, resultTo, resultWho, requestCode, startFlags,
3095                null, null, null, config, options, userId, null);
3096        return ret;
3097    }
3098
3099    @Override
3100    public int startActivityIntentSender(IApplicationThread caller,
3101            IntentSender intent, Intent fillInIntent, String resolvedType,
3102            IBinder resultTo, String resultWho, int requestCode,
3103            int flagsMask, int flagsValues, Bundle options) {
3104        enforceNotIsolatedCaller("startActivityIntentSender");
3105        // Refuse possible leaked file descriptors
3106        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3107            throw new IllegalArgumentException("File descriptors passed in Intent");
3108        }
3109
3110        IIntentSender sender = intent.getTarget();
3111        if (!(sender instanceof PendingIntentRecord)) {
3112            throw new IllegalArgumentException("Bad PendingIntent object");
3113        }
3114
3115        PendingIntentRecord pir = (PendingIntentRecord)sender;
3116
3117        synchronized (this) {
3118            // If this is coming from the currently resumed activity, it is
3119            // effectively saying that app switches are allowed at this point.
3120            final ActivityStack stack = getFocusedStack();
3121            if (stack.mResumedActivity != null &&
3122                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3123                mAppSwitchesAllowedTime = 0;
3124            }
3125        }
3126        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3127                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3128        return ret;
3129    }
3130
3131    @Override
3132    public boolean startNextMatchingActivity(IBinder callingActivity,
3133            Intent intent, Bundle options) {
3134        // Refuse possible leaked file descriptors
3135        if (intent != null && intent.hasFileDescriptors() == true) {
3136            throw new IllegalArgumentException("File descriptors passed in Intent");
3137        }
3138
3139        synchronized (this) {
3140            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3141            if (r == null) {
3142                ActivityOptions.abort(options);
3143                return false;
3144            }
3145            if (r.app == null || r.app.thread == null) {
3146                // The caller is not running...  d'oh!
3147                ActivityOptions.abort(options);
3148                return false;
3149            }
3150            intent = new Intent(intent);
3151            // The caller is not allowed to change the data.
3152            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3153            // And we are resetting to find the next component...
3154            intent.setComponent(null);
3155
3156            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3157
3158            ActivityInfo aInfo = null;
3159            try {
3160                List<ResolveInfo> resolves =
3161                    AppGlobals.getPackageManager().queryIntentActivities(
3162                            intent, r.resolvedType,
3163                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3164                            UserHandle.getCallingUserId());
3165
3166                // Look for the original activity in the list...
3167                final int N = resolves != null ? resolves.size() : 0;
3168                for (int i=0; i<N; i++) {
3169                    ResolveInfo rInfo = resolves.get(i);
3170                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3171                            && rInfo.activityInfo.name.equals(r.info.name)) {
3172                        // We found the current one...  the next matching is
3173                        // after it.
3174                        i++;
3175                        if (i<N) {
3176                            aInfo = resolves.get(i).activityInfo;
3177                        }
3178                        if (debug) {
3179                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3180                                    + "/" + r.info.name);
3181                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3182                                    + "/" + aInfo.name);
3183                        }
3184                        break;
3185                    }
3186                }
3187            } catch (RemoteException e) {
3188            }
3189
3190            if (aInfo == null) {
3191                // Nobody who is next!
3192                ActivityOptions.abort(options);
3193                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3194                return false;
3195            }
3196
3197            intent.setComponent(new ComponentName(
3198                    aInfo.applicationInfo.packageName, aInfo.name));
3199            intent.setFlags(intent.getFlags()&~(
3200                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3201                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3202                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3203                    Intent.FLAG_ACTIVITY_NEW_TASK));
3204
3205            // Okay now we need to start the new activity, replacing the
3206            // currently running activity.  This is a little tricky because
3207            // we want to start the new one as if the current one is finished,
3208            // but not finish the current one first so that there is no flicker.
3209            // And thus...
3210            final boolean wasFinishing = r.finishing;
3211            r.finishing = true;
3212
3213            // Propagate reply information over to the new activity.
3214            final ActivityRecord resultTo = r.resultTo;
3215            final String resultWho = r.resultWho;
3216            final int requestCode = r.requestCode;
3217            r.resultTo = null;
3218            if (resultTo != null) {
3219                resultTo.removeResultsLocked(r, resultWho, requestCode);
3220            }
3221
3222            final long origId = Binder.clearCallingIdentity();
3223            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3224                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3225                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3226                    options, false, null, null);
3227            Binder.restoreCallingIdentity(origId);
3228
3229            r.finishing = wasFinishing;
3230            if (res != ActivityManager.START_SUCCESS) {
3231                return false;
3232            }
3233            return true;
3234        }
3235    }
3236
3237    final int startActivityInPackage(int uid, String callingPackage,
3238            Intent intent, String resolvedType, IBinder resultTo,
3239            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3240                    IActivityContainer container) {
3241
3242        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3243                false, true, "startActivityInPackage", null);
3244
3245        // TODO: Switch to user app stacks here.
3246        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3247                resultTo, resultWho, requestCode, startFlags,
3248                null, null, null, null, options, userId, container);
3249        return ret;
3250    }
3251
3252    @Override
3253    public final int startActivities(IApplicationThread caller, String callingPackage,
3254            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3255            int userId) {
3256        enforceNotIsolatedCaller("startActivities");
3257        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3258                false, true, "startActivity", null);
3259        // TODO: Switch to user app stacks here.
3260        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3261                resolvedTypes, resultTo, options, userId);
3262        return ret;
3263    }
3264
3265    final int startActivitiesInPackage(int uid, String callingPackage,
3266            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3267            Bundle options, int userId) {
3268
3269        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3270                false, true, "startActivityInPackage", null);
3271        // TODO: Switch to user app stacks here.
3272        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3273                resultTo, options, userId);
3274        return ret;
3275    }
3276
3277    final void addRecentTaskLocked(TaskRecord task) {
3278        int N = mRecentTasks.size();
3279        // Quick case: check if the top-most recent task is the same.
3280        if (N > 0 && mRecentTasks.get(0) == task) {
3281            return;
3282        }
3283        // Remove any existing entries that are the same kind of task.
3284        for (int i=0; i<N; i++) {
3285            TaskRecord tr = mRecentTasks.get(i);
3286            if (task.userId == tr.userId
3287                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3288                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3289                tr.disposeThumbnail();
3290                mRecentTasks.remove(i);
3291                i--;
3292                N--;
3293                if (task.intent == null) {
3294                    // If the new recent task we are adding is not fully
3295                    // specified, then replace it with the existing recent task.
3296                    task = tr;
3297                }
3298            }
3299        }
3300        if (N >= MAX_RECENT_TASKS) {
3301            mRecentTasks.remove(N-1).disposeThumbnail();
3302        }
3303        mRecentTasks.add(0, task);
3304    }
3305
3306    @Override
3307    public void reportActivityFullyDrawn(IBinder token) {
3308        synchronized (this) {
3309            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3310            if (r == null) {
3311                return;
3312            }
3313            r.reportFullyDrawnLocked();
3314        }
3315    }
3316
3317    @Override
3318    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3319        synchronized (this) {
3320            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3321            if (r == null) {
3322                return;
3323            }
3324            final long origId = Binder.clearCallingIdentity();
3325            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3326            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3327                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3328            if (config != null) {
3329                r.frozenBeforeDestroy = true;
3330                if (!updateConfigurationLocked(config, r, false, false)) {
3331                    mStackSupervisor.resumeTopActivitiesLocked();
3332                }
3333            }
3334            Binder.restoreCallingIdentity(origId);
3335        }
3336    }
3337
3338    @Override
3339    public int getRequestedOrientation(IBinder token) {
3340        synchronized (this) {
3341            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3342            if (r == null) {
3343                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3344            }
3345            return mWindowManager.getAppOrientation(r.appToken);
3346        }
3347    }
3348
3349    /**
3350     * This is the internal entry point for handling Activity.finish().
3351     *
3352     * @param token The Binder token referencing the Activity we want to finish.
3353     * @param resultCode Result code, if any, from this Activity.
3354     * @param resultData Result data (Intent), if any, from this Activity.
3355     *
3356     * @return Returns true if the activity successfully finished, or false if it is still running.
3357     */
3358    @Override
3359    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3360        // Refuse possible leaked file descriptors
3361        if (resultData != null && resultData.hasFileDescriptors() == true) {
3362            throw new IllegalArgumentException("File descriptors passed in Intent");
3363        }
3364
3365        synchronized(this) {
3366            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3367            if (r == null) {
3368                return true;
3369            }
3370            if (mController != null) {
3371                // Find the first activity that is not finishing.
3372                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3373                if (next != null) {
3374                    // ask watcher if this is allowed
3375                    boolean resumeOK = true;
3376                    try {
3377                        resumeOK = mController.activityResuming(next.packageName);
3378                    } catch (RemoteException e) {
3379                        mController = null;
3380                        Watchdog.getInstance().setActivityController(null);
3381                    }
3382
3383                    if (!resumeOK) {
3384                        return false;
3385                    }
3386                }
3387            }
3388            final long origId = Binder.clearCallingIdentity();
3389            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3390                    resultData, "app-request", true);
3391            Binder.restoreCallingIdentity(origId);
3392            return res;
3393        }
3394    }
3395
3396    @Override
3397    public final void finishHeavyWeightApp() {
3398        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3399                != PackageManager.PERMISSION_GRANTED) {
3400            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3401                    + Binder.getCallingPid()
3402                    + ", uid=" + Binder.getCallingUid()
3403                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3404            Slog.w(TAG, msg);
3405            throw new SecurityException(msg);
3406        }
3407
3408        synchronized(this) {
3409            if (mHeavyWeightProcess == null) {
3410                return;
3411            }
3412
3413            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3414                    mHeavyWeightProcess.activities);
3415            for (int i=0; i<activities.size(); i++) {
3416                ActivityRecord r = activities.get(i);
3417                if (!r.finishing) {
3418                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3419                            null, "finish-heavy", true);
3420                }
3421            }
3422
3423            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3424                    mHeavyWeightProcess.userId, 0));
3425            mHeavyWeightProcess = null;
3426        }
3427    }
3428
3429    @Override
3430    public void crashApplication(int uid, int initialPid, String packageName,
3431            String message) {
3432        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3433                != PackageManager.PERMISSION_GRANTED) {
3434            String msg = "Permission Denial: crashApplication() from pid="
3435                    + Binder.getCallingPid()
3436                    + ", uid=" + Binder.getCallingUid()
3437                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3438            Slog.w(TAG, msg);
3439            throw new SecurityException(msg);
3440        }
3441
3442        synchronized(this) {
3443            ProcessRecord proc = null;
3444
3445            // Figure out which process to kill.  We don't trust that initialPid
3446            // still has any relation to current pids, so must scan through the
3447            // list.
3448            synchronized (mPidsSelfLocked) {
3449                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3450                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3451                    if (p.uid != uid) {
3452                        continue;
3453                    }
3454                    if (p.pid == initialPid) {
3455                        proc = p;
3456                        break;
3457                    }
3458                    if (p.pkgList.containsKey(packageName)) {
3459                        proc = p;
3460                    }
3461                }
3462            }
3463
3464            if (proc == null) {
3465                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3466                        + " initialPid=" + initialPid
3467                        + " packageName=" + packageName);
3468                return;
3469            }
3470
3471            if (proc.thread != null) {
3472                if (proc.pid == Process.myPid()) {
3473                    Log.w(TAG, "crashApplication: trying to crash self!");
3474                    return;
3475                }
3476                long ident = Binder.clearCallingIdentity();
3477                try {
3478                    proc.thread.scheduleCrash(message);
3479                } catch (RemoteException e) {
3480                }
3481                Binder.restoreCallingIdentity(ident);
3482            }
3483        }
3484    }
3485
3486    @Override
3487    public final void finishSubActivity(IBinder token, String resultWho,
3488            int requestCode) {
3489        synchronized(this) {
3490            final long origId = Binder.clearCallingIdentity();
3491            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3492            if (r != null) {
3493                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3494            }
3495            Binder.restoreCallingIdentity(origId);
3496        }
3497    }
3498
3499    @Override
3500    public boolean finishActivityAffinity(IBinder token) {
3501        synchronized(this) {
3502            final long origId = Binder.clearCallingIdentity();
3503            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3504            boolean res = false;
3505            if (r != null) {
3506                res = r.task.stack.finishActivityAffinityLocked(r);
3507            }
3508            Binder.restoreCallingIdentity(origId);
3509            return res;
3510        }
3511    }
3512
3513    @Override
3514    public boolean willActivityBeVisible(IBinder token) {
3515        synchronized(this) {
3516            ActivityStack stack = ActivityRecord.getStackLocked(token);
3517            if (stack != null) {
3518                return stack.willActivityBeVisibleLocked(token);
3519            }
3520            return false;
3521        }
3522    }
3523
3524    @Override
3525    public void overridePendingTransition(IBinder token, String packageName,
3526            int enterAnim, int exitAnim) {
3527        synchronized(this) {
3528            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3529            if (self == null) {
3530                return;
3531            }
3532
3533            final long origId = Binder.clearCallingIdentity();
3534
3535            if (self.state == ActivityState.RESUMED
3536                    || self.state == ActivityState.PAUSING) {
3537                mWindowManager.overridePendingAppTransition(packageName,
3538                        enterAnim, exitAnim, null);
3539            }
3540
3541            Binder.restoreCallingIdentity(origId);
3542        }
3543    }
3544
3545    /**
3546     * Main function for removing an existing process from the activity manager
3547     * as a result of that process going away.  Clears out all connections
3548     * to the process.
3549     */
3550    private final void handleAppDiedLocked(ProcessRecord app,
3551            boolean restarting, boolean allowRestart) {
3552        int pid = app.pid;
3553        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3554        if (!restarting) {
3555            removeLruProcessLocked(app);
3556            if (pid > 0) {
3557                ProcessList.remove(pid);
3558            }
3559        }
3560
3561        if (mProfileProc == app) {
3562            clearProfilerLocked();
3563        }
3564
3565        // Remove this application's activities from active lists.
3566        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3567
3568        app.activities.clear();
3569
3570        if (app.instrumentationClass != null) {
3571            Slog.w(TAG, "Crash of app " + app.processName
3572                  + " running instrumentation " + app.instrumentationClass);
3573            Bundle info = new Bundle();
3574            info.putString("shortMsg", "Process crashed.");
3575            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3576        }
3577
3578        if (!restarting) {
3579            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3580                // If there was nothing to resume, and we are not already
3581                // restarting this process, but there is a visible activity that
3582                // is hosted by the process...  then make sure all visible
3583                // activities are running, taking care of restarting this
3584                // process.
3585                if (hasVisibleActivities) {
3586                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3587                }
3588            }
3589        }
3590    }
3591
3592    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3593        IBinder threadBinder = thread.asBinder();
3594        // Find the application record.
3595        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3596            ProcessRecord rec = mLruProcesses.get(i);
3597            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3598                return i;
3599            }
3600        }
3601        return -1;
3602    }
3603
3604    final ProcessRecord getRecordForAppLocked(
3605            IApplicationThread thread) {
3606        if (thread == null) {
3607            return null;
3608        }
3609
3610        int appIndex = getLRURecordIndexForAppLocked(thread);
3611        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3612    }
3613
3614    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3615        // If there are no longer any background processes running,
3616        // and the app that died was not running instrumentation,
3617        // then tell everyone we are now low on memory.
3618        boolean haveBg = false;
3619        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3620            ProcessRecord rec = mLruProcesses.get(i);
3621            if (rec.thread != null
3622                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3623                haveBg = true;
3624                break;
3625            }
3626        }
3627
3628        if (!haveBg) {
3629            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3630            if (doReport) {
3631                long now = SystemClock.uptimeMillis();
3632                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3633                    doReport = false;
3634                } else {
3635                    mLastMemUsageReportTime = now;
3636                }
3637            }
3638            final ArrayList<ProcessMemInfo> memInfos
3639                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3640            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3641            long now = SystemClock.uptimeMillis();
3642            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3643                ProcessRecord rec = mLruProcesses.get(i);
3644                if (rec == dyingProc || rec.thread == null) {
3645                    continue;
3646                }
3647                if (doReport) {
3648                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3649                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3650                }
3651                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3652                    // The low memory report is overriding any current
3653                    // state for a GC request.  Make sure to do
3654                    // heavy/important/visible/foreground processes first.
3655                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3656                        rec.lastRequestedGc = 0;
3657                    } else {
3658                        rec.lastRequestedGc = rec.lastLowMemory;
3659                    }
3660                    rec.reportLowMemory = true;
3661                    rec.lastLowMemory = now;
3662                    mProcessesToGc.remove(rec);
3663                    addProcessToGcListLocked(rec);
3664                }
3665            }
3666            if (doReport) {
3667                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3668                mHandler.sendMessage(msg);
3669            }
3670            scheduleAppGcsLocked();
3671        }
3672    }
3673
3674    final void appDiedLocked(ProcessRecord app, int pid,
3675            IApplicationThread thread) {
3676
3677        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3678        synchronized (stats) {
3679            stats.noteProcessDiedLocked(app.info.uid, pid);
3680        }
3681
3682        // Clean up already done if the process has been re-started.
3683        if (app.pid == pid && app.thread != null &&
3684                app.thread.asBinder() == thread.asBinder()) {
3685            boolean doLowMem = app.instrumentationClass == null;
3686            boolean doOomAdj = doLowMem;
3687            if (!app.killedByAm) {
3688                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3689                        + ") has died.");
3690                mAllowLowerMemLevel = true;
3691            } else {
3692                // Note that we always want to do oom adj to update our state with the
3693                // new number of procs.
3694                mAllowLowerMemLevel = false;
3695                doLowMem = false;
3696            }
3697            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3698            if (DEBUG_CLEANUP) Slog.v(
3699                TAG, "Dying app: " + app + ", pid: " + pid
3700                + ", thread: " + thread.asBinder());
3701            handleAppDiedLocked(app, false, true);
3702
3703            if (doOomAdj) {
3704                updateOomAdjLocked();
3705            }
3706            if (doLowMem) {
3707                doLowMemReportIfNeededLocked(app);
3708            }
3709        } else if (app.pid != pid) {
3710            // A new process has already been started.
3711            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3712                    + ") has died and restarted (pid " + app.pid + ").");
3713            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3714        } else if (DEBUG_PROCESSES) {
3715            Slog.d(TAG, "Received spurious death notification for thread "
3716                    + thread.asBinder());
3717        }
3718    }
3719
3720    /**
3721     * If a stack trace dump file is configured, dump process stack traces.
3722     * @param clearTraces causes the dump file to be erased prior to the new
3723     *    traces being written, if true; when false, the new traces will be
3724     *    appended to any existing file content.
3725     * @param firstPids of dalvik VM processes to dump stack traces for first
3726     * @param lastPids of dalvik VM processes to dump stack traces for last
3727     * @param nativeProcs optional list of native process names to dump stack crawls
3728     * @return file containing stack traces, or null if no dump file is configured
3729     */
3730    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3731            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3732        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3733        if (tracesPath == null || tracesPath.length() == 0) {
3734            return null;
3735        }
3736
3737        File tracesFile = new File(tracesPath);
3738        try {
3739            File tracesDir = tracesFile.getParentFile();
3740            if (!tracesDir.exists()) {
3741                tracesFile.mkdirs();
3742                if (!SELinux.restorecon(tracesDir)) {
3743                    return null;
3744                }
3745            }
3746            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3747
3748            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3749            tracesFile.createNewFile();
3750            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3751        } catch (IOException e) {
3752            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3753            return null;
3754        }
3755
3756        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3757        return tracesFile;
3758    }
3759
3760    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3761            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3762        // Use a FileObserver to detect when traces finish writing.
3763        // The order of traces is considered important to maintain for legibility.
3764        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3765            @Override
3766            public synchronized void onEvent(int event, String path) { notify(); }
3767        };
3768
3769        try {
3770            observer.startWatching();
3771
3772            // First collect all of the stacks of the most important pids.
3773            if (firstPids != null) {
3774                try {
3775                    int num = firstPids.size();
3776                    for (int i = 0; i < num; i++) {
3777                        synchronized (observer) {
3778                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3779                            observer.wait(200);  // Wait for write-close, give up after 200msec
3780                        }
3781                    }
3782                } catch (InterruptedException e) {
3783                    Log.wtf(TAG, e);
3784                }
3785            }
3786
3787            // Next collect the stacks of the native pids
3788            if (nativeProcs != null) {
3789                int[] pids = Process.getPidsForCommands(nativeProcs);
3790                if (pids != null) {
3791                    for (int pid : pids) {
3792                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3793                    }
3794                }
3795            }
3796
3797            // Lastly, measure CPU usage.
3798            if (processCpuTracker != null) {
3799                processCpuTracker.init();
3800                System.gc();
3801                processCpuTracker.update();
3802                try {
3803                    synchronized (processCpuTracker) {
3804                        processCpuTracker.wait(500); // measure over 1/2 second.
3805                    }
3806                } catch (InterruptedException e) {
3807                }
3808                processCpuTracker.update();
3809
3810                // We'll take the stack crawls of just the top apps using CPU.
3811                final int N = processCpuTracker.countWorkingStats();
3812                int numProcs = 0;
3813                for (int i=0; i<N && numProcs<5; i++) {
3814                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3815                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3816                        numProcs++;
3817                        try {
3818                            synchronized (observer) {
3819                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3820                                observer.wait(200);  // Wait for write-close, give up after 200msec
3821                            }
3822                        } catch (InterruptedException e) {
3823                            Log.wtf(TAG, e);
3824                        }
3825
3826                    }
3827                }
3828            }
3829        } finally {
3830            observer.stopWatching();
3831        }
3832    }
3833
3834    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3835        if (true || IS_USER_BUILD) {
3836            return;
3837        }
3838        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3839        if (tracesPath == null || tracesPath.length() == 0) {
3840            return;
3841        }
3842
3843        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3844        StrictMode.allowThreadDiskWrites();
3845        try {
3846            final File tracesFile = new File(tracesPath);
3847            final File tracesDir = tracesFile.getParentFile();
3848            final File tracesTmp = new File(tracesDir, "__tmp__");
3849            try {
3850                if (!tracesDir.exists()) {
3851                    tracesFile.mkdirs();
3852                    if (!SELinux.restorecon(tracesDir.getPath())) {
3853                        return;
3854                    }
3855                }
3856                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3857
3858                if (tracesFile.exists()) {
3859                    tracesTmp.delete();
3860                    tracesFile.renameTo(tracesTmp);
3861                }
3862                StringBuilder sb = new StringBuilder();
3863                Time tobj = new Time();
3864                tobj.set(System.currentTimeMillis());
3865                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3866                sb.append(": ");
3867                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3868                sb.append(" since ");
3869                sb.append(msg);
3870                FileOutputStream fos = new FileOutputStream(tracesFile);
3871                fos.write(sb.toString().getBytes());
3872                if (app == null) {
3873                    fos.write("\n*** No application process!".getBytes());
3874                }
3875                fos.close();
3876                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3877            } catch (IOException e) {
3878                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3879                return;
3880            }
3881
3882            if (app != null) {
3883                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3884                firstPids.add(app.pid);
3885                dumpStackTraces(tracesPath, firstPids, null, null, null);
3886            }
3887
3888            File lastTracesFile = null;
3889            File curTracesFile = null;
3890            for (int i=9; i>=0; i--) {
3891                String name = String.format(Locale.US, "slow%02d.txt", i);
3892                curTracesFile = new File(tracesDir, name);
3893                if (curTracesFile.exists()) {
3894                    if (lastTracesFile != null) {
3895                        curTracesFile.renameTo(lastTracesFile);
3896                    } else {
3897                        curTracesFile.delete();
3898                    }
3899                }
3900                lastTracesFile = curTracesFile;
3901            }
3902            tracesFile.renameTo(curTracesFile);
3903            if (tracesTmp.exists()) {
3904                tracesTmp.renameTo(tracesFile);
3905            }
3906        } finally {
3907            StrictMode.setThreadPolicy(oldPolicy);
3908        }
3909    }
3910
3911    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3912            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3913        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3914        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3915
3916        if (mController != null) {
3917            try {
3918                // 0 == continue, -1 = kill process immediately
3919                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3920                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3921            } catch (RemoteException e) {
3922                mController = null;
3923                Watchdog.getInstance().setActivityController(null);
3924            }
3925        }
3926
3927        long anrTime = SystemClock.uptimeMillis();
3928        if (MONITOR_CPU_USAGE) {
3929            updateCpuStatsNow();
3930        }
3931
3932        synchronized (this) {
3933            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3934            if (mShuttingDown) {
3935                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3936                return;
3937            } else if (app.notResponding) {
3938                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3939                return;
3940            } else if (app.crashing) {
3941                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3942                return;
3943            }
3944
3945            // In case we come through here for the same app before completing
3946            // this one, mark as anring now so we will bail out.
3947            app.notResponding = true;
3948
3949            // Log the ANR to the event log.
3950            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3951                    app.processName, app.info.flags, annotation);
3952
3953            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3954            firstPids.add(app.pid);
3955
3956            int parentPid = app.pid;
3957            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3958            if (parentPid != app.pid) firstPids.add(parentPid);
3959
3960            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3961
3962            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3963                ProcessRecord r = mLruProcesses.get(i);
3964                if (r != null && r.thread != null) {
3965                    int pid = r.pid;
3966                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3967                        if (r.persistent) {
3968                            firstPids.add(pid);
3969                        } else {
3970                            lastPids.put(pid, Boolean.TRUE);
3971                        }
3972                    }
3973                }
3974            }
3975        }
3976
3977        // Log the ANR to the main log.
3978        StringBuilder info = new StringBuilder();
3979        info.setLength(0);
3980        info.append("ANR in ").append(app.processName);
3981        if (activity != null && activity.shortComponentName != null) {
3982            info.append(" (").append(activity.shortComponentName).append(")");
3983        }
3984        info.append("\n");
3985        info.append("PID: ").append(app.pid).append("\n");
3986        if (annotation != null) {
3987            info.append("Reason: ").append(annotation).append("\n");
3988        }
3989        if (parent != null && parent != activity) {
3990            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3991        }
3992
3993        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
3994
3995        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
3996                NATIVE_STACKS_OF_INTEREST);
3997
3998        String cpuInfo = null;
3999        if (MONITOR_CPU_USAGE) {
4000            updateCpuStatsNow();
4001            synchronized (mProcessCpuThread) {
4002                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4003            }
4004            info.append(processCpuTracker.printCurrentLoad());
4005            info.append(cpuInfo);
4006        }
4007
4008        info.append(processCpuTracker.printCurrentState(anrTime));
4009
4010        Slog.e(TAG, info.toString());
4011        if (tracesFile == null) {
4012            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4013            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4014        }
4015
4016        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4017                cpuInfo, tracesFile, null);
4018
4019        if (mController != null) {
4020            try {
4021                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4022                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4023                if (res != 0) {
4024                    if (res < 0 && app.pid != MY_PID) {
4025                        Process.killProcess(app.pid);
4026                    } else {
4027                        synchronized (this) {
4028                            mServices.scheduleServiceTimeoutLocked(app);
4029                        }
4030                    }
4031                    return;
4032                }
4033            } catch (RemoteException e) {
4034                mController = null;
4035                Watchdog.getInstance().setActivityController(null);
4036            }
4037        }
4038
4039        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4040        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4041                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4042
4043        synchronized (this) {
4044            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4045                killUnneededProcessLocked(app, "background ANR");
4046                return;
4047            }
4048
4049            // Set the app's notResponding state, and look up the errorReportReceiver
4050            makeAppNotRespondingLocked(app,
4051                    activity != null ? activity.shortComponentName : null,
4052                    annotation != null ? "ANR " + annotation : "ANR",
4053                    info.toString());
4054
4055            // Bring up the infamous App Not Responding dialog
4056            Message msg = Message.obtain();
4057            HashMap<String, Object> map = new HashMap<String, Object>();
4058            msg.what = SHOW_NOT_RESPONDING_MSG;
4059            msg.obj = map;
4060            msg.arg1 = aboveSystem ? 1 : 0;
4061            map.put("app", app);
4062            if (activity != null) {
4063                map.put("activity", activity);
4064            }
4065
4066            mHandler.sendMessage(msg);
4067        }
4068    }
4069
4070    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4071        if (!mLaunchWarningShown) {
4072            mLaunchWarningShown = true;
4073            mHandler.post(new Runnable() {
4074                @Override
4075                public void run() {
4076                    synchronized (ActivityManagerService.this) {
4077                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4078                        d.show();
4079                        mHandler.postDelayed(new Runnable() {
4080                            @Override
4081                            public void run() {
4082                                synchronized (ActivityManagerService.this) {
4083                                    d.dismiss();
4084                                    mLaunchWarningShown = false;
4085                                }
4086                            }
4087                        }, 4000);
4088                    }
4089                }
4090            });
4091        }
4092    }
4093
4094    @Override
4095    public boolean clearApplicationUserData(final String packageName,
4096            final IPackageDataObserver observer, int userId) {
4097        enforceNotIsolatedCaller("clearApplicationUserData");
4098        int uid = Binder.getCallingUid();
4099        int pid = Binder.getCallingPid();
4100        userId = handleIncomingUser(pid, uid,
4101                userId, false, true, "clearApplicationUserData", null);
4102        long callingId = Binder.clearCallingIdentity();
4103        try {
4104            IPackageManager pm = AppGlobals.getPackageManager();
4105            int pkgUid = -1;
4106            synchronized(this) {
4107                try {
4108                    pkgUid = pm.getPackageUid(packageName, userId);
4109                } catch (RemoteException e) {
4110                }
4111                if (pkgUid == -1) {
4112                    Slog.w(TAG, "Invalid packageName: " + packageName);
4113                    if (observer != null) {
4114                        try {
4115                            observer.onRemoveCompleted(packageName, false);
4116                        } catch (RemoteException e) {
4117                            Slog.i(TAG, "Observer no longer exists.");
4118                        }
4119                    }
4120                    return false;
4121                }
4122                if (uid == pkgUid || checkComponentPermission(
4123                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4124                        pid, uid, -1, true)
4125                        == PackageManager.PERMISSION_GRANTED) {
4126                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4127                } else {
4128                    throw new SecurityException("PID " + pid + " does not have permission "
4129                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4130                                    + " of package " + packageName);
4131                }
4132            }
4133
4134            try {
4135                // Clear application user data
4136                pm.clearApplicationUserData(packageName, observer, userId);
4137
4138                // Remove all permissions granted from/to this package
4139                removeUriPermissionsForPackageLocked(packageName, userId, true);
4140
4141                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4142                        Uri.fromParts("package", packageName, null));
4143                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4144                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4145                        null, null, 0, null, null, null, false, false, userId);
4146            } catch (RemoteException e) {
4147            }
4148        } finally {
4149            Binder.restoreCallingIdentity(callingId);
4150        }
4151        return true;
4152    }
4153
4154    @Override
4155    public void killBackgroundProcesses(final String packageName, int userId) {
4156        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4157                != PackageManager.PERMISSION_GRANTED &&
4158                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4159                        != PackageManager.PERMISSION_GRANTED) {
4160            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4161                    + Binder.getCallingPid()
4162                    + ", uid=" + Binder.getCallingUid()
4163                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4164            Slog.w(TAG, msg);
4165            throw new SecurityException(msg);
4166        }
4167
4168        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4169                userId, true, true, "killBackgroundProcesses", null);
4170        long callingId = Binder.clearCallingIdentity();
4171        try {
4172            IPackageManager pm = AppGlobals.getPackageManager();
4173            synchronized(this) {
4174                int appId = -1;
4175                try {
4176                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4177                } catch (RemoteException e) {
4178                }
4179                if (appId == -1) {
4180                    Slog.w(TAG, "Invalid packageName: " + packageName);
4181                    return;
4182                }
4183                killPackageProcessesLocked(packageName, appId, userId,
4184                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4185            }
4186        } finally {
4187            Binder.restoreCallingIdentity(callingId);
4188        }
4189    }
4190
4191    @Override
4192    public void killAllBackgroundProcesses() {
4193        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4194                != PackageManager.PERMISSION_GRANTED) {
4195            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4196                    + Binder.getCallingPid()
4197                    + ", uid=" + Binder.getCallingUid()
4198                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4199            Slog.w(TAG, msg);
4200            throw new SecurityException(msg);
4201        }
4202
4203        long callingId = Binder.clearCallingIdentity();
4204        try {
4205            synchronized(this) {
4206                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4207                final int NP = mProcessNames.getMap().size();
4208                for (int ip=0; ip<NP; ip++) {
4209                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4210                    final int NA = apps.size();
4211                    for (int ia=0; ia<NA; ia++) {
4212                        ProcessRecord app = apps.valueAt(ia);
4213                        if (app.persistent) {
4214                            // we don't kill persistent processes
4215                            continue;
4216                        }
4217                        if (app.removed) {
4218                            procs.add(app);
4219                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4220                            app.removed = true;
4221                            procs.add(app);
4222                        }
4223                    }
4224                }
4225
4226                int N = procs.size();
4227                for (int i=0; i<N; i++) {
4228                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4229                }
4230                mAllowLowerMemLevel = true;
4231                updateOomAdjLocked();
4232                doLowMemReportIfNeededLocked(null);
4233            }
4234        } finally {
4235            Binder.restoreCallingIdentity(callingId);
4236        }
4237    }
4238
4239    @Override
4240    public void forceStopPackage(final String packageName, int userId) {
4241        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4242                != PackageManager.PERMISSION_GRANTED) {
4243            String msg = "Permission Denial: forceStopPackage() from pid="
4244                    + Binder.getCallingPid()
4245                    + ", uid=" + Binder.getCallingUid()
4246                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4247            Slog.w(TAG, msg);
4248            throw new SecurityException(msg);
4249        }
4250        final int callingPid = Binder.getCallingPid();
4251        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4252                userId, true, true, "forceStopPackage", null);
4253        long callingId = Binder.clearCallingIdentity();
4254        try {
4255            IPackageManager pm = AppGlobals.getPackageManager();
4256            synchronized(this) {
4257                int[] users = userId == UserHandle.USER_ALL
4258                        ? getUsersLocked() : new int[] { userId };
4259                for (int user : users) {
4260                    int pkgUid = -1;
4261                    try {
4262                        pkgUid = pm.getPackageUid(packageName, user);
4263                    } catch (RemoteException e) {
4264                    }
4265                    if (pkgUid == -1) {
4266                        Slog.w(TAG, "Invalid packageName: " + packageName);
4267                        continue;
4268                    }
4269                    try {
4270                        pm.setPackageStoppedState(packageName, true, user);
4271                    } catch (RemoteException e) {
4272                    } catch (IllegalArgumentException e) {
4273                        Slog.w(TAG, "Failed trying to unstop package "
4274                                + packageName + ": " + e);
4275                    }
4276                    if (isUserRunningLocked(user, false)) {
4277                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4278                    }
4279                }
4280            }
4281        } finally {
4282            Binder.restoreCallingIdentity(callingId);
4283        }
4284    }
4285
4286    /*
4287     * The pkg name and app id have to be specified.
4288     */
4289    @Override
4290    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4291        if (pkg == null) {
4292            return;
4293        }
4294        // Make sure the uid is valid.
4295        if (appid < 0) {
4296            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4297            return;
4298        }
4299        int callerUid = Binder.getCallingUid();
4300        // Only the system server can kill an application
4301        if (callerUid == Process.SYSTEM_UID) {
4302            // Post an aysnc message to kill the application
4303            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4304            msg.arg1 = appid;
4305            msg.arg2 = 0;
4306            Bundle bundle = new Bundle();
4307            bundle.putString("pkg", pkg);
4308            bundle.putString("reason", reason);
4309            msg.obj = bundle;
4310            mHandler.sendMessage(msg);
4311        } else {
4312            throw new SecurityException(callerUid + " cannot kill pkg: " +
4313                    pkg);
4314        }
4315    }
4316
4317    @Override
4318    public void closeSystemDialogs(String reason) {
4319        enforceNotIsolatedCaller("closeSystemDialogs");
4320
4321        final int pid = Binder.getCallingPid();
4322        final int uid = Binder.getCallingUid();
4323        final long origId = Binder.clearCallingIdentity();
4324        try {
4325            synchronized (this) {
4326                // Only allow this from foreground processes, so that background
4327                // applications can't abuse it to prevent system UI from being shown.
4328                if (uid >= Process.FIRST_APPLICATION_UID) {
4329                    ProcessRecord proc;
4330                    synchronized (mPidsSelfLocked) {
4331                        proc = mPidsSelfLocked.get(pid);
4332                    }
4333                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4334                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4335                                + " from background process " + proc);
4336                        return;
4337                    }
4338                }
4339                closeSystemDialogsLocked(reason);
4340            }
4341        } finally {
4342            Binder.restoreCallingIdentity(origId);
4343        }
4344    }
4345
4346    void closeSystemDialogsLocked(String reason) {
4347        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4348        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4349                | Intent.FLAG_RECEIVER_FOREGROUND);
4350        if (reason != null) {
4351            intent.putExtra("reason", reason);
4352        }
4353        mWindowManager.closeSystemDialogs(reason);
4354
4355        mStackSupervisor.closeSystemDialogsLocked();
4356
4357        broadcastIntentLocked(null, null, intent, null,
4358                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4359                Process.SYSTEM_UID, UserHandle.USER_ALL);
4360    }
4361
4362    @Override
4363    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4364        enforceNotIsolatedCaller("getProcessMemoryInfo");
4365        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4366        for (int i=pids.length-1; i>=0; i--) {
4367            ProcessRecord proc;
4368            int oomAdj;
4369            synchronized (this) {
4370                synchronized (mPidsSelfLocked) {
4371                    proc = mPidsSelfLocked.get(pids[i]);
4372                    oomAdj = proc != null ? proc.setAdj : 0;
4373                }
4374            }
4375            infos[i] = new Debug.MemoryInfo();
4376            Debug.getMemoryInfo(pids[i], infos[i]);
4377            if (proc != null) {
4378                synchronized (this) {
4379                    if (proc.thread != null && proc.setAdj == oomAdj) {
4380                        // Record this for posterity if the process has been stable.
4381                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4382                                infos[i].getTotalUss(), false, proc.pkgList);
4383                    }
4384                }
4385            }
4386        }
4387        return infos;
4388    }
4389
4390    @Override
4391    public long[] getProcessPss(int[] pids) {
4392        enforceNotIsolatedCaller("getProcessPss");
4393        long[] pss = new long[pids.length];
4394        for (int i=pids.length-1; i>=0; i--) {
4395            ProcessRecord proc;
4396            int oomAdj;
4397            synchronized (this) {
4398                synchronized (mPidsSelfLocked) {
4399                    proc = mPidsSelfLocked.get(pids[i]);
4400                    oomAdj = proc != null ? proc.setAdj : 0;
4401                }
4402            }
4403            long[] tmpUss = new long[1];
4404            pss[i] = Debug.getPss(pids[i], tmpUss);
4405            if (proc != null) {
4406                synchronized (this) {
4407                    if (proc.thread != null && proc.setAdj == oomAdj) {
4408                        // Record this for posterity if the process has been stable.
4409                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4410                    }
4411                }
4412            }
4413        }
4414        return pss;
4415    }
4416
4417    @Override
4418    public void killApplicationProcess(String processName, int uid) {
4419        if (processName == null) {
4420            return;
4421        }
4422
4423        int callerUid = Binder.getCallingUid();
4424        // Only the system server can kill an application
4425        if (callerUid == Process.SYSTEM_UID) {
4426            synchronized (this) {
4427                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4428                if (app != null && app.thread != null) {
4429                    try {
4430                        app.thread.scheduleSuicide();
4431                    } catch (RemoteException e) {
4432                        // If the other end already died, then our work here is done.
4433                    }
4434                } else {
4435                    Slog.w(TAG, "Process/uid not found attempting kill of "
4436                            + processName + " / " + uid);
4437                }
4438            }
4439        } else {
4440            throw new SecurityException(callerUid + " cannot kill app process: " +
4441                    processName);
4442        }
4443    }
4444
4445    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4446        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4447                false, true, false, UserHandle.getUserId(uid), reason);
4448        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4449                Uri.fromParts("package", packageName, null));
4450        if (!mProcessesReady) {
4451            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4452                    | Intent.FLAG_RECEIVER_FOREGROUND);
4453        }
4454        intent.putExtra(Intent.EXTRA_UID, uid);
4455        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4456        broadcastIntentLocked(null, null, intent,
4457                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4458                false, false,
4459                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4460    }
4461
4462    private void forceStopUserLocked(int userId, String reason) {
4463        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
4464        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4465        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4466                | Intent.FLAG_RECEIVER_FOREGROUND);
4467        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4468        broadcastIntentLocked(null, null, intent,
4469                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4470                false, false,
4471                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4472    }
4473
4474    private final boolean killPackageProcessesLocked(String packageName, int appId,
4475            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4476            boolean doit, boolean evenPersistent, String reason) {
4477        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4478
4479        // Remove all processes this package may have touched: all with the
4480        // same UID (except for the system or root user), and all whose name
4481        // matches the package name.
4482        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4483        final int NP = mProcessNames.getMap().size();
4484        for (int ip=0; ip<NP; ip++) {
4485            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4486            final int NA = apps.size();
4487            for (int ia=0; ia<NA; ia++) {
4488                ProcessRecord app = apps.valueAt(ia);
4489                if (app.persistent && !evenPersistent) {
4490                    // we don't kill persistent processes
4491                    continue;
4492                }
4493                if (app.removed) {
4494                    if (doit) {
4495                        procs.add(app);
4496                    }
4497                    continue;
4498                }
4499
4500                // Skip process if it doesn't meet our oom adj requirement.
4501                if (app.setAdj < minOomAdj) {
4502                    continue;
4503                }
4504
4505                // If no package is specified, we call all processes under the
4506                // give user id.
4507                if (packageName == null) {
4508                    if (app.userId != userId) {
4509                        continue;
4510                    }
4511                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4512                        continue;
4513                    }
4514                // Package has been specified, we want to hit all processes
4515                // that match it.  We need to qualify this by the processes
4516                // that are running under the specified app and user ID.
4517                } else {
4518                    if (UserHandle.getAppId(app.uid) != appId) {
4519                        continue;
4520                    }
4521                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4522                        continue;
4523                    }
4524                    if (!app.pkgList.containsKey(packageName)) {
4525                        continue;
4526                    }
4527                }
4528
4529                // Process has passed all conditions, kill it!
4530                if (!doit) {
4531                    return true;
4532                }
4533                app.removed = true;
4534                procs.add(app);
4535            }
4536        }
4537
4538        int N = procs.size();
4539        for (int i=0; i<N; i++) {
4540            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4541        }
4542        updateOomAdjLocked();
4543        return N > 0;
4544    }
4545
4546    private final boolean forceStopPackageLocked(String name, int appId,
4547            boolean callerWillRestart, boolean purgeCache, boolean doit,
4548            boolean evenPersistent, int userId, String reason) {
4549        int i;
4550        int N;
4551
4552        if (userId == UserHandle.USER_ALL && name == null) {
4553            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4554        }
4555
4556        if (appId < 0 && name != null) {
4557            try {
4558                appId = UserHandle.getAppId(
4559                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4560            } catch (RemoteException e) {
4561            }
4562        }
4563
4564        if (doit) {
4565            if (name != null) {
4566                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4567                        + " user=" + userId + ": " + reason);
4568            } else {
4569                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4570            }
4571
4572            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4573            for (int ip=pmap.size()-1; ip>=0; ip--) {
4574                SparseArray<Long> ba = pmap.valueAt(ip);
4575                for (i=ba.size()-1; i>=0; i--) {
4576                    boolean remove = false;
4577                    final int entUid = ba.keyAt(i);
4578                    if (name != null) {
4579                        if (userId == UserHandle.USER_ALL) {
4580                            if (UserHandle.getAppId(entUid) == appId) {
4581                                remove = true;
4582                            }
4583                        } else {
4584                            if (entUid == UserHandle.getUid(userId, appId)) {
4585                                remove = true;
4586                            }
4587                        }
4588                    } else if (UserHandle.getUserId(entUid) == userId) {
4589                        remove = true;
4590                    }
4591                    if (remove) {
4592                        ba.removeAt(i);
4593                    }
4594                }
4595                if (ba.size() == 0) {
4596                    pmap.removeAt(ip);
4597                }
4598            }
4599        }
4600
4601        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4602                -100, callerWillRestart, true, doit, evenPersistent,
4603                name == null ? ("stop user " + userId) : ("stop " + name));
4604
4605        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4606            if (!doit) {
4607                return true;
4608            }
4609            didSomething = true;
4610        }
4611
4612        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4613            if (!doit) {
4614                return true;
4615            }
4616            didSomething = true;
4617        }
4618
4619        if (name == null) {
4620            // Remove all sticky broadcasts from this user.
4621            mStickyBroadcasts.remove(userId);
4622        }
4623
4624        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4625        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4626                userId, providers)) {
4627            if (!doit) {
4628                return true;
4629            }
4630            didSomething = true;
4631        }
4632        N = providers.size();
4633        for (i=0; i<N; i++) {
4634            removeDyingProviderLocked(null, providers.get(i), true);
4635        }
4636
4637        // Remove transient permissions granted from/to this package/user
4638        removeUriPermissionsForPackageLocked(name, userId, false);
4639
4640        if (name == null) {
4641            // Remove pending intents.  For now we only do this when force
4642            // stopping users, because we have some problems when doing this
4643            // for packages -- app widgets are not currently cleaned up for
4644            // such packages, so they can be left with bad pending intents.
4645            if (mIntentSenderRecords.size() > 0) {
4646                Iterator<WeakReference<PendingIntentRecord>> it
4647                        = mIntentSenderRecords.values().iterator();
4648                while (it.hasNext()) {
4649                    WeakReference<PendingIntentRecord> wpir = it.next();
4650                    if (wpir == null) {
4651                        it.remove();
4652                        continue;
4653                    }
4654                    PendingIntentRecord pir = wpir.get();
4655                    if (pir == null) {
4656                        it.remove();
4657                        continue;
4658                    }
4659                    if (name == null) {
4660                        // Stopping user, remove all objects for the user.
4661                        if (pir.key.userId != userId) {
4662                            // Not the same user, skip it.
4663                            continue;
4664                        }
4665                    } else {
4666                        if (UserHandle.getAppId(pir.uid) != appId) {
4667                            // Different app id, skip it.
4668                            continue;
4669                        }
4670                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4671                            // Different user, skip it.
4672                            continue;
4673                        }
4674                        if (!pir.key.packageName.equals(name)) {
4675                            // Different package, skip it.
4676                            continue;
4677                        }
4678                    }
4679                    if (!doit) {
4680                        return true;
4681                    }
4682                    didSomething = true;
4683                    it.remove();
4684                    pir.canceled = true;
4685                    if (pir.key.activity != null) {
4686                        pir.key.activity.pendingResults.remove(pir.ref);
4687                    }
4688                }
4689            }
4690        }
4691
4692        if (doit) {
4693            if (purgeCache && name != null) {
4694                AttributeCache ac = AttributeCache.instance();
4695                if (ac != null) {
4696                    ac.removePackage(name);
4697                }
4698            }
4699            if (mBooted) {
4700                mStackSupervisor.resumeTopActivitiesLocked();
4701                mStackSupervisor.scheduleIdleLocked();
4702            }
4703        }
4704
4705        return didSomething;
4706    }
4707
4708    private final boolean removeProcessLocked(ProcessRecord app,
4709            boolean callerWillRestart, boolean allowRestart, String reason) {
4710        final String name = app.processName;
4711        final int uid = app.uid;
4712        if (DEBUG_PROCESSES) Slog.d(
4713            TAG, "Force removing proc " + app.toShortString() + " (" + name
4714            + "/" + uid + ")");
4715
4716        mProcessNames.remove(name, uid);
4717        mIsolatedProcesses.remove(app.uid);
4718        if (mHeavyWeightProcess == app) {
4719            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4720                    mHeavyWeightProcess.userId, 0));
4721            mHeavyWeightProcess = null;
4722        }
4723        boolean needRestart = false;
4724        if (app.pid > 0 && app.pid != MY_PID) {
4725            int pid = app.pid;
4726            synchronized (mPidsSelfLocked) {
4727                mPidsSelfLocked.remove(pid);
4728                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4729            }
4730            killUnneededProcessLocked(app, reason);
4731            handleAppDiedLocked(app, true, allowRestart);
4732            removeLruProcessLocked(app);
4733
4734            if (app.persistent && !app.isolated) {
4735                if (!callerWillRestart) {
4736                    addAppLocked(app.info, false);
4737                } else {
4738                    needRestart = true;
4739                }
4740            }
4741        } else {
4742            mRemovedProcesses.add(app);
4743        }
4744
4745        return needRestart;
4746    }
4747
4748    private final void processStartTimedOutLocked(ProcessRecord app) {
4749        final int pid = app.pid;
4750        boolean gone = false;
4751        synchronized (mPidsSelfLocked) {
4752            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4753            if (knownApp != null && knownApp.thread == null) {
4754                mPidsSelfLocked.remove(pid);
4755                gone = true;
4756            }
4757        }
4758
4759        if (gone) {
4760            Slog.w(TAG, "Process " + app + " failed to attach");
4761            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4762                    pid, app.uid, app.processName);
4763            mProcessNames.remove(app.processName, app.uid);
4764            mIsolatedProcesses.remove(app.uid);
4765            if (mHeavyWeightProcess == app) {
4766                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4767                        mHeavyWeightProcess.userId, 0));
4768                mHeavyWeightProcess = null;
4769            }
4770            // Take care of any launching providers waiting for this process.
4771            checkAppInLaunchingProvidersLocked(app, true);
4772            // Take care of any services that are waiting for the process.
4773            mServices.processStartTimedOutLocked(app);
4774            killUnneededProcessLocked(app, "start timeout");
4775            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4776                Slog.w(TAG, "Unattached app died before backup, skipping");
4777                try {
4778                    IBackupManager bm = IBackupManager.Stub.asInterface(
4779                            ServiceManager.getService(Context.BACKUP_SERVICE));
4780                    bm.agentDisconnected(app.info.packageName);
4781                } catch (RemoteException e) {
4782                    // Can't happen; the backup manager is local
4783                }
4784            }
4785            if (isPendingBroadcastProcessLocked(pid)) {
4786                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4787                skipPendingBroadcastLocked(pid);
4788            }
4789        } else {
4790            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4791        }
4792    }
4793
4794    private final boolean attachApplicationLocked(IApplicationThread thread,
4795            int pid) {
4796
4797        // Find the application record that is being attached...  either via
4798        // the pid if we are running in multiple processes, or just pull the
4799        // next app record if we are emulating process with anonymous threads.
4800        ProcessRecord app;
4801        if (pid != MY_PID && pid >= 0) {
4802            synchronized (mPidsSelfLocked) {
4803                app = mPidsSelfLocked.get(pid);
4804            }
4805        } else {
4806            app = null;
4807        }
4808
4809        if (app == null) {
4810            Slog.w(TAG, "No pending application record for pid " + pid
4811                    + " (IApplicationThread " + thread + "); dropping process");
4812            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4813            if (pid > 0 && pid != MY_PID) {
4814                Process.killProcessQuiet(pid);
4815            } else {
4816                try {
4817                    thread.scheduleExit();
4818                } catch (Exception e) {
4819                    // Ignore exceptions.
4820                }
4821            }
4822            return false;
4823        }
4824
4825        // If this application record is still attached to a previous
4826        // process, clean it up now.
4827        if (app.thread != null) {
4828            handleAppDiedLocked(app, true, true);
4829        }
4830
4831        // Tell the process all about itself.
4832
4833        if (localLOGV) Slog.v(
4834                TAG, "Binding process pid " + pid + " to record " + app);
4835
4836        final String processName = app.processName;
4837        try {
4838            AppDeathRecipient adr = new AppDeathRecipient(
4839                    app, pid, thread);
4840            thread.asBinder().linkToDeath(adr, 0);
4841            app.deathRecipient = adr;
4842        } catch (RemoteException e) {
4843            app.resetPackageList(mProcessStats);
4844            startProcessLocked(app, "link fail", processName);
4845            return false;
4846        }
4847
4848        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4849
4850        app.makeActive(thread, mProcessStats);
4851        app.curAdj = app.setAdj = -100;
4852        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4853        app.forcingToForeground = null;
4854        app.foregroundServices = false;
4855        app.hasShownUi = false;
4856        app.debugging = false;
4857        app.cached = false;
4858
4859        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4860
4861        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4862        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4863
4864        if (!normalMode) {
4865            Slog.i(TAG, "Launching preboot mode app: " + app);
4866        }
4867
4868        if (localLOGV) Slog.v(
4869            TAG, "New app record " + app
4870            + " thread=" + thread.asBinder() + " pid=" + pid);
4871        try {
4872            int testMode = IApplicationThread.DEBUG_OFF;
4873            if (mDebugApp != null && mDebugApp.equals(processName)) {
4874                testMode = mWaitForDebugger
4875                    ? IApplicationThread.DEBUG_WAIT
4876                    : IApplicationThread.DEBUG_ON;
4877                app.debugging = true;
4878                if (mDebugTransient) {
4879                    mDebugApp = mOrigDebugApp;
4880                    mWaitForDebugger = mOrigWaitForDebugger;
4881                }
4882            }
4883            String profileFile = app.instrumentationProfileFile;
4884            ParcelFileDescriptor profileFd = null;
4885            boolean profileAutoStop = false;
4886            if (mProfileApp != null && mProfileApp.equals(processName)) {
4887                mProfileProc = app;
4888                profileFile = mProfileFile;
4889                profileFd = mProfileFd;
4890                profileAutoStop = mAutoStopProfiler;
4891            }
4892            boolean enableOpenGlTrace = false;
4893            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4894                enableOpenGlTrace = true;
4895                mOpenGlTraceApp = null;
4896            }
4897
4898            // If the app is being launched for restore or full backup, set it up specially
4899            boolean isRestrictedBackupMode = false;
4900            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4901                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4902                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4903                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4904            }
4905
4906            ensurePackageDexOpt(app.instrumentationInfo != null
4907                    ? app.instrumentationInfo.packageName
4908                    : app.info.packageName);
4909            if (app.instrumentationClass != null) {
4910                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4911            }
4912            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4913                    + processName + " with config " + mConfiguration);
4914            ApplicationInfo appInfo = app.instrumentationInfo != null
4915                    ? app.instrumentationInfo : app.info;
4916            app.compat = compatibilityInfoForPackageLocked(appInfo);
4917            if (profileFd != null) {
4918                profileFd = profileFd.dup();
4919            }
4920            thread.bindApplication(processName, appInfo, providers,
4921                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4922                    app.instrumentationArguments, app.instrumentationWatcher,
4923                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4924                    isRestrictedBackupMode || !normalMode, app.persistent,
4925                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4926                    mCoreSettingsObserver.getCoreSettingsLocked());
4927            updateLruProcessLocked(app, false, null);
4928            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4929        } catch (Exception e) {
4930            // todo: Yikes!  What should we do?  For now we will try to
4931            // start another process, but that could easily get us in
4932            // an infinite loop of restarting processes...
4933            Slog.w(TAG, "Exception thrown during bind!", e);
4934
4935            app.resetPackageList(mProcessStats);
4936            app.unlinkDeathRecipient();
4937            startProcessLocked(app, "bind fail", processName);
4938            return false;
4939        }
4940
4941        // Remove this record from the list of starting applications.
4942        mPersistentStartingProcesses.remove(app);
4943        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4944                "Attach application locked removing on hold: " + app);
4945        mProcessesOnHold.remove(app);
4946
4947        boolean badApp = false;
4948        boolean didSomething = false;
4949
4950        // See if the top visible activity is waiting to run in this process...
4951        if (normalMode) {
4952            try {
4953                if (mStackSupervisor.attachApplicationLocked(app)) {
4954                    didSomething = true;
4955                }
4956            } catch (Exception e) {
4957                badApp = true;
4958            }
4959        }
4960
4961        // Find any services that should be running in this process...
4962        if (!badApp) {
4963            try {
4964                didSomething |= mServices.attachApplicationLocked(app, processName);
4965            } catch (Exception e) {
4966                badApp = true;
4967            }
4968        }
4969
4970        // Check if a next-broadcast receiver is in this process...
4971        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4972            try {
4973                didSomething |= sendPendingBroadcastsLocked(app);
4974            } catch (Exception e) {
4975                // If the app died trying to launch the receiver we declare it 'bad'
4976                badApp = true;
4977            }
4978        }
4979
4980        // Check whether the next backup agent is in this process...
4981        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4982            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4983            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4984            try {
4985                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4986                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4987                        mBackupTarget.backupMode);
4988            } catch (Exception e) {
4989                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4990                e.printStackTrace();
4991            }
4992        }
4993
4994        if (badApp) {
4995            // todo: Also need to kill application to deal with all
4996            // kinds of exceptions.
4997            handleAppDiedLocked(app, false, true);
4998            return false;
4999        }
5000
5001        if (!didSomething) {
5002            updateOomAdjLocked();
5003        }
5004
5005        return true;
5006    }
5007
5008    @Override
5009    public final void attachApplication(IApplicationThread thread) {
5010        synchronized (this) {
5011            int callingPid = Binder.getCallingPid();
5012            final long origId = Binder.clearCallingIdentity();
5013            attachApplicationLocked(thread, callingPid);
5014            Binder.restoreCallingIdentity(origId);
5015        }
5016    }
5017
5018    @Override
5019    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5020        final long origId = Binder.clearCallingIdentity();
5021        synchronized (this) {
5022            ActivityStack stack = ActivityRecord.getStackLocked(token);
5023            if (stack != null) {
5024                ActivityRecord r =
5025                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5026                if (stopProfiling) {
5027                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5028                        try {
5029                            mProfileFd.close();
5030                        } catch (IOException e) {
5031                        }
5032                        clearProfilerLocked();
5033                    }
5034                }
5035            }
5036        }
5037        Binder.restoreCallingIdentity(origId);
5038    }
5039
5040    void enableScreenAfterBoot() {
5041        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5042                SystemClock.uptimeMillis());
5043        mWindowManager.enableScreenAfterBoot();
5044
5045        synchronized (this) {
5046            updateEventDispatchingLocked();
5047        }
5048    }
5049
5050    @Override
5051    public void showBootMessage(final CharSequence msg, final boolean always) {
5052        enforceNotIsolatedCaller("showBootMessage");
5053        mWindowManager.showBootMessage(msg, always);
5054    }
5055
5056    @Override
5057    public void dismissKeyguardOnNextActivity() {
5058        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5059        final long token = Binder.clearCallingIdentity();
5060        try {
5061            synchronized (this) {
5062                if (DEBUG_LOCKSCREEN) logLockScreen("");
5063                if (mLockScreenShown) {
5064                    mLockScreenShown = false;
5065                    comeOutOfSleepIfNeededLocked();
5066                }
5067                mStackSupervisor.setDismissKeyguard(true);
5068            }
5069        } finally {
5070            Binder.restoreCallingIdentity(token);
5071        }
5072    }
5073
5074    final void finishBooting() {
5075        IntentFilter pkgFilter = new IntentFilter();
5076        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5077        pkgFilter.addDataScheme("package");
5078        mContext.registerReceiver(new BroadcastReceiver() {
5079            @Override
5080            public void onReceive(Context context, Intent intent) {
5081                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5082                if (pkgs != null) {
5083                    for (String pkg : pkgs) {
5084                        synchronized (ActivityManagerService.this) {
5085                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
5086                                    "finished booting")) {
5087                                setResultCode(Activity.RESULT_OK);
5088                                return;
5089                            }
5090                        }
5091                    }
5092                }
5093            }
5094        }, pkgFilter);
5095
5096        synchronized (this) {
5097            // Ensure that any processes we had put on hold are now started
5098            // up.
5099            final int NP = mProcessesOnHold.size();
5100            if (NP > 0) {
5101                ArrayList<ProcessRecord> procs =
5102                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5103                for (int ip=0; ip<NP; ip++) {
5104                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5105                            + procs.get(ip));
5106                    startProcessLocked(procs.get(ip), "on-hold", null);
5107                }
5108            }
5109
5110            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5111                // Start looking for apps that are abusing wake locks.
5112                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5113                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5114                // Tell anyone interested that we are done booting!
5115                SystemProperties.set("sys.boot_completed", "1");
5116                SystemProperties.set("dev.bootcomplete", "1");
5117                for (int i=0; i<mStartedUsers.size(); i++) {
5118                    UserStartedState uss = mStartedUsers.valueAt(i);
5119                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5120                        uss.mState = UserStartedState.STATE_RUNNING;
5121                        final int userId = mStartedUsers.keyAt(i);
5122                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5123                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5124                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5125                        broadcastIntentLocked(null, null, intent, null,
5126                                new IIntentReceiver.Stub() {
5127                                    @Override
5128                                    public void performReceive(Intent intent, int resultCode,
5129                                            String data, Bundle extras, boolean ordered,
5130                                            boolean sticky, int sendingUser) {
5131                                        synchronized (ActivityManagerService.this) {
5132                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5133                                                    true, false);
5134                                        }
5135                                    }
5136                                },
5137                                0, null, null,
5138                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5139                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5140                                userId);
5141                    }
5142                }
5143            }
5144        }
5145    }
5146
5147    final void ensureBootCompleted() {
5148        boolean booting;
5149        boolean enableScreen;
5150        synchronized (this) {
5151            booting = mBooting;
5152            mBooting = false;
5153            enableScreen = !mBooted;
5154            mBooted = true;
5155        }
5156
5157        if (booting) {
5158            finishBooting();
5159        }
5160
5161        if (enableScreen) {
5162            enableScreenAfterBoot();
5163        }
5164    }
5165
5166    @Override
5167    public final void activityResumed(IBinder token) {
5168        final long origId = Binder.clearCallingIdentity();
5169        synchronized(this) {
5170            ActivityStack stack = ActivityRecord.getStackLocked(token);
5171            if (stack != null) {
5172                ActivityRecord.activityResumedLocked(token);
5173            }
5174        }
5175        Binder.restoreCallingIdentity(origId);
5176    }
5177
5178    @Override
5179    public final void activityPaused(IBinder token) {
5180        final long origId = Binder.clearCallingIdentity();
5181        synchronized(this) {
5182            ActivityStack stack = ActivityRecord.getStackLocked(token);
5183            if (stack != null) {
5184                stack.activityPausedLocked(token, false);
5185            }
5186        }
5187        Binder.restoreCallingIdentity(origId);
5188    }
5189
5190    @Override
5191    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5192            CharSequence description) {
5193        if (localLOGV) Slog.v(
5194            TAG, "Activity stopped: token=" + token);
5195
5196        // Refuse possible leaked file descriptors
5197        if (icicle != null && icicle.hasFileDescriptors()) {
5198            throw new IllegalArgumentException("File descriptors passed in Bundle");
5199        }
5200
5201        ActivityRecord r = null;
5202
5203        final long origId = Binder.clearCallingIdentity();
5204
5205        synchronized (this) {
5206            r = ActivityRecord.isInStackLocked(token);
5207            if (r != null) {
5208                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5209            }
5210        }
5211
5212        if (r != null) {
5213            sendPendingThumbnail(r, null, null, null, false);
5214        }
5215
5216        trimApplications();
5217
5218        Binder.restoreCallingIdentity(origId);
5219    }
5220
5221    @Override
5222    public final void activityDestroyed(IBinder token) {
5223        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5224        synchronized (this) {
5225            ActivityStack stack = ActivityRecord.getStackLocked(token);
5226            if (stack != null) {
5227                stack.activityDestroyedLocked(token);
5228            }
5229        }
5230    }
5231
5232    @Override
5233    public String getCallingPackage(IBinder token) {
5234        synchronized (this) {
5235            ActivityRecord r = getCallingRecordLocked(token);
5236            return r != null ? r.info.packageName : null;
5237        }
5238    }
5239
5240    @Override
5241    public ComponentName getCallingActivity(IBinder token) {
5242        synchronized (this) {
5243            ActivityRecord r = getCallingRecordLocked(token);
5244            return r != null ? r.intent.getComponent() : null;
5245        }
5246    }
5247
5248    private ActivityRecord getCallingRecordLocked(IBinder token) {
5249        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5250        if (r == null) {
5251            return null;
5252        }
5253        return r.resultTo;
5254    }
5255
5256    @Override
5257    public ComponentName getActivityClassForToken(IBinder token) {
5258        synchronized(this) {
5259            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5260            if (r == null) {
5261                return null;
5262            }
5263            return r.intent.getComponent();
5264        }
5265    }
5266
5267    @Override
5268    public String getPackageForToken(IBinder token) {
5269        synchronized(this) {
5270            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5271            if (r == null) {
5272                return null;
5273            }
5274            return r.packageName;
5275        }
5276    }
5277
5278    @Override
5279    public IIntentSender getIntentSender(int type,
5280            String packageName, IBinder token, String resultWho,
5281            int requestCode, Intent[] intents, String[] resolvedTypes,
5282            int flags, Bundle options, int userId) {
5283        enforceNotIsolatedCaller("getIntentSender");
5284        // Refuse possible leaked file descriptors
5285        if (intents != null) {
5286            if (intents.length < 1) {
5287                throw new IllegalArgumentException("Intents array length must be >= 1");
5288            }
5289            for (int i=0; i<intents.length; i++) {
5290                Intent intent = intents[i];
5291                if (intent != null) {
5292                    if (intent.hasFileDescriptors()) {
5293                        throw new IllegalArgumentException("File descriptors passed in Intent");
5294                    }
5295                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5296                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5297                        throw new IllegalArgumentException(
5298                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5299                    }
5300                    intents[i] = new Intent(intent);
5301                }
5302            }
5303            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5304                throw new IllegalArgumentException(
5305                        "Intent array length does not match resolvedTypes length");
5306            }
5307        }
5308        if (options != null) {
5309            if (options.hasFileDescriptors()) {
5310                throw new IllegalArgumentException("File descriptors passed in options");
5311            }
5312        }
5313
5314        synchronized(this) {
5315            int callingUid = Binder.getCallingUid();
5316            int origUserId = userId;
5317            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5318                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5319                    "getIntentSender", null);
5320            if (origUserId == UserHandle.USER_CURRENT) {
5321                // We don't want to evaluate this until the pending intent is
5322                // actually executed.  However, we do want to always do the
5323                // security checking for it above.
5324                userId = UserHandle.USER_CURRENT;
5325            }
5326            try {
5327                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5328                    int uid = AppGlobals.getPackageManager()
5329                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5330                    if (!UserHandle.isSameApp(callingUid, uid)) {
5331                        String msg = "Permission Denial: getIntentSender() from pid="
5332                            + Binder.getCallingPid()
5333                            + ", uid=" + Binder.getCallingUid()
5334                            + ", (need uid=" + uid + ")"
5335                            + " is not allowed to send as package " + packageName;
5336                        Slog.w(TAG, msg);
5337                        throw new SecurityException(msg);
5338                    }
5339                }
5340
5341                return getIntentSenderLocked(type, packageName, callingUid, userId,
5342                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5343
5344            } catch (RemoteException e) {
5345                throw new SecurityException(e);
5346            }
5347        }
5348    }
5349
5350    IIntentSender getIntentSenderLocked(int type, String packageName,
5351            int callingUid, int userId, IBinder token, String resultWho,
5352            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5353            Bundle options) {
5354        if (DEBUG_MU)
5355            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5356        ActivityRecord activity = null;
5357        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5358            activity = ActivityRecord.isInStackLocked(token);
5359            if (activity == null) {
5360                return null;
5361            }
5362            if (activity.finishing) {
5363                return null;
5364            }
5365        }
5366
5367        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5368        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5369        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5370        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5371                |PendingIntent.FLAG_UPDATE_CURRENT);
5372
5373        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5374                type, packageName, activity, resultWho,
5375                requestCode, intents, resolvedTypes, flags, options, userId);
5376        WeakReference<PendingIntentRecord> ref;
5377        ref = mIntentSenderRecords.get(key);
5378        PendingIntentRecord rec = ref != null ? ref.get() : null;
5379        if (rec != null) {
5380            if (!cancelCurrent) {
5381                if (updateCurrent) {
5382                    if (rec.key.requestIntent != null) {
5383                        rec.key.requestIntent.replaceExtras(intents != null ?
5384                                intents[intents.length - 1] : null);
5385                    }
5386                    if (intents != null) {
5387                        intents[intents.length-1] = rec.key.requestIntent;
5388                        rec.key.allIntents = intents;
5389                        rec.key.allResolvedTypes = resolvedTypes;
5390                    } else {
5391                        rec.key.allIntents = null;
5392                        rec.key.allResolvedTypes = null;
5393                    }
5394                }
5395                return rec;
5396            }
5397            rec.canceled = true;
5398            mIntentSenderRecords.remove(key);
5399        }
5400        if (noCreate) {
5401            return rec;
5402        }
5403        rec = new PendingIntentRecord(this, key, callingUid);
5404        mIntentSenderRecords.put(key, rec.ref);
5405        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5406            if (activity.pendingResults == null) {
5407                activity.pendingResults
5408                        = new HashSet<WeakReference<PendingIntentRecord>>();
5409            }
5410            activity.pendingResults.add(rec.ref);
5411        }
5412        return rec;
5413    }
5414
5415    @Override
5416    public void cancelIntentSender(IIntentSender sender) {
5417        if (!(sender instanceof PendingIntentRecord)) {
5418            return;
5419        }
5420        synchronized(this) {
5421            PendingIntentRecord rec = (PendingIntentRecord)sender;
5422            try {
5423                int uid = AppGlobals.getPackageManager()
5424                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5425                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5426                    String msg = "Permission Denial: cancelIntentSender() from pid="
5427                        + Binder.getCallingPid()
5428                        + ", uid=" + Binder.getCallingUid()
5429                        + " is not allowed to cancel packges "
5430                        + rec.key.packageName;
5431                    Slog.w(TAG, msg);
5432                    throw new SecurityException(msg);
5433                }
5434            } catch (RemoteException e) {
5435                throw new SecurityException(e);
5436            }
5437            cancelIntentSenderLocked(rec, true);
5438        }
5439    }
5440
5441    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5442        rec.canceled = true;
5443        mIntentSenderRecords.remove(rec.key);
5444        if (cleanActivity && rec.key.activity != null) {
5445            rec.key.activity.pendingResults.remove(rec.ref);
5446        }
5447    }
5448
5449    @Override
5450    public String getPackageForIntentSender(IIntentSender pendingResult) {
5451        if (!(pendingResult instanceof PendingIntentRecord)) {
5452            return null;
5453        }
5454        try {
5455            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5456            return res.key.packageName;
5457        } catch (ClassCastException e) {
5458        }
5459        return null;
5460    }
5461
5462    @Override
5463    public int getUidForIntentSender(IIntentSender sender) {
5464        if (sender instanceof PendingIntentRecord) {
5465            try {
5466                PendingIntentRecord res = (PendingIntentRecord)sender;
5467                return res.uid;
5468            } catch (ClassCastException e) {
5469            }
5470        }
5471        return -1;
5472    }
5473
5474    @Override
5475    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5476        if (!(pendingResult instanceof PendingIntentRecord)) {
5477            return false;
5478        }
5479        try {
5480            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5481            if (res.key.allIntents == null) {
5482                return false;
5483            }
5484            for (int i=0; i<res.key.allIntents.length; i++) {
5485                Intent intent = res.key.allIntents[i];
5486                if (intent.getPackage() != null && intent.getComponent() != null) {
5487                    return false;
5488                }
5489            }
5490            return true;
5491        } catch (ClassCastException e) {
5492        }
5493        return false;
5494    }
5495
5496    @Override
5497    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5498        if (!(pendingResult instanceof PendingIntentRecord)) {
5499            return false;
5500        }
5501        try {
5502            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5503            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5504                return true;
5505            }
5506            return false;
5507        } catch (ClassCastException e) {
5508        }
5509        return false;
5510    }
5511
5512    @Override
5513    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5514        if (!(pendingResult instanceof PendingIntentRecord)) {
5515            return null;
5516        }
5517        try {
5518            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5519            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5520        } catch (ClassCastException e) {
5521        }
5522        return null;
5523    }
5524
5525    @Override
5526    public void setProcessLimit(int max) {
5527        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5528                "setProcessLimit()");
5529        synchronized (this) {
5530            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5531            mProcessLimitOverride = max;
5532        }
5533        trimApplications();
5534    }
5535
5536    @Override
5537    public int getProcessLimit() {
5538        synchronized (this) {
5539            return mProcessLimitOverride;
5540        }
5541    }
5542
5543    void foregroundTokenDied(ForegroundToken token) {
5544        synchronized (ActivityManagerService.this) {
5545            synchronized (mPidsSelfLocked) {
5546                ForegroundToken cur
5547                    = mForegroundProcesses.get(token.pid);
5548                if (cur != token) {
5549                    return;
5550                }
5551                mForegroundProcesses.remove(token.pid);
5552                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5553                if (pr == null) {
5554                    return;
5555                }
5556                pr.forcingToForeground = null;
5557                pr.foregroundServices = false;
5558            }
5559            updateOomAdjLocked();
5560        }
5561    }
5562
5563    @Override
5564    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5565        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5566                "setProcessForeground()");
5567        synchronized(this) {
5568            boolean changed = false;
5569
5570            synchronized (mPidsSelfLocked) {
5571                ProcessRecord pr = mPidsSelfLocked.get(pid);
5572                if (pr == null && isForeground) {
5573                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5574                    return;
5575                }
5576                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5577                if (oldToken != null) {
5578                    oldToken.token.unlinkToDeath(oldToken, 0);
5579                    mForegroundProcesses.remove(pid);
5580                    if (pr != null) {
5581                        pr.forcingToForeground = null;
5582                    }
5583                    changed = true;
5584                }
5585                if (isForeground && token != null) {
5586                    ForegroundToken newToken = new ForegroundToken() {
5587                        @Override
5588                        public void binderDied() {
5589                            foregroundTokenDied(this);
5590                        }
5591                    };
5592                    newToken.pid = pid;
5593                    newToken.token = token;
5594                    try {
5595                        token.linkToDeath(newToken, 0);
5596                        mForegroundProcesses.put(pid, newToken);
5597                        pr.forcingToForeground = token;
5598                        changed = true;
5599                    } catch (RemoteException e) {
5600                        // If the process died while doing this, we will later
5601                        // do the cleanup with the process death link.
5602                    }
5603                }
5604            }
5605
5606            if (changed) {
5607                updateOomAdjLocked();
5608            }
5609        }
5610    }
5611
5612    // =========================================================
5613    // PERMISSIONS
5614    // =========================================================
5615
5616    static class PermissionController extends IPermissionController.Stub {
5617        ActivityManagerService mActivityManagerService;
5618        PermissionController(ActivityManagerService activityManagerService) {
5619            mActivityManagerService = activityManagerService;
5620        }
5621
5622        @Override
5623        public boolean checkPermission(String permission, int pid, int uid) {
5624            return mActivityManagerService.checkPermission(permission, pid,
5625                    uid) == PackageManager.PERMISSION_GRANTED;
5626        }
5627    }
5628
5629    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5630        @Override
5631        public int checkComponentPermission(String permission, int pid, int uid,
5632                int owningUid, boolean exported) {
5633            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5634                    owningUid, exported);
5635        }
5636
5637        @Override
5638        public Object getAMSLock() {
5639            return ActivityManagerService.this;
5640        }
5641    }
5642
5643    /**
5644     * This can be called with or without the global lock held.
5645     */
5646    int checkComponentPermission(String permission, int pid, int uid,
5647            int owningUid, boolean exported) {
5648        // We might be performing an operation on behalf of an indirect binder
5649        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5650        // client identity accordingly before proceeding.
5651        Identity tlsIdentity = sCallerIdentity.get();
5652        if (tlsIdentity != null) {
5653            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5654                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5655            uid = tlsIdentity.uid;
5656            pid = tlsIdentity.pid;
5657        }
5658
5659        if (pid == MY_PID) {
5660            return PackageManager.PERMISSION_GRANTED;
5661        }
5662
5663        return ActivityManager.checkComponentPermission(permission, uid,
5664                owningUid, exported);
5665    }
5666
5667    /**
5668     * As the only public entry point for permissions checking, this method
5669     * can enforce the semantic that requesting a check on a null global
5670     * permission is automatically denied.  (Internally a null permission
5671     * string is used when calling {@link #checkComponentPermission} in cases
5672     * when only uid-based security is needed.)
5673     *
5674     * This can be called with or without the global lock held.
5675     */
5676    @Override
5677    public int checkPermission(String permission, int pid, int uid) {
5678        if (permission == null) {
5679            return PackageManager.PERMISSION_DENIED;
5680        }
5681        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5682    }
5683
5684    /**
5685     * Binder IPC calls go through the public entry point.
5686     * This can be called with or without the global lock held.
5687     */
5688    int checkCallingPermission(String permission) {
5689        return checkPermission(permission,
5690                Binder.getCallingPid(),
5691                UserHandle.getAppId(Binder.getCallingUid()));
5692    }
5693
5694    /**
5695     * This can be called with or without the global lock held.
5696     */
5697    void enforceCallingPermission(String permission, String func) {
5698        if (checkCallingPermission(permission)
5699                == PackageManager.PERMISSION_GRANTED) {
5700            return;
5701        }
5702
5703        String msg = "Permission Denial: " + func + " from pid="
5704                + Binder.getCallingPid()
5705                + ", uid=" + Binder.getCallingUid()
5706                + " requires " + permission;
5707        Slog.w(TAG, msg);
5708        throw new SecurityException(msg);
5709    }
5710
5711    /**
5712     * Determine if UID is holding permissions required to access {@link Uri} in
5713     * the given {@link ProviderInfo}. Final permission checking is always done
5714     * in {@link ContentProvider}.
5715     */
5716    private final boolean checkHoldingPermissionsLocked(
5717            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5718        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5719                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5720
5721        if (pi.applicationInfo.uid == uid) {
5722            return true;
5723        } else if (!pi.exported) {
5724            return false;
5725        }
5726
5727        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5728        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5729        try {
5730            // check if target holds top-level <provider> permissions
5731            if (!readMet && pi.readPermission != null
5732                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5733                readMet = true;
5734            }
5735            if (!writeMet && pi.writePermission != null
5736                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5737                writeMet = true;
5738            }
5739
5740            // track if unprotected read/write is allowed; any denied
5741            // <path-permission> below removes this ability
5742            boolean allowDefaultRead = pi.readPermission == null;
5743            boolean allowDefaultWrite = pi.writePermission == null;
5744
5745            // check if target holds any <path-permission> that match uri
5746            final PathPermission[] pps = pi.pathPermissions;
5747            if (pps != null) {
5748                final String path = uri.getPath();
5749                int i = pps.length;
5750                while (i > 0 && (!readMet || !writeMet)) {
5751                    i--;
5752                    PathPermission pp = pps[i];
5753                    if (pp.match(path)) {
5754                        if (!readMet) {
5755                            final String pprperm = pp.getReadPermission();
5756                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5757                                    + pprperm + " for " + pp.getPath()
5758                                    + ": match=" + pp.match(path)
5759                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5760                            if (pprperm != null) {
5761                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5762                                    readMet = true;
5763                                } else {
5764                                    allowDefaultRead = false;
5765                                }
5766                            }
5767                        }
5768                        if (!writeMet) {
5769                            final String ppwperm = pp.getWritePermission();
5770                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5771                                    + ppwperm + " for " + pp.getPath()
5772                                    + ": match=" + pp.match(path)
5773                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5774                            if (ppwperm != null) {
5775                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5776                                    writeMet = true;
5777                                } else {
5778                                    allowDefaultWrite = false;
5779                                }
5780                            }
5781                        }
5782                    }
5783                }
5784            }
5785
5786            // grant unprotected <provider> read/write, if not blocked by
5787            // <path-permission> above
5788            if (allowDefaultRead) readMet = true;
5789            if (allowDefaultWrite) writeMet = true;
5790
5791        } catch (RemoteException e) {
5792            return false;
5793        }
5794
5795        return readMet && writeMet;
5796    }
5797
5798    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5799        ProviderInfo pi = null;
5800        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5801        if (cpr != null) {
5802            pi = cpr.info;
5803        } else {
5804            try {
5805                pi = AppGlobals.getPackageManager().resolveContentProvider(
5806                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5807            } catch (RemoteException ex) {
5808            }
5809        }
5810        return pi;
5811    }
5812
5813    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5814        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5815        if (targetUris != null) {
5816            return targetUris.get(uri);
5817        } else {
5818            return null;
5819        }
5820    }
5821
5822    private UriPermission findOrCreateUriPermissionLocked(
5823            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5824        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5825        if (targetUris == null) {
5826            targetUris = Maps.newArrayMap();
5827            mGrantedUriPermissions.put(targetUid, targetUris);
5828        }
5829
5830        UriPermission perm = targetUris.get(uri);
5831        if (perm == null) {
5832            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5833            targetUris.put(uri, perm);
5834        }
5835
5836        return perm;
5837    }
5838
5839    private final boolean checkUriPermissionLocked(
5840            Uri uri, int uid, int modeFlags, int minStrength) {
5841        // Root gets to do everything.
5842        if (uid == 0) {
5843            return true;
5844        }
5845        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5846        if (perms == null) return false;
5847        UriPermission perm = perms.get(uri);
5848        if (perm == null) return false;
5849        return perm.getStrength(modeFlags) >= minStrength;
5850    }
5851
5852    @Override
5853    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5854        enforceNotIsolatedCaller("checkUriPermission");
5855
5856        // Another redirected-binder-call permissions check as in
5857        // {@link checkComponentPermission}.
5858        Identity tlsIdentity = sCallerIdentity.get();
5859        if (tlsIdentity != null) {
5860            uid = tlsIdentity.uid;
5861            pid = tlsIdentity.pid;
5862        }
5863
5864        // Our own process gets to do everything.
5865        if (pid == MY_PID) {
5866            return PackageManager.PERMISSION_GRANTED;
5867        }
5868        synchronized(this) {
5869            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5870                    ? PackageManager.PERMISSION_GRANTED
5871                    : PackageManager.PERMISSION_DENIED;
5872        }
5873    }
5874
5875    /**
5876     * Check if the targetPkg can be granted permission to access uri by
5877     * the callingUid using the given modeFlags.  Throws a security exception
5878     * if callingUid is not allowed to do this.  Returns the uid of the target
5879     * if the URI permission grant should be performed; returns -1 if it is not
5880     * needed (for example targetPkg already has permission to access the URI).
5881     * If you already know the uid of the target, you can supply it in
5882     * lastTargetUid else set that to -1.
5883     */
5884    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5885            Uri uri, int modeFlags, int lastTargetUid) {
5886        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5887        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5888                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5889        if (modeFlags == 0) {
5890            return -1;
5891        }
5892
5893        if (targetPkg != null) {
5894            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5895                    "Checking grant " + targetPkg + " permission to " + uri);
5896        }
5897
5898        final IPackageManager pm = AppGlobals.getPackageManager();
5899
5900        // If this is not a content: uri, we can't do anything with it.
5901        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5902            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5903                    "Can't grant URI permission for non-content URI: " + uri);
5904            return -1;
5905        }
5906
5907        final String authority = uri.getAuthority();
5908        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5909        if (pi == null) {
5910            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5911            return -1;
5912        }
5913
5914        int targetUid = lastTargetUid;
5915        if (targetUid < 0 && targetPkg != null) {
5916            try {
5917                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5918                if (targetUid < 0) {
5919                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5920                            "Can't grant URI permission no uid for: " + targetPkg);
5921                    return -1;
5922                }
5923            } catch (RemoteException ex) {
5924                return -1;
5925            }
5926        }
5927
5928        if (targetUid >= 0) {
5929            // First...  does the target actually need this permission?
5930            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5931                // No need to grant the target this permission.
5932                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5933                        "Target " + targetPkg + " already has full permission to " + uri);
5934                return -1;
5935            }
5936        } else {
5937            // First...  there is no target package, so can anyone access it?
5938            boolean allowed = pi.exported;
5939            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5940                if (pi.readPermission != null) {
5941                    allowed = false;
5942                }
5943            }
5944            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5945                if (pi.writePermission != null) {
5946                    allowed = false;
5947                }
5948            }
5949            if (allowed) {
5950                return -1;
5951            }
5952        }
5953
5954        // Second...  is the provider allowing granting of URI permissions?
5955        if (!pi.grantUriPermissions) {
5956            throw new SecurityException("Provider " + pi.packageName
5957                    + "/" + pi.name
5958                    + " does not allow granting of Uri permissions (uri "
5959                    + uri + ")");
5960        }
5961        if (pi.uriPermissionPatterns != null) {
5962            final int N = pi.uriPermissionPatterns.length;
5963            boolean allowed = false;
5964            for (int i=0; i<N; i++) {
5965                if (pi.uriPermissionPatterns[i] != null
5966                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5967                    allowed = true;
5968                    break;
5969                }
5970            }
5971            if (!allowed) {
5972                throw new SecurityException("Provider " + pi.packageName
5973                        + "/" + pi.name
5974                        + " does not allow granting of permission to path of Uri "
5975                        + uri);
5976            }
5977        }
5978
5979        // Third...  does the caller itself have permission to access
5980        // this uri?
5981        if (callingUid != Process.myUid()) {
5982            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5983                // Require they hold a strong enough Uri permission
5984                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
5985                        : UriPermission.STRENGTH_OWNED;
5986                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
5987                    throw new SecurityException("Uid " + callingUid
5988                            + " does not have permission to uri " + uri);
5989                }
5990            }
5991        }
5992
5993        return targetUid;
5994    }
5995
5996    @Override
5997    public int checkGrantUriPermission(int callingUid, String targetPkg,
5998            Uri uri, int modeFlags) {
5999        enforceNotIsolatedCaller("checkGrantUriPermission");
6000        synchronized(this) {
6001            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6002        }
6003    }
6004
6005    void grantUriPermissionUncheckedLocked(
6006            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6007        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6008        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6009                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6010        if (modeFlags == 0) {
6011            return;
6012        }
6013
6014        // So here we are: the caller has the assumed permission
6015        // to the uri, and the target doesn't.  Let's now give this to
6016        // the target.
6017
6018        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6019                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6020
6021        final String authority = uri.getAuthority();
6022        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6023        if (pi == null) {
6024            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6025            return;
6026        }
6027
6028        final UriPermission perm = findOrCreateUriPermissionLocked(
6029                pi.packageName, targetPkg, targetUid, uri);
6030        perm.grantModes(modeFlags, persistable, owner);
6031    }
6032
6033    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6034            int modeFlags, UriPermissionOwner owner) {
6035        if (targetPkg == null) {
6036            throw new NullPointerException("targetPkg");
6037        }
6038
6039        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6040        if (targetUid < 0) {
6041            return;
6042        }
6043
6044        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6045    }
6046
6047    static class NeededUriGrants extends ArrayList<Uri> {
6048        final String targetPkg;
6049        final int targetUid;
6050        final int flags;
6051
6052        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6053            this.targetPkg = targetPkg;
6054            this.targetUid = targetUid;
6055            this.flags = flags;
6056        }
6057    }
6058
6059    /**
6060     * Like checkGrantUriPermissionLocked, but takes an Intent.
6061     */
6062    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6063            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6064        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6065                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6066                + " clip=" + (intent != null ? intent.getClipData() : null)
6067                + " from " + intent + "; flags=0x"
6068                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6069
6070        if (targetPkg == null) {
6071            throw new NullPointerException("targetPkg");
6072        }
6073
6074        if (intent == null) {
6075            return null;
6076        }
6077        Uri data = intent.getData();
6078        ClipData clip = intent.getClipData();
6079        if (data == null && clip == null) {
6080            return null;
6081        }
6082
6083        if (data != null) {
6084            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6085                mode, needed != null ? needed.targetUid : -1);
6086            if (targetUid > 0) {
6087                if (needed == null) {
6088                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6089                }
6090                needed.add(data);
6091            }
6092        }
6093        if (clip != null) {
6094            for (int i=0; i<clip.getItemCount(); i++) {
6095                Uri uri = clip.getItemAt(i).getUri();
6096                if (uri != null) {
6097                    int targetUid = -1;
6098                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6099                            mode, needed != null ? needed.targetUid : -1);
6100                    if (targetUid > 0) {
6101                        if (needed == null) {
6102                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6103                        }
6104                        needed.add(uri);
6105                    }
6106                } else {
6107                    Intent clipIntent = clip.getItemAt(i).getIntent();
6108                    if (clipIntent != null) {
6109                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6110                                callingUid, targetPkg, clipIntent, mode, needed);
6111                        if (newNeeded != null) {
6112                            needed = newNeeded;
6113                        }
6114                    }
6115                }
6116            }
6117        }
6118
6119        return needed;
6120    }
6121
6122    /**
6123     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6124     */
6125    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6126            UriPermissionOwner owner) {
6127        if (needed != null) {
6128            for (int i=0; i<needed.size(); i++) {
6129                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6130                        needed.get(i), needed.flags, owner);
6131            }
6132        }
6133    }
6134
6135    void grantUriPermissionFromIntentLocked(int callingUid,
6136            String targetPkg, Intent intent, UriPermissionOwner owner) {
6137        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6138                intent, intent != null ? intent.getFlags() : 0, null);
6139        if (needed == null) {
6140            return;
6141        }
6142
6143        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6144    }
6145
6146    @Override
6147    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6148            Uri uri, int modeFlags) {
6149        enforceNotIsolatedCaller("grantUriPermission");
6150        synchronized(this) {
6151            final ProcessRecord r = getRecordForAppLocked(caller);
6152            if (r == null) {
6153                throw new SecurityException("Unable to find app for caller "
6154                        + caller
6155                        + " when granting permission to uri " + uri);
6156            }
6157            if (targetPkg == null) {
6158                throw new IllegalArgumentException("null target");
6159            }
6160            if (uri == null) {
6161                throw new IllegalArgumentException("null uri");
6162            }
6163
6164            // Persistable only supported through Intents
6165            Preconditions.checkFlagsArgument(modeFlags,
6166                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6167
6168            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6169                    null);
6170        }
6171    }
6172
6173    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6174        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6175                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6176            ArrayMap<Uri, UriPermission> perms
6177                    = mGrantedUriPermissions.get(perm.targetUid);
6178            if (perms != null) {
6179                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6180                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6181                perms.remove(perm.uri);
6182                if (perms.size() == 0) {
6183                    mGrantedUriPermissions.remove(perm.targetUid);
6184                }
6185            }
6186        }
6187    }
6188
6189    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6190        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6191
6192        final IPackageManager pm = AppGlobals.getPackageManager();
6193        final String authority = uri.getAuthority();
6194        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6195        if (pi == null) {
6196            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6197            return;
6198        }
6199
6200        // Does the caller have this permission on the URI?
6201        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6202            // Right now, if you are not the original owner of the permission,
6203            // you are not allowed to revoke it.
6204            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6205                throw new SecurityException("Uid " + callingUid
6206                        + " does not have permission to uri " + uri);
6207            //}
6208        }
6209
6210        boolean persistChanged = false;
6211
6212        // Go through all of the permissions and remove any that match.
6213        final List<String> SEGMENTS = uri.getPathSegments();
6214        if (SEGMENTS != null) {
6215            final int NS = SEGMENTS.size();
6216            int N = mGrantedUriPermissions.size();
6217            for (int i=0; i<N; i++) {
6218                ArrayMap<Uri, UriPermission> perms
6219                        = mGrantedUriPermissions.valueAt(i);
6220                Iterator<UriPermission> it = perms.values().iterator();
6221            toploop:
6222                while (it.hasNext()) {
6223                    UriPermission perm = it.next();
6224                    Uri targetUri = perm.uri;
6225                    if (!authority.equals(targetUri.getAuthority())) {
6226                        continue;
6227                    }
6228                    List<String> targetSegments = targetUri.getPathSegments();
6229                    if (targetSegments == null) {
6230                        continue;
6231                    }
6232                    if (targetSegments.size() < NS) {
6233                        continue;
6234                    }
6235                    for (int j=0; j<NS; j++) {
6236                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6237                            continue toploop;
6238                        }
6239                    }
6240                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6241                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6242                    persistChanged |= perm.clearModes(modeFlags, true);
6243                    if (perm.modeFlags == 0) {
6244                        it.remove();
6245                    }
6246                }
6247                if (perms.size() == 0) {
6248                    mGrantedUriPermissions.remove(
6249                            mGrantedUriPermissions.keyAt(i));
6250                    N--;
6251                    i--;
6252                }
6253            }
6254        }
6255
6256        if (persistChanged) {
6257            schedulePersistUriGrants();
6258        }
6259    }
6260
6261    @Override
6262    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6263            int modeFlags) {
6264        enforceNotIsolatedCaller("revokeUriPermission");
6265        synchronized(this) {
6266            final ProcessRecord r = getRecordForAppLocked(caller);
6267            if (r == null) {
6268                throw new SecurityException("Unable to find app for caller "
6269                        + caller
6270                        + " when revoking permission to uri " + uri);
6271            }
6272            if (uri == null) {
6273                Slog.w(TAG, "revokeUriPermission: null uri");
6274                return;
6275            }
6276
6277            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6278                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6279            if (modeFlags == 0) {
6280                return;
6281            }
6282
6283            final IPackageManager pm = AppGlobals.getPackageManager();
6284            final String authority = uri.getAuthority();
6285            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6286            if (pi == null) {
6287                Slog.w(TAG, "No content provider found for permission revoke: "
6288                        + uri.toSafeString());
6289                return;
6290            }
6291
6292            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6293        }
6294    }
6295
6296    /**
6297     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6298     * given package.
6299     *
6300     * @param packageName Package name to match, or {@code null} to apply to all
6301     *            packages.
6302     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6303     *            to all users.
6304     * @param persistable If persistable grants should be removed.
6305     */
6306    private void removeUriPermissionsForPackageLocked(
6307            String packageName, int userHandle, boolean persistable) {
6308        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6309            throw new IllegalArgumentException("Must narrow by either package or user");
6310        }
6311
6312        boolean persistChanged = false;
6313
6314        final int size = mGrantedUriPermissions.size();
6315        for (int i = 0; i < size; i++) {
6316            // Only inspect grants matching user
6317            if (userHandle == UserHandle.USER_ALL
6318                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6319                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6320                        .values().iterator();
6321                while (it.hasNext()) {
6322                    final UriPermission perm = it.next();
6323
6324                    // Only inspect grants matching package
6325                    if (packageName == null || perm.sourcePkg.equals(packageName)
6326                            || perm.targetPkg.equals(packageName)) {
6327                        persistChanged |= perm.clearModes(~0, persistable);
6328
6329                        // Only remove when no modes remain; any persisted grants
6330                        // will keep this alive.
6331                        if (perm.modeFlags == 0) {
6332                            it.remove();
6333                        }
6334                    }
6335                }
6336            }
6337        }
6338
6339        if (persistChanged) {
6340            schedulePersistUriGrants();
6341        }
6342    }
6343
6344    @Override
6345    public IBinder newUriPermissionOwner(String name) {
6346        enforceNotIsolatedCaller("newUriPermissionOwner");
6347        synchronized(this) {
6348            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6349            return owner.getExternalTokenLocked();
6350        }
6351    }
6352
6353    @Override
6354    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6355            Uri uri, int modeFlags) {
6356        synchronized(this) {
6357            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6358            if (owner == null) {
6359                throw new IllegalArgumentException("Unknown owner: " + token);
6360            }
6361            if (fromUid != Binder.getCallingUid()) {
6362                if (Binder.getCallingUid() != Process.myUid()) {
6363                    // Only system code can grant URI permissions on behalf
6364                    // of other users.
6365                    throw new SecurityException("nice try");
6366                }
6367            }
6368            if (targetPkg == null) {
6369                throw new IllegalArgumentException("null target");
6370            }
6371            if (uri == null) {
6372                throw new IllegalArgumentException("null uri");
6373            }
6374
6375            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6376        }
6377    }
6378
6379    @Override
6380    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6381        synchronized(this) {
6382            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6383            if (owner == null) {
6384                throw new IllegalArgumentException("Unknown owner: " + token);
6385            }
6386
6387            if (uri == null) {
6388                owner.removeUriPermissionsLocked(mode);
6389            } else {
6390                owner.removeUriPermissionLocked(uri, mode);
6391            }
6392        }
6393    }
6394
6395    private void schedulePersistUriGrants() {
6396        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6397            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6398                    10 * DateUtils.SECOND_IN_MILLIS);
6399        }
6400    }
6401
6402    private void writeGrantedUriPermissions() {
6403        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6404
6405        // Snapshot permissions so we can persist without lock
6406        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6407        synchronized (this) {
6408            final int size = mGrantedUriPermissions.size();
6409            for (int i = 0 ; i < size; i++) {
6410                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6411                    if (perm.persistedModeFlags != 0) {
6412                        persist.add(perm.snapshot());
6413                    }
6414                }
6415            }
6416        }
6417
6418        FileOutputStream fos = null;
6419        try {
6420            fos = mGrantFile.startWrite();
6421
6422            XmlSerializer out = new FastXmlSerializer();
6423            out.setOutput(fos, "utf-8");
6424            out.startDocument(null, true);
6425            out.startTag(null, TAG_URI_GRANTS);
6426            for (UriPermission.Snapshot perm : persist) {
6427                out.startTag(null, TAG_URI_GRANT);
6428                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6429                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6430                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6431                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6432                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6433                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6434                out.endTag(null, TAG_URI_GRANT);
6435            }
6436            out.endTag(null, TAG_URI_GRANTS);
6437            out.endDocument();
6438
6439            mGrantFile.finishWrite(fos);
6440        } catch (IOException e) {
6441            if (fos != null) {
6442                mGrantFile.failWrite(fos);
6443            }
6444        }
6445    }
6446
6447    private void readGrantedUriPermissionsLocked() {
6448        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6449
6450        final long now = System.currentTimeMillis();
6451
6452        FileInputStream fis = null;
6453        try {
6454            fis = mGrantFile.openRead();
6455            final XmlPullParser in = Xml.newPullParser();
6456            in.setInput(fis, null);
6457
6458            int type;
6459            while ((type = in.next()) != END_DOCUMENT) {
6460                final String tag = in.getName();
6461                if (type == START_TAG) {
6462                    if (TAG_URI_GRANT.equals(tag)) {
6463                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6464                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6465                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6466                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6467                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6468                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6469
6470                        // Sanity check that provider still belongs to source package
6471                        final ProviderInfo pi = getProviderInfoLocked(
6472                                uri.getAuthority(), userHandle);
6473                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6474                            int targetUid = -1;
6475                            try {
6476                                targetUid = AppGlobals.getPackageManager()
6477                                        .getPackageUid(targetPkg, userHandle);
6478                            } catch (RemoteException e) {
6479                            }
6480                            if (targetUid != -1) {
6481                                final UriPermission perm = findOrCreateUriPermissionLocked(
6482                                        sourcePkg, targetPkg, targetUid, uri);
6483                                perm.initPersistedModes(modeFlags, createdTime);
6484                            }
6485                        } else {
6486                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6487                                    + " but instead found " + pi);
6488                        }
6489                    }
6490                }
6491            }
6492        } catch (FileNotFoundException e) {
6493            // Missing grants is okay
6494        } catch (IOException e) {
6495            Log.wtf(TAG, "Failed reading Uri grants", e);
6496        } catch (XmlPullParserException e) {
6497            Log.wtf(TAG, "Failed reading Uri grants", e);
6498        } finally {
6499            IoUtils.closeQuietly(fis);
6500        }
6501    }
6502
6503    @Override
6504    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6505        enforceNotIsolatedCaller("takePersistableUriPermission");
6506
6507        Preconditions.checkFlagsArgument(modeFlags,
6508                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6509
6510        synchronized (this) {
6511            final int callingUid = Binder.getCallingUid();
6512            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6513            if (perm == null) {
6514                throw new SecurityException("No permission grant found for UID " + callingUid
6515                        + " and Uri " + uri.toSafeString());
6516            }
6517
6518            boolean persistChanged = perm.takePersistableModes(modeFlags);
6519            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6520
6521            if (persistChanged) {
6522                schedulePersistUriGrants();
6523            }
6524        }
6525    }
6526
6527    @Override
6528    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6529        enforceNotIsolatedCaller("releasePersistableUriPermission");
6530
6531        Preconditions.checkFlagsArgument(modeFlags,
6532                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6533
6534        synchronized (this) {
6535            final int callingUid = Binder.getCallingUid();
6536
6537            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6538            if (perm == null) {
6539                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6540                        + uri.toSafeString());
6541                return;
6542            }
6543
6544            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6545            removeUriPermissionIfNeededLocked(perm);
6546            if (persistChanged) {
6547                schedulePersistUriGrants();
6548            }
6549        }
6550    }
6551
6552    /**
6553     * Prune any older {@link UriPermission} for the given UID until outstanding
6554     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6555     *
6556     * @return if any mutations occured that require persisting.
6557     */
6558    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6559        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6560        if (perms == null) return false;
6561        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6562
6563        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6564        for (UriPermission perm : perms.values()) {
6565            if (perm.persistedModeFlags != 0) {
6566                persisted.add(perm);
6567            }
6568        }
6569
6570        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6571        if (trimCount <= 0) return false;
6572
6573        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6574        for (int i = 0; i < trimCount; i++) {
6575            final UriPermission perm = persisted.get(i);
6576
6577            if (DEBUG_URI_PERMISSION) {
6578                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6579            }
6580
6581            perm.releasePersistableModes(~0);
6582            removeUriPermissionIfNeededLocked(perm);
6583        }
6584
6585        return true;
6586    }
6587
6588    @Override
6589    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6590            String packageName, boolean incoming) {
6591        enforceNotIsolatedCaller("getPersistedUriPermissions");
6592        Preconditions.checkNotNull(packageName, "packageName");
6593
6594        final int callingUid = Binder.getCallingUid();
6595        final IPackageManager pm = AppGlobals.getPackageManager();
6596        try {
6597            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6598            if (packageUid != callingUid) {
6599                throw new SecurityException(
6600                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6601            }
6602        } catch (RemoteException e) {
6603            throw new SecurityException("Failed to verify package name ownership");
6604        }
6605
6606        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6607        synchronized (this) {
6608            if (incoming) {
6609                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6610                if (perms == null) {
6611                    Slog.w(TAG, "No permission grants found for " + packageName);
6612                } else {
6613                    final int size = perms.size();
6614                    for (int i = 0; i < size; i++) {
6615                        final UriPermission perm = perms.valueAt(i);
6616                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6617                            result.add(perm.buildPersistedPublicApiObject());
6618                        }
6619                    }
6620                }
6621            } else {
6622                final int size = mGrantedUriPermissions.size();
6623                for (int i = 0; i < size; i++) {
6624                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6625                    final int permsSize = perms.size();
6626                    for (int j = 0; j < permsSize; j++) {
6627                        final UriPermission perm = perms.valueAt(j);
6628                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6629                            result.add(perm.buildPersistedPublicApiObject());
6630                        }
6631                    }
6632                }
6633            }
6634        }
6635        return new ParceledListSlice<android.content.UriPermission>(result);
6636    }
6637
6638    @Override
6639    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6640        synchronized (this) {
6641            ProcessRecord app =
6642                who != null ? getRecordForAppLocked(who) : null;
6643            if (app == null) return;
6644
6645            Message msg = Message.obtain();
6646            msg.what = WAIT_FOR_DEBUGGER_MSG;
6647            msg.obj = app;
6648            msg.arg1 = waiting ? 1 : 0;
6649            mHandler.sendMessage(msg);
6650        }
6651    }
6652
6653    @Override
6654    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6655        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6656        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6657        outInfo.availMem = Process.getFreeMemory();
6658        outInfo.totalMem = Process.getTotalMemory();
6659        outInfo.threshold = homeAppMem;
6660        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6661        outInfo.hiddenAppThreshold = cachedAppMem;
6662        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6663                ProcessList.SERVICE_ADJ);
6664        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6665                ProcessList.VISIBLE_APP_ADJ);
6666        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6667                ProcessList.FOREGROUND_APP_ADJ);
6668    }
6669
6670    // =========================================================
6671    // TASK MANAGEMENT
6672    // =========================================================
6673
6674    @Override
6675    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6676                         IThumbnailReceiver receiver) {
6677        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6678
6679        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6680        ActivityRecord topRecord = null;
6681
6682        synchronized(this) {
6683            if (localLOGV) Slog.v(
6684                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6685                + ", receiver=" + receiver);
6686
6687            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6688                    != PackageManager.PERMISSION_GRANTED) {
6689                if (receiver != null) {
6690                    // If the caller wants to wait for pending thumbnails,
6691                    // it ain't gonna get them.
6692                    try {
6693                        receiver.finished();
6694                    } catch (RemoteException ex) {
6695                    }
6696                }
6697                String msg = "Permission Denial: getTasks() from pid="
6698                        + Binder.getCallingPid()
6699                        + ", uid=" + Binder.getCallingUid()
6700                        + " requires " + android.Manifest.permission.GET_TASKS;
6701                Slog.w(TAG, msg);
6702                throw new SecurityException(msg);
6703            }
6704
6705            // TODO: Improve with MRU list from all ActivityStacks.
6706            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6707
6708            if (!pending.pendingRecords.isEmpty()) {
6709                mPendingThumbnails.add(pending);
6710            }
6711        }
6712
6713        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6714
6715        if (topRecord != null) {
6716            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6717            try {
6718                IApplicationThread topThumbnail = topRecord.app.thread;
6719                topThumbnail.requestThumbnail(topRecord.appToken);
6720            } catch (Exception e) {
6721                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6722                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6723            }
6724        }
6725
6726        if (pending == null && receiver != null) {
6727            // In this case all thumbnails were available and the client
6728            // is being asked to be told when the remaining ones come in...
6729            // which is unusually, since the top-most currently running
6730            // activity should never have a canned thumbnail!  Oh well.
6731            try {
6732                receiver.finished();
6733            } catch (RemoteException ex) {
6734            }
6735        }
6736
6737        return list;
6738    }
6739
6740    TaskRecord getMostRecentTask() {
6741        return mRecentTasks.get(0);
6742    }
6743
6744    @Override
6745    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6746            int flags, int userId) {
6747        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6748                false, true, "getRecentTasks", null);
6749
6750        synchronized (this) {
6751            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6752                    "getRecentTasks()");
6753            final boolean detailed = checkCallingPermission(
6754                    android.Manifest.permission.GET_DETAILED_TASKS)
6755                    == PackageManager.PERMISSION_GRANTED;
6756
6757            IPackageManager pm = AppGlobals.getPackageManager();
6758
6759            final int N = mRecentTasks.size();
6760            ArrayList<ActivityManager.RecentTaskInfo> res
6761                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6762                            maxNum < N ? maxNum : N);
6763            for (int i=0; i<N && maxNum > 0; i++) {
6764                TaskRecord tr = mRecentTasks.get(i);
6765                // Only add calling user's recent tasks
6766                if (tr.userId != userId) continue;
6767                // Return the entry if desired by the caller.  We always return
6768                // the first entry, because callers always expect this to be the
6769                // foreground app.  We may filter others if the caller has
6770                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6771                // we should exclude the entry.
6772
6773                if (i == 0
6774                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6775                        || (tr.intent == null)
6776                        || ((tr.intent.getFlags()
6777                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6778                    ActivityManager.RecentTaskInfo rti
6779                            = new ActivityManager.RecentTaskInfo();
6780                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6781                    rti.persistentId = tr.taskId;
6782                    rti.baseIntent = new Intent(
6783                            tr.intent != null ? tr.intent : tr.affinityIntent);
6784                    if (!detailed) {
6785                        rti.baseIntent.replaceExtras((Bundle)null);
6786                    }
6787                    rti.origActivity = tr.origActivity;
6788                    rti.description = tr.lastDescription;
6789                    rti.stackId = tr.stack.mStackId;
6790
6791                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6792                        // Check whether this activity is currently available.
6793                        try {
6794                            if (rti.origActivity != null) {
6795                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6796                                        == null) {
6797                                    continue;
6798                                }
6799                            } else if (rti.baseIntent != null) {
6800                                if (pm.queryIntentActivities(rti.baseIntent,
6801                                        null, 0, userId) == null) {
6802                                    continue;
6803                                }
6804                            }
6805                        } catch (RemoteException e) {
6806                            // Will never happen.
6807                        }
6808                    }
6809
6810                    res.add(rti);
6811                    maxNum--;
6812                }
6813            }
6814            return res;
6815        }
6816    }
6817
6818    private TaskRecord recentTaskForIdLocked(int id) {
6819        final int N = mRecentTasks.size();
6820            for (int i=0; i<N; i++) {
6821                TaskRecord tr = mRecentTasks.get(i);
6822                if (tr.taskId == id) {
6823                    return tr;
6824                }
6825            }
6826            return null;
6827    }
6828
6829    @Override
6830    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6831        synchronized (this) {
6832            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6833                    "getTaskThumbnails()");
6834            TaskRecord tr = recentTaskForIdLocked(id);
6835            if (tr != null) {
6836                return tr.getTaskThumbnailsLocked();
6837            }
6838        }
6839        return null;
6840    }
6841
6842    @Override
6843    public Bitmap getTaskTopThumbnail(int id) {
6844        synchronized (this) {
6845            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6846                    "getTaskTopThumbnail()");
6847            TaskRecord tr = recentTaskForIdLocked(id);
6848            if (tr != null) {
6849                return tr.getTaskTopThumbnailLocked();
6850            }
6851        }
6852        return null;
6853    }
6854
6855    @Override
6856    public boolean removeSubTask(int taskId, int subTaskIndex) {
6857        synchronized (this) {
6858            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6859                    "removeSubTask()");
6860            long ident = Binder.clearCallingIdentity();
6861            try {
6862                TaskRecord tr = recentTaskForIdLocked(taskId);
6863                if (tr != null) {
6864                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6865                }
6866                return false;
6867            } finally {
6868                Binder.restoreCallingIdentity(ident);
6869            }
6870        }
6871    }
6872
6873    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6874        if (!pr.killedByAm) {
6875            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6876            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6877                    pr.processName, pr.setAdj, reason);
6878            pr.killedByAm = true;
6879            Process.killProcessQuiet(pr.pid);
6880        }
6881    }
6882
6883    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6884        tr.disposeThumbnail();
6885        mRecentTasks.remove(tr);
6886        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6887        Intent baseIntent = new Intent(
6888                tr.intent != null ? tr.intent : tr.affinityIntent);
6889        ComponentName component = baseIntent.getComponent();
6890        if (component == null) {
6891            Slog.w(TAG, "Now component for base intent of task: " + tr);
6892            return;
6893        }
6894
6895        // Find any running services associated with this app.
6896        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6897
6898        if (killProcesses) {
6899            // Find any running processes associated with this app.
6900            final String pkg = component.getPackageName();
6901            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6902            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6903            for (int i=0; i<pmap.size(); i++) {
6904                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6905                for (int j=0; j<uids.size(); j++) {
6906                    ProcessRecord proc = uids.valueAt(j);
6907                    if (proc.userId != tr.userId) {
6908                        continue;
6909                    }
6910                    if (!proc.pkgList.containsKey(pkg)) {
6911                        continue;
6912                    }
6913                    procs.add(proc);
6914                }
6915            }
6916
6917            // Kill the running processes.
6918            for (int i=0; i<procs.size(); i++) {
6919                ProcessRecord pr = procs.get(i);
6920                if (pr == mHomeProcess) {
6921                    // Don't kill the home process along with tasks from the same package.
6922                    continue;
6923                }
6924                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6925                    killUnneededProcessLocked(pr, "remove task");
6926                } else {
6927                    pr.waitingToKill = "remove task";
6928                }
6929            }
6930        }
6931    }
6932
6933    @Override
6934    public boolean removeTask(int taskId, int flags) {
6935        synchronized (this) {
6936            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6937                    "removeTask()");
6938            long ident = Binder.clearCallingIdentity();
6939            try {
6940                TaskRecord tr = recentTaskForIdLocked(taskId);
6941                if (tr != null) {
6942                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6943                    if (r != null) {
6944                        cleanUpRemovedTaskLocked(tr, flags);
6945                        return true;
6946                    }
6947                    if (tr.mActivities.size() == 0) {
6948                        // Caller is just removing a recent task that is
6949                        // not actively running.  That is easy!
6950                        cleanUpRemovedTaskLocked(tr, flags);
6951                        return true;
6952                    }
6953                    Slog.w(TAG, "removeTask: task " + taskId
6954                            + " does not have activities to remove, "
6955                            + " but numActivities=" + tr.numActivities
6956                            + ": " + tr);
6957                }
6958            } finally {
6959                Binder.restoreCallingIdentity(ident);
6960            }
6961        }
6962        return false;
6963    }
6964
6965    /**
6966     * TODO: Add mController hook
6967     */
6968    @Override
6969    public void moveTaskToFront(int task, int flags, Bundle options) {
6970        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6971                "moveTaskToFront()");
6972
6973        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
6974        synchronized(this) {
6975            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6976                    Binder.getCallingUid(), "Task to front")) {
6977                ActivityOptions.abort(options);
6978                return;
6979            }
6980            final long origId = Binder.clearCallingIdentity();
6981            try {
6982                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
6983            } finally {
6984                Binder.restoreCallingIdentity(origId);
6985            }
6986            ActivityOptions.abort(options);
6987        }
6988    }
6989
6990    @Override
6991    public void moveTaskToBack(int taskId) {
6992        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6993                "moveTaskToBack()");
6994
6995        synchronized(this) {
6996            TaskRecord tr = recentTaskForIdLocked(taskId);
6997            if (tr != null) {
6998                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
6999                ActivityStack stack = tr.stack;
7000                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7001                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7002                            Binder.getCallingUid(), "Task to back")) {
7003                        return;
7004                    }
7005                }
7006                final long origId = Binder.clearCallingIdentity();
7007                try {
7008                    stack.moveTaskToBackLocked(taskId, null);
7009                } finally {
7010                    Binder.restoreCallingIdentity(origId);
7011                }
7012            }
7013        }
7014    }
7015
7016    /**
7017     * Moves an activity, and all of the other activities within the same task, to the bottom
7018     * of the history stack.  The activity's order within the task is unchanged.
7019     *
7020     * @param token A reference to the activity we wish to move
7021     * @param nonRoot If false then this only works if the activity is the root
7022     *                of a task; if true it will work for any activity in a task.
7023     * @return Returns true if the move completed, false if not.
7024     */
7025    @Override
7026    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7027        enforceNotIsolatedCaller("moveActivityTaskToBack");
7028        synchronized(this) {
7029            final long origId = Binder.clearCallingIdentity();
7030            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7031            if (taskId >= 0) {
7032                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7033            }
7034            Binder.restoreCallingIdentity(origId);
7035        }
7036        return false;
7037    }
7038
7039    @Override
7040    public void moveTaskBackwards(int task) {
7041        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7042                "moveTaskBackwards()");
7043
7044        synchronized(this) {
7045            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7046                    Binder.getCallingUid(), "Task backwards")) {
7047                return;
7048            }
7049            final long origId = Binder.clearCallingIdentity();
7050            moveTaskBackwardsLocked(task);
7051            Binder.restoreCallingIdentity(origId);
7052        }
7053    }
7054
7055    private final void moveTaskBackwardsLocked(int task) {
7056        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7057    }
7058
7059    @Override
7060    public IBinder getHomeActivityToken() throws RemoteException {
7061        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7062                "getHomeActivityToken()");
7063        synchronized (this) {
7064            return mStackSupervisor.getHomeActivityToken();
7065        }
7066    }
7067
7068    @Override
7069    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7070            IActivityContainerCallback callback) throws RemoteException {
7071        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7072                "createActivityContainer()");
7073        synchronized (this) {
7074            if (parentActivityToken == null) {
7075                throw new IllegalArgumentException("parent token must not be null");
7076            }
7077            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7078            if (r == null) {
7079                return null;
7080            }
7081            return mStackSupervisor.createActivityContainer(r, callback);
7082        }
7083    }
7084
7085    @Override
7086    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7087            throws RemoteException {
7088        synchronized (this) {
7089            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7090            if (stack != null) {
7091                return stack.mActivityContainer;
7092            }
7093            return null;
7094        }
7095    }
7096
7097    @Override
7098    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7099        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7100                "moveTaskToStack()");
7101        if (stackId == HOME_STACK_ID) {
7102            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7103                    new RuntimeException("here").fillInStackTrace());
7104        }
7105        synchronized (this) {
7106            long ident = Binder.clearCallingIdentity();
7107            try {
7108                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7109                        + stackId + " toTop=" + toTop);
7110                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7111            } finally {
7112                Binder.restoreCallingIdentity(ident);
7113            }
7114        }
7115    }
7116
7117    @Override
7118    public void resizeStack(int stackBoxId, Rect bounds) {
7119        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7120                "resizeStackBox()");
7121        long ident = Binder.clearCallingIdentity();
7122        try {
7123            mWindowManager.resizeStack(stackBoxId, bounds);
7124        } finally {
7125            Binder.restoreCallingIdentity(ident);
7126        }
7127    }
7128
7129    @Override
7130    public List<StackInfo> getAllStackInfos() {
7131        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7132                "getAllStackInfos()");
7133        long ident = Binder.clearCallingIdentity();
7134        try {
7135            synchronized (this) {
7136                return mStackSupervisor.getAllStackInfosLocked();
7137            }
7138        } finally {
7139            Binder.restoreCallingIdentity(ident);
7140        }
7141    }
7142
7143    @Override
7144    public StackInfo getStackInfo(int stackId) {
7145        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7146                "getStackInfo()");
7147        long ident = Binder.clearCallingIdentity();
7148        try {
7149            synchronized (this) {
7150                return mStackSupervisor.getStackInfoLocked(stackId);
7151            }
7152        } finally {
7153            Binder.restoreCallingIdentity(ident);
7154        }
7155    }
7156
7157    @Override
7158    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7159        synchronized(this) {
7160            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7161        }
7162    }
7163
7164    // =========================================================
7165    // THUMBNAILS
7166    // =========================================================
7167
7168    public void reportThumbnail(IBinder token,
7169            Bitmap thumbnail, CharSequence description) {
7170        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7171        final long origId = Binder.clearCallingIdentity();
7172        sendPendingThumbnail(null, token, thumbnail, description, true);
7173        Binder.restoreCallingIdentity(origId);
7174    }
7175
7176    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7177            Bitmap thumbnail, CharSequence description, boolean always) {
7178        TaskRecord task;
7179        ArrayList<PendingThumbnailsRecord> receivers = null;
7180
7181        //System.out.println("Send pending thumbnail: " + r);
7182
7183        synchronized(this) {
7184            if (r == null) {
7185                r = ActivityRecord.isInStackLocked(token);
7186                if (r == null) {
7187                    return;
7188                }
7189            }
7190            if (thumbnail == null && r.thumbHolder != null) {
7191                thumbnail = r.thumbHolder.lastThumbnail;
7192                description = r.thumbHolder.lastDescription;
7193            }
7194            if (thumbnail == null && !always) {
7195                // If there is no thumbnail, and this entry is not actually
7196                // going away, then abort for now and pick up the next
7197                // thumbnail we get.
7198                return;
7199            }
7200            task = r.task;
7201
7202            int N = mPendingThumbnails.size();
7203            int i=0;
7204            while (i<N) {
7205                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7206                //System.out.println("Looking in " + pr.pendingRecords);
7207                if (pr.pendingRecords.remove(r)) {
7208                    if (receivers == null) {
7209                        receivers = new ArrayList<PendingThumbnailsRecord>();
7210                    }
7211                    receivers.add(pr);
7212                    if (pr.pendingRecords.size() == 0) {
7213                        pr.finished = true;
7214                        mPendingThumbnails.remove(i);
7215                        N--;
7216                        continue;
7217                    }
7218                }
7219                i++;
7220            }
7221        }
7222
7223        if (receivers != null) {
7224            final int N = receivers.size();
7225            for (int i=0; i<N; i++) {
7226                try {
7227                    PendingThumbnailsRecord pr = receivers.get(i);
7228                    pr.receiver.newThumbnail(
7229                        task != null ? task.taskId : -1, thumbnail, description);
7230                    if (pr.finished) {
7231                        pr.receiver.finished();
7232                    }
7233                } catch (Exception e) {
7234                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7235                }
7236            }
7237        }
7238    }
7239
7240    // =========================================================
7241    // CONTENT PROVIDERS
7242    // =========================================================
7243
7244    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7245        List<ProviderInfo> providers = null;
7246        try {
7247            providers = AppGlobals.getPackageManager().
7248                queryContentProviders(app.processName, app.uid,
7249                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7250        } catch (RemoteException ex) {
7251        }
7252        if (DEBUG_MU)
7253            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7254        int userId = app.userId;
7255        if (providers != null) {
7256            int N = providers.size();
7257            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7258            for (int i=0; i<N; i++) {
7259                ProviderInfo cpi =
7260                    (ProviderInfo)providers.get(i);
7261                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7262                        cpi.name, cpi.flags);
7263                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7264                    // This is a singleton provider, but a user besides the
7265                    // default user is asking to initialize a process it runs
7266                    // in...  well, no, it doesn't actually run in this process,
7267                    // it runs in the process of the default user.  Get rid of it.
7268                    providers.remove(i);
7269                    N--;
7270                    i--;
7271                    continue;
7272                }
7273
7274                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7275                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7276                if (cpr == null) {
7277                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7278                    mProviderMap.putProviderByClass(comp, cpr);
7279                }
7280                if (DEBUG_MU)
7281                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7282                app.pubProviders.put(cpi.name, cpr);
7283                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7284                    // Don't add this if it is a platform component that is marked
7285                    // to run in multiple processes, because this is actually
7286                    // part of the framework so doesn't make sense to track as a
7287                    // separate apk in the process.
7288                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7289                }
7290                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7291            }
7292        }
7293        return providers;
7294    }
7295
7296    /**
7297     * Check if {@link ProcessRecord} has a possible chance at accessing the
7298     * given {@link ProviderInfo}. Final permission checking is always done
7299     * in {@link ContentProvider}.
7300     */
7301    private final String checkContentProviderPermissionLocked(
7302            ProviderInfo cpi, ProcessRecord r) {
7303        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7304        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7305        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7306                cpi.applicationInfo.uid, cpi.exported)
7307                == PackageManager.PERMISSION_GRANTED) {
7308            return null;
7309        }
7310        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7311                cpi.applicationInfo.uid, cpi.exported)
7312                == PackageManager.PERMISSION_GRANTED) {
7313            return null;
7314        }
7315
7316        PathPermission[] pps = cpi.pathPermissions;
7317        if (pps != null) {
7318            int i = pps.length;
7319            while (i > 0) {
7320                i--;
7321                PathPermission pp = pps[i];
7322                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7323                        cpi.applicationInfo.uid, cpi.exported)
7324                        == PackageManager.PERMISSION_GRANTED) {
7325                    return null;
7326                }
7327                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7328                        cpi.applicationInfo.uid, cpi.exported)
7329                        == PackageManager.PERMISSION_GRANTED) {
7330                    return null;
7331                }
7332            }
7333        }
7334
7335        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7336        if (perms != null) {
7337            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7338                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7339                    return null;
7340                }
7341            }
7342        }
7343
7344        String msg;
7345        if (!cpi.exported) {
7346            msg = "Permission Denial: opening provider " + cpi.name
7347                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7348                    + ", uid=" + callingUid + ") that is not exported from uid "
7349                    + cpi.applicationInfo.uid;
7350        } else {
7351            msg = "Permission Denial: opening provider " + cpi.name
7352                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7353                    + ", uid=" + callingUid + ") requires "
7354                    + cpi.readPermission + " or " + cpi.writePermission;
7355        }
7356        Slog.w(TAG, msg);
7357        return msg;
7358    }
7359
7360    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7361            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7362        if (r != null) {
7363            for (int i=0; i<r.conProviders.size(); i++) {
7364                ContentProviderConnection conn = r.conProviders.get(i);
7365                if (conn.provider == cpr) {
7366                    if (DEBUG_PROVIDER) Slog.v(TAG,
7367                            "Adding provider requested by "
7368                            + r.processName + " from process "
7369                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7370                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7371                    if (stable) {
7372                        conn.stableCount++;
7373                        conn.numStableIncs++;
7374                    } else {
7375                        conn.unstableCount++;
7376                        conn.numUnstableIncs++;
7377                    }
7378                    return conn;
7379                }
7380            }
7381            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7382            if (stable) {
7383                conn.stableCount = 1;
7384                conn.numStableIncs = 1;
7385            } else {
7386                conn.unstableCount = 1;
7387                conn.numUnstableIncs = 1;
7388            }
7389            cpr.connections.add(conn);
7390            r.conProviders.add(conn);
7391            return conn;
7392        }
7393        cpr.addExternalProcessHandleLocked(externalProcessToken);
7394        return null;
7395    }
7396
7397    boolean decProviderCountLocked(ContentProviderConnection conn,
7398            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7399        if (conn != null) {
7400            cpr = conn.provider;
7401            if (DEBUG_PROVIDER) Slog.v(TAG,
7402                    "Removing provider requested by "
7403                    + conn.client.processName + " from process "
7404                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7405                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7406            if (stable) {
7407                conn.stableCount--;
7408            } else {
7409                conn.unstableCount--;
7410            }
7411            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7412                cpr.connections.remove(conn);
7413                conn.client.conProviders.remove(conn);
7414                return true;
7415            }
7416            return false;
7417        }
7418        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7419        return false;
7420    }
7421
7422    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7423            String name, IBinder token, boolean stable, int userId) {
7424        ContentProviderRecord cpr;
7425        ContentProviderConnection conn = null;
7426        ProviderInfo cpi = null;
7427
7428        synchronized(this) {
7429            ProcessRecord r = null;
7430            if (caller != null) {
7431                r = getRecordForAppLocked(caller);
7432                if (r == null) {
7433                    throw new SecurityException(
7434                            "Unable to find app for caller " + caller
7435                          + " (pid=" + Binder.getCallingPid()
7436                          + ") when getting content provider " + name);
7437                }
7438            }
7439
7440            // First check if this content provider has been published...
7441            cpr = mProviderMap.getProviderByName(name, userId);
7442            boolean providerRunning = cpr != null;
7443            if (providerRunning) {
7444                cpi = cpr.info;
7445                String msg;
7446                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7447                    throw new SecurityException(msg);
7448                }
7449
7450                if (r != null && cpr.canRunHere(r)) {
7451                    // This provider has been published or is in the process
7452                    // of being published...  but it is also allowed to run
7453                    // in the caller's process, so don't make a connection
7454                    // and just let the caller instantiate its own instance.
7455                    ContentProviderHolder holder = cpr.newHolder(null);
7456                    // don't give caller the provider object, it needs
7457                    // to make its own.
7458                    holder.provider = null;
7459                    return holder;
7460                }
7461
7462                final long origId = Binder.clearCallingIdentity();
7463
7464                // In this case the provider instance already exists, so we can
7465                // return it right away.
7466                conn = incProviderCountLocked(r, cpr, token, stable);
7467                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7468                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7469                        // If this is a perceptible app accessing the provider,
7470                        // make sure to count it as being accessed and thus
7471                        // back up on the LRU list.  This is good because
7472                        // content providers are often expensive to start.
7473                        updateLruProcessLocked(cpr.proc, false, null);
7474                    }
7475                }
7476
7477                if (cpr.proc != null) {
7478                    if (false) {
7479                        if (cpr.name.flattenToShortString().equals(
7480                                "com.android.providers.calendar/.CalendarProvider2")) {
7481                            Slog.v(TAG, "****************** KILLING "
7482                                + cpr.name.flattenToShortString());
7483                            Process.killProcess(cpr.proc.pid);
7484                        }
7485                    }
7486                    boolean success = updateOomAdjLocked(cpr.proc);
7487                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7488                    // NOTE: there is still a race here where a signal could be
7489                    // pending on the process even though we managed to update its
7490                    // adj level.  Not sure what to do about this, but at least
7491                    // the race is now smaller.
7492                    if (!success) {
7493                        // Uh oh...  it looks like the provider's process
7494                        // has been killed on us.  We need to wait for a new
7495                        // process to be started, and make sure its death
7496                        // doesn't kill our process.
7497                        Slog.i(TAG,
7498                                "Existing provider " + cpr.name.flattenToShortString()
7499                                + " is crashing; detaching " + r);
7500                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7501                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7502                        if (!lastRef) {
7503                            // This wasn't the last ref our process had on
7504                            // the provider...  we have now been killed, bail.
7505                            return null;
7506                        }
7507                        providerRunning = false;
7508                        conn = null;
7509                    }
7510                }
7511
7512                Binder.restoreCallingIdentity(origId);
7513            }
7514
7515            boolean singleton;
7516            if (!providerRunning) {
7517                try {
7518                    cpi = AppGlobals.getPackageManager().
7519                        resolveContentProvider(name,
7520                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7521                } catch (RemoteException ex) {
7522                }
7523                if (cpi == null) {
7524                    return null;
7525                }
7526                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7527                        cpi.name, cpi.flags);
7528                if (singleton) {
7529                    userId = 0;
7530                }
7531                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7532
7533                String msg;
7534                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7535                    throw new SecurityException(msg);
7536                }
7537
7538                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7539                        && !cpi.processName.equals("system")) {
7540                    // If this content provider does not run in the system
7541                    // process, and the system is not yet ready to run other
7542                    // processes, then fail fast instead of hanging.
7543                    throw new IllegalArgumentException(
7544                            "Attempt to launch content provider before system ready");
7545                }
7546
7547                // Make sure that the user who owns this provider is started.  If not,
7548                // we don't want to allow it to run.
7549                if (mStartedUsers.get(userId) == null) {
7550                    Slog.w(TAG, "Unable to launch app "
7551                            + cpi.applicationInfo.packageName + "/"
7552                            + cpi.applicationInfo.uid + " for provider "
7553                            + name + ": user " + userId + " is stopped");
7554                    return null;
7555                }
7556
7557                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7558                cpr = mProviderMap.getProviderByClass(comp, userId);
7559                final boolean firstClass = cpr == null;
7560                if (firstClass) {
7561                    try {
7562                        ApplicationInfo ai =
7563                            AppGlobals.getPackageManager().
7564                                getApplicationInfo(
7565                                        cpi.applicationInfo.packageName,
7566                                        STOCK_PM_FLAGS, userId);
7567                        if (ai == null) {
7568                            Slog.w(TAG, "No package info for content provider "
7569                                    + cpi.name);
7570                            return null;
7571                        }
7572                        ai = getAppInfoForUser(ai, userId);
7573                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7574                    } catch (RemoteException ex) {
7575                        // pm is in same process, this will never happen.
7576                    }
7577                }
7578
7579                if (r != null && cpr.canRunHere(r)) {
7580                    // If this is a multiprocess provider, then just return its
7581                    // info and allow the caller to instantiate it.  Only do
7582                    // this if the provider is the same user as the caller's
7583                    // process, or can run as root (so can be in any process).
7584                    return cpr.newHolder(null);
7585                }
7586
7587                if (DEBUG_PROVIDER) {
7588                    RuntimeException e = new RuntimeException("here");
7589                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7590                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7591                }
7592
7593                // This is single process, and our app is now connecting to it.
7594                // See if we are already in the process of launching this
7595                // provider.
7596                final int N = mLaunchingProviders.size();
7597                int i;
7598                for (i=0; i<N; i++) {
7599                    if (mLaunchingProviders.get(i) == cpr) {
7600                        break;
7601                    }
7602                }
7603
7604                // If the provider is not already being launched, then get it
7605                // started.
7606                if (i >= N) {
7607                    final long origId = Binder.clearCallingIdentity();
7608
7609                    try {
7610                        // Content provider is now in use, its package can't be stopped.
7611                        try {
7612                            AppGlobals.getPackageManager().setPackageStoppedState(
7613                                    cpr.appInfo.packageName, false, userId);
7614                        } catch (RemoteException e) {
7615                        } catch (IllegalArgumentException e) {
7616                            Slog.w(TAG, "Failed trying to unstop package "
7617                                    + cpr.appInfo.packageName + ": " + e);
7618                        }
7619
7620                        // Use existing process if already started
7621                        ProcessRecord proc = getProcessRecordLocked(
7622                                cpi.processName, cpr.appInfo.uid, false);
7623                        if (proc != null && proc.thread != null) {
7624                            if (DEBUG_PROVIDER) {
7625                                Slog.d(TAG, "Installing in existing process " + proc);
7626                            }
7627                            proc.pubProviders.put(cpi.name, cpr);
7628                            try {
7629                                proc.thread.scheduleInstallProvider(cpi);
7630                            } catch (RemoteException e) {
7631                            }
7632                        } else {
7633                            proc = startProcessLocked(cpi.processName,
7634                                    cpr.appInfo, false, 0, "content provider",
7635                                    new ComponentName(cpi.applicationInfo.packageName,
7636                                            cpi.name), false, false, false);
7637                            if (proc == null) {
7638                                Slog.w(TAG, "Unable to launch app "
7639                                        + cpi.applicationInfo.packageName + "/"
7640                                        + cpi.applicationInfo.uid + " for provider "
7641                                        + name + ": process is bad");
7642                                return null;
7643                            }
7644                        }
7645                        cpr.launchingApp = proc;
7646                        mLaunchingProviders.add(cpr);
7647                    } finally {
7648                        Binder.restoreCallingIdentity(origId);
7649                    }
7650                }
7651
7652                // Make sure the provider is published (the same provider class
7653                // may be published under multiple names).
7654                if (firstClass) {
7655                    mProviderMap.putProviderByClass(comp, cpr);
7656                }
7657
7658                mProviderMap.putProviderByName(name, cpr);
7659                conn = incProviderCountLocked(r, cpr, token, stable);
7660                if (conn != null) {
7661                    conn.waiting = true;
7662                }
7663            }
7664        }
7665
7666        // Wait for the provider to be published...
7667        synchronized (cpr) {
7668            while (cpr.provider == null) {
7669                if (cpr.launchingApp == null) {
7670                    Slog.w(TAG, "Unable to launch app "
7671                            + cpi.applicationInfo.packageName + "/"
7672                            + cpi.applicationInfo.uid + " for provider "
7673                            + name + ": launching app became null");
7674                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7675                            UserHandle.getUserId(cpi.applicationInfo.uid),
7676                            cpi.applicationInfo.packageName,
7677                            cpi.applicationInfo.uid, name);
7678                    return null;
7679                }
7680                try {
7681                    if (DEBUG_MU) {
7682                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7683                                + cpr.launchingApp);
7684                    }
7685                    if (conn != null) {
7686                        conn.waiting = true;
7687                    }
7688                    cpr.wait();
7689                } catch (InterruptedException ex) {
7690                } finally {
7691                    if (conn != null) {
7692                        conn.waiting = false;
7693                    }
7694                }
7695            }
7696        }
7697        return cpr != null ? cpr.newHolder(conn) : null;
7698    }
7699
7700    public final ContentProviderHolder getContentProvider(
7701            IApplicationThread caller, String name, int userId, boolean stable) {
7702        enforceNotIsolatedCaller("getContentProvider");
7703        if (caller == null) {
7704            String msg = "null IApplicationThread when getting content provider "
7705                    + name;
7706            Slog.w(TAG, msg);
7707            throw new SecurityException(msg);
7708        }
7709
7710        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7711                false, true, "getContentProvider", null);
7712        return getContentProviderImpl(caller, name, null, stable, userId);
7713    }
7714
7715    public ContentProviderHolder getContentProviderExternal(
7716            String name, int userId, IBinder token) {
7717        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7718            "Do not have permission in call getContentProviderExternal()");
7719        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7720                false, true, "getContentProvider", null);
7721        return getContentProviderExternalUnchecked(name, token, userId);
7722    }
7723
7724    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7725            IBinder token, int userId) {
7726        return getContentProviderImpl(null, name, token, true, userId);
7727    }
7728
7729    /**
7730     * Drop a content provider from a ProcessRecord's bookkeeping
7731     */
7732    public void removeContentProvider(IBinder connection, boolean stable) {
7733        enforceNotIsolatedCaller("removeContentProvider");
7734        synchronized (this) {
7735            ContentProviderConnection conn;
7736            try {
7737                conn = (ContentProviderConnection)connection;
7738            } catch (ClassCastException e) {
7739                String msg ="removeContentProvider: " + connection
7740                        + " not a ContentProviderConnection";
7741                Slog.w(TAG, msg);
7742                throw new IllegalArgumentException(msg);
7743            }
7744            if (conn == null) {
7745                throw new NullPointerException("connection is null");
7746            }
7747            if (decProviderCountLocked(conn, null, null, stable)) {
7748                updateOomAdjLocked();
7749            }
7750        }
7751    }
7752
7753    public void removeContentProviderExternal(String name, IBinder token) {
7754        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7755            "Do not have permission in call removeContentProviderExternal()");
7756        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7757    }
7758
7759    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7760        synchronized (this) {
7761            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7762            if(cpr == null) {
7763                //remove from mProvidersByClass
7764                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7765                return;
7766            }
7767
7768            //update content provider record entry info
7769            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7770            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7771            if (localCpr.hasExternalProcessHandles()) {
7772                if (localCpr.removeExternalProcessHandleLocked(token)) {
7773                    updateOomAdjLocked();
7774                } else {
7775                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7776                            + " with no external reference for token: "
7777                            + token + ".");
7778                }
7779            } else {
7780                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7781                        + " with no external references.");
7782            }
7783        }
7784    }
7785
7786    public final void publishContentProviders(IApplicationThread caller,
7787            List<ContentProviderHolder> providers) {
7788        if (providers == null) {
7789            return;
7790        }
7791
7792        enforceNotIsolatedCaller("publishContentProviders");
7793        synchronized (this) {
7794            final ProcessRecord r = getRecordForAppLocked(caller);
7795            if (DEBUG_MU)
7796                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7797            if (r == null) {
7798                throw new SecurityException(
7799                        "Unable to find app for caller " + caller
7800                      + " (pid=" + Binder.getCallingPid()
7801                      + ") when publishing content providers");
7802            }
7803
7804            final long origId = Binder.clearCallingIdentity();
7805
7806            final int N = providers.size();
7807            for (int i=0; i<N; i++) {
7808                ContentProviderHolder src = providers.get(i);
7809                if (src == null || src.info == null || src.provider == null) {
7810                    continue;
7811                }
7812                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7813                if (DEBUG_MU)
7814                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7815                if (dst != null) {
7816                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7817                    mProviderMap.putProviderByClass(comp, dst);
7818                    String names[] = dst.info.authority.split(";");
7819                    for (int j = 0; j < names.length; j++) {
7820                        mProviderMap.putProviderByName(names[j], dst);
7821                    }
7822
7823                    int NL = mLaunchingProviders.size();
7824                    int j;
7825                    for (j=0; j<NL; j++) {
7826                        if (mLaunchingProviders.get(j) == dst) {
7827                            mLaunchingProviders.remove(j);
7828                            j--;
7829                            NL--;
7830                        }
7831                    }
7832                    synchronized (dst) {
7833                        dst.provider = src.provider;
7834                        dst.proc = r;
7835                        dst.notifyAll();
7836                    }
7837                    updateOomAdjLocked(r);
7838                }
7839            }
7840
7841            Binder.restoreCallingIdentity(origId);
7842        }
7843    }
7844
7845    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7846        ContentProviderConnection conn;
7847        try {
7848            conn = (ContentProviderConnection)connection;
7849        } catch (ClassCastException e) {
7850            String msg ="refContentProvider: " + connection
7851                    + " not a ContentProviderConnection";
7852            Slog.w(TAG, msg);
7853            throw new IllegalArgumentException(msg);
7854        }
7855        if (conn == null) {
7856            throw new NullPointerException("connection is null");
7857        }
7858
7859        synchronized (this) {
7860            if (stable > 0) {
7861                conn.numStableIncs += stable;
7862            }
7863            stable = conn.stableCount + stable;
7864            if (stable < 0) {
7865                throw new IllegalStateException("stableCount < 0: " + stable);
7866            }
7867
7868            if (unstable > 0) {
7869                conn.numUnstableIncs += unstable;
7870            }
7871            unstable = conn.unstableCount + unstable;
7872            if (unstable < 0) {
7873                throw new IllegalStateException("unstableCount < 0: " + unstable);
7874            }
7875
7876            if ((stable+unstable) <= 0) {
7877                throw new IllegalStateException("ref counts can't go to zero here: stable="
7878                        + stable + " unstable=" + unstable);
7879            }
7880            conn.stableCount = stable;
7881            conn.unstableCount = unstable;
7882            return !conn.dead;
7883        }
7884    }
7885
7886    public void unstableProviderDied(IBinder connection) {
7887        ContentProviderConnection conn;
7888        try {
7889            conn = (ContentProviderConnection)connection;
7890        } catch (ClassCastException e) {
7891            String msg ="refContentProvider: " + connection
7892                    + " not a ContentProviderConnection";
7893            Slog.w(TAG, msg);
7894            throw new IllegalArgumentException(msg);
7895        }
7896        if (conn == null) {
7897            throw new NullPointerException("connection is null");
7898        }
7899
7900        // Safely retrieve the content provider associated with the connection.
7901        IContentProvider provider;
7902        synchronized (this) {
7903            provider = conn.provider.provider;
7904        }
7905
7906        if (provider == null) {
7907            // Um, yeah, we're way ahead of you.
7908            return;
7909        }
7910
7911        // Make sure the caller is being honest with us.
7912        if (provider.asBinder().pingBinder()) {
7913            // Er, no, still looks good to us.
7914            synchronized (this) {
7915                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7916                        + " says " + conn + " died, but we don't agree");
7917                return;
7918            }
7919        }
7920
7921        // Well look at that!  It's dead!
7922        synchronized (this) {
7923            if (conn.provider.provider != provider) {
7924                // But something changed...  good enough.
7925                return;
7926            }
7927
7928            ProcessRecord proc = conn.provider.proc;
7929            if (proc == null || proc.thread == null) {
7930                // Seems like the process is already cleaned up.
7931                return;
7932            }
7933
7934            // As far as we're concerned, this is just like receiving a
7935            // death notification...  just a bit prematurely.
7936            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7937                    + ") early provider death");
7938            final long ident = Binder.clearCallingIdentity();
7939            try {
7940                appDiedLocked(proc, proc.pid, proc.thread);
7941            } finally {
7942                Binder.restoreCallingIdentity(ident);
7943            }
7944        }
7945    }
7946
7947    @Override
7948    public void appNotRespondingViaProvider(IBinder connection) {
7949        enforceCallingPermission(
7950                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7951
7952        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7953        if (conn == null) {
7954            Slog.w(TAG, "ContentProviderConnection is null");
7955            return;
7956        }
7957
7958        final ProcessRecord host = conn.provider.proc;
7959        if (host == null) {
7960            Slog.w(TAG, "Failed to find hosting ProcessRecord");
7961            return;
7962        }
7963
7964        final long token = Binder.clearCallingIdentity();
7965        try {
7966            appNotResponding(host, null, null, false, "ContentProvider not responding");
7967        } finally {
7968            Binder.restoreCallingIdentity(token);
7969        }
7970    }
7971
7972    public final void installSystemProviders() {
7973        List<ProviderInfo> providers;
7974        synchronized (this) {
7975            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
7976            providers = generateApplicationProvidersLocked(app);
7977            if (providers != null) {
7978                for (int i=providers.size()-1; i>=0; i--) {
7979                    ProviderInfo pi = (ProviderInfo)providers.get(i);
7980                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7981                        Slog.w(TAG, "Not installing system proc provider " + pi.name
7982                                + ": not system .apk");
7983                        providers.remove(i);
7984                    }
7985                }
7986            }
7987        }
7988        if (providers != null) {
7989            mSystemThread.installSystemProviders(providers);
7990        }
7991
7992        mCoreSettingsObserver = new CoreSettingsObserver(this);
7993
7994        mUsageStatsService.monitorPackages();
7995    }
7996
7997    /**
7998     * Allows app to retrieve the MIME type of a URI without having permission
7999     * to access its content provider.
8000     *
8001     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8002     *
8003     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8004     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8005     */
8006    public String getProviderMimeType(Uri uri, int userId) {
8007        enforceNotIsolatedCaller("getProviderMimeType");
8008        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8009                userId, false, true, "getProviderMimeType", null);
8010        final String name = uri.getAuthority();
8011        final long ident = Binder.clearCallingIdentity();
8012        ContentProviderHolder holder = null;
8013
8014        try {
8015            holder = getContentProviderExternalUnchecked(name, null, userId);
8016            if (holder != null) {
8017                return holder.provider.getType(uri);
8018            }
8019        } catch (RemoteException e) {
8020            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8021            return null;
8022        } finally {
8023            if (holder != null) {
8024                removeContentProviderExternalUnchecked(name, null, userId);
8025            }
8026            Binder.restoreCallingIdentity(ident);
8027        }
8028
8029        return null;
8030    }
8031
8032    // =========================================================
8033    // GLOBAL MANAGEMENT
8034    // =========================================================
8035
8036    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8037            boolean isolated) {
8038        String proc = customProcess != null ? customProcess : info.processName;
8039        BatteryStatsImpl.Uid.Proc ps = null;
8040        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8041        int uid = info.uid;
8042        if (isolated) {
8043            int userId = UserHandle.getUserId(uid);
8044            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8045            while (true) {
8046                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8047                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8048                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8049                }
8050                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8051                mNextIsolatedProcessUid++;
8052                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8053                    // No process for this uid, use it.
8054                    break;
8055                }
8056                stepsLeft--;
8057                if (stepsLeft <= 0) {
8058                    return null;
8059                }
8060            }
8061        }
8062        return new ProcessRecord(stats, info, proc, uid);
8063    }
8064
8065    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8066        ProcessRecord app;
8067        if (!isolated) {
8068            app = getProcessRecordLocked(info.processName, info.uid, true);
8069        } else {
8070            app = null;
8071        }
8072
8073        if (app == null) {
8074            app = newProcessRecordLocked(info, null, isolated);
8075            mProcessNames.put(info.processName, app.uid, app);
8076            if (isolated) {
8077                mIsolatedProcesses.put(app.uid, app);
8078            }
8079            updateLruProcessLocked(app, false, null);
8080            updateOomAdjLocked();
8081        }
8082
8083        // This package really, really can not be stopped.
8084        try {
8085            AppGlobals.getPackageManager().setPackageStoppedState(
8086                    info.packageName, false, UserHandle.getUserId(app.uid));
8087        } catch (RemoteException e) {
8088        } catch (IllegalArgumentException e) {
8089            Slog.w(TAG, "Failed trying to unstop package "
8090                    + info.packageName + ": " + e);
8091        }
8092
8093        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8094                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8095            app.persistent = true;
8096            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8097        }
8098        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8099            mPersistentStartingProcesses.add(app);
8100            startProcessLocked(app, "added application", app.processName);
8101        }
8102
8103        return app;
8104    }
8105
8106    public void unhandledBack() {
8107        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8108                "unhandledBack()");
8109
8110        synchronized(this) {
8111            final long origId = Binder.clearCallingIdentity();
8112            try {
8113                getFocusedStack().unhandledBackLocked();
8114            } finally {
8115                Binder.restoreCallingIdentity(origId);
8116            }
8117        }
8118    }
8119
8120    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8121        enforceNotIsolatedCaller("openContentUri");
8122        final int userId = UserHandle.getCallingUserId();
8123        String name = uri.getAuthority();
8124        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8125        ParcelFileDescriptor pfd = null;
8126        if (cph != null) {
8127            // We record the binder invoker's uid in thread-local storage before
8128            // going to the content provider to open the file.  Later, in the code
8129            // that handles all permissions checks, we look for this uid and use
8130            // that rather than the Activity Manager's own uid.  The effect is that
8131            // we do the check against the caller's permissions even though it looks
8132            // to the content provider like the Activity Manager itself is making
8133            // the request.
8134            sCallerIdentity.set(new Identity(
8135                    Binder.getCallingPid(), Binder.getCallingUid()));
8136            try {
8137                pfd = cph.provider.openFile(null, uri, "r", null);
8138            } catch (FileNotFoundException e) {
8139                // do nothing; pfd will be returned null
8140            } finally {
8141                // Ensure that whatever happens, we clean up the identity state
8142                sCallerIdentity.remove();
8143            }
8144
8145            // We've got the fd now, so we're done with the provider.
8146            removeContentProviderExternalUnchecked(name, null, userId);
8147        } else {
8148            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8149        }
8150        return pfd;
8151    }
8152
8153    // Actually is sleeping or shutting down or whatever else in the future
8154    // is an inactive state.
8155    public boolean isSleepingOrShuttingDown() {
8156        return mSleeping || mShuttingDown;
8157    }
8158
8159    public void goingToSleep() {
8160        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8161                != PackageManager.PERMISSION_GRANTED) {
8162            throw new SecurityException("Requires permission "
8163                    + android.Manifest.permission.DEVICE_POWER);
8164        }
8165
8166        synchronized(this) {
8167            mWentToSleep = true;
8168            updateEventDispatchingLocked();
8169
8170            if (!mSleeping) {
8171                mSleeping = true;
8172                mStackSupervisor.goingToSleepLocked();
8173
8174                // Initialize the wake times of all processes.
8175                checkExcessivePowerUsageLocked(false);
8176                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8177                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8178                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8179            }
8180        }
8181    }
8182
8183    @Override
8184    public boolean shutdown(int timeout) {
8185        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8186                != PackageManager.PERMISSION_GRANTED) {
8187            throw new SecurityException("Requires permission "
8188                    + android.Manifest.permission.SHUTDOWN);
8189        }
8190
8191        boolean timedout = false;
8192
8193        synchronized(this) {
8194            mShuttingDown = true;
8195            updateEventDispatchingLocked();
8196            timedout = mStackSupervisor.shutdownLocked(timeout);
8197        }
8198
8199        mAppOpsService.shutdown();
8200        mUsageStatsService.shutdown();
8201        mBatteryStatsService.shutdown();
8202        synchronized (this) {
8203            mProcessStats.shutdownLocked();
8204        }
8205
8206        return timedout;
8207    }
8208
8209    public final void activitySlept(IBinder token) {
8210        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8211
8212        final long origId = Binder.clearCallingIdentity();
8213
8214        synchronized (this) {
8215            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8216            if (r != null) {
8217                mStackSupervisor.activitySleptLocked(r);
8218            }
8219        }
8220
8221        Binder.restoreCallingIdentity(origId);
8222    }
8223
8224    void logLockScreen(String msg) {
8225        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8226                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8227                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8228                mStackSupervisor.mDismissKeyguardOnNextActivity);
8229    }
8230
8231    private void comeOutOfSleepIfNeededLocked() {
8232        if (!mWentToSleep && !mLockScreenShown) {
8233            if (mSleeping) {
8234                mSleeping = false;
8235                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8236            }
8237        }
8238    }
8239
8240    public void wakingUp() {
8241        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8242                != PackageManager.PERMISSION_GRANTED) {
8243            throw new SecurityException("Requires permission "
8244                    + android.Manifest.permission.DEVICE_POWER);
8245        }
8246
8247        synchronized(this) {
8248            mWentToSleep = false;
8249            updateEventDispatchingLocked();
8250            comeOutOfSleepIfNeededLocked();
8251        }
8252    }
8253
8254    private void updateEventDispatchingLocked() {
8255        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8256    }
8257
8258    public void setLockScreenShown(boolean shown) {
8259        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8260                != PackageManager.PERMISSION_GRANTED) {
8261            throw new SecurityException("Requires permission "
8262                    + android.Manifest.permission.DEVICE_POWER);
8263        }
8264
8265        synchronized(this) {
8266            long ident = Binder.clearCallingIdentity();
8267            try {
8268                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8269                mLockScreenShown = shown;
8270                comeOutOfSleepIfNeededLocked();
8271            } finally {
8272                Binder.restoreCallingIdentity(ident);
8273            }
8274        }
8275    }
8276
8277    public void stopAppSwitches() {
8278        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8279                != PackageManager.PERMISSION_GRANTED) {
8280            throw new SecurityException("Requires permission "
8281                    + android.Manifest.permission.STOP_APP_SWITCHES);
8282        }
8283
8284        synchronized(this) {
8285            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8286                    + APP_SWITCH_DELAY_TIME;
8287            mDidAppSwitch = false;
8288            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8289            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8290            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8291        }
8292    }
8293
8294    public void resumeAppSwitches() {
8295        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8296                != PackageManager.PERMISSION_GRANTED) {
8297            throw new SecurityException("Requires permission "
8298                    + android.Manifest.permission.STOP_APP_SWITCHES);
8299        }
8300
8301        synchronized(this) {
8302            // Note that we don't execute any pending app switches... we will
8303            // let those wait until either the timeout, or the next start
8304            // activity request.
8305            mAppSwitchesAllowedTime = 0;
8306        }
8307    }
8308
8309    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8310            String name) {
8311        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8312            return true;
8313        }
8314
8315        final int perm = checkComponentPermission(
8316                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8317                callingUid, -1, true);
8318        if (perm == PackageManager.PERMISSION_GRANTED) {
8319            return true;
8320        }
8321
8322        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8323        return false;
8324    }
8325
8326    public void setDebugApp(String packageName, boolean waitForDebugger,
8327            boolean persistent) {
8328        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8329                "setDebugApp()");
8330
8331        long ident = Binder.clearCallingIdentity();
8332        try {
8333            // Note that this is not really thread safe if there are multiple
8334            // callers into it at the same time, but that's not a situation we
8335            // care about.
8336            if (persistent) {
8337                final ContentResolver resolver = mContext.getContentResolver();
8338                Settings.Global.putString(
8339                    resolver, Settings.Global.DEBUG_APP,
8340                    packageName);
8341                Settings.Global.putInt(
8342                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8343                    waitForDebugger ? 1 : 0);
8344            }
8345
8346            synchronized (this) {
8347                if (!persistent) {
8348                    mOrigDebugApp = mDebugApp;
8349                    mOrigWaitForDebugger = mWaitForDebugger;
8350                }
8351                mDebugApp = packageName;
8352                mWaitForDebugger = waitForDebugger;
8353                mDebugTransient = !persistent;
8354                if (packageName != null) {
8355                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8356                            UserHandle.USER_ALL, "set debug app");
8357                }
8358            }
8359        } finally {
8360            Binder.restoreCallingIdentity(ident);
8361        }
8362    }
8363
8364    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8365        synchronized (this) {
8366            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8367            if (!isDebuggable) {
8368                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8369                    throw new SecurityException("Process not debuggable: " + app.packageName);
8370                }
8371            }
8372
8373            mOpenGlTraceApp = processName;
8374        }
8375    }
8376
8377    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8378            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8379        synchronized (this) {
8380            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8381            if (!isDebuggable) {
8382                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8383                    throw new SecurityException("Process not debuggable: " + app.packageName);
8384                }
8385            }
8386            mProfileApp = processName;
8387            mProfileFile = profileFile;
8388            if (mProfileFd != null) {
8389                try {
8390                    mProfileFd.close();
8391                } catch (IOException e) {
8392                }
8393                mProfileFd = null;
8394            }
8395            mProfileFd = profileFd;
8396            mProfileType = 0;
8397            mAutoStopProfiler = autoStopProfiler;
8398        }
8399    }
8400
8401    @Override
8402    public void setAlwaysFinish(boolean enabled) {
8403        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8404                "setAlwaysFinish()");
8405
8406        Settings.Global.putInt(
8407                mContext.getContentResolver(),
8408                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8409
8410        synchronized (this) {
8411            mAlwaysFinishActivities = enabled;
8412        }
8413    }
8414
8415    @Override
8416    public void setActivityController(IActivityController controller) {
8417        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8418                "setActivityController()");
8419        synchronized (this) {
8420            mController = controller;
8421            Watchdog.getInstance().setActivityController(controller);
8422        }
8423    }
8424
8425    @Override
8426    public void setUserIsMonkey(boolean userIsMonkey) {
8427        synchronized (this) {
8428            synchronized (mPidsSelfLocked) {
8429                final int callingPid = Binder.getCallingPid();
8430                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8431                if (precessRecord == null) {
8432                    throw new SecurityException("Unknown process: " + callingPid);
8433                }
8434                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8435                    throw new SecurityException("Only an instrumentation process "
8436                            + "with a UiAutomation can call setUserIsMonkey");
8437                }
8438            }
8439            mUserIsMonkey = userIsMonkey;
8440        }
8441    }
8442
8443    @Override
8444    public boolean isUserAMonkey() {
8445        synchronized (this) {
8446            // If there is a controller also implies the user is a monkey.
8447            return (mUserIsMonkey || mController != null);
8448        }
8449    }
8450
8451    public void requestBugReport() {
8452        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8453        SystemProperties.set("ctl.start", "bugreport");
8454    }
8455
8456    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8457        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8458    }
8459
8460    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8461        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8462            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8463        }
8464        return KEY_DISPATCHING_TIMEOUT;
8465    }
8466
8467    @Override
8468    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8469        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8470                != PackageManager.PERMISSION_GRANTED) {
8471            throw new SecurityException("Requires permission "
8472                    + android.Manifest.permission.FILTER_EVENTS);
8473        }
8474        ProcessRecord proc;
8475        long timeout;
8476        synchronized (this) {
8477            synchronized (mPidsSelfLocked) {
8478                proc = mPidsSelfLocked.get(pid);
8479            }
8480            timeout = getInputDispatchingTimeoutLocked(proc);
8481        }
8482
8483        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8484            return -1;
8485        }
8486
8487        return timeout;
8488    }
8489
8490    /**
8491     * Handle input dispatching timeouts.
8492     * Returns whether input dispatching should be aborted or not.
8493     */
8494    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8495            final ActivityRecord activity, final ActivityRecord parent,
8496            final boolean aboveSystem, String reason) {
8497        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8498                != PackageManager.PERMISSION_GRANTED) {
8499            throw new SecurityException("Requires permission "
8500                    + android.Manifest.permission.FILTER_EVENTS);
8501        }
8502
8503        final String annotation;
8504        if (reason == null) {
8505            annotation = "Input dispatching timed out";
8506        } else {
8507            annotation = "Input dispatching timed out (" + reason + ")";
8508        }
8509
8510        if (proc != null) {
8511            synchronized (this) {
8512                if (proc.debugging) {
8513                    return false;
8514                }
8515
8516                if (mDidDexOpt) {
8517                    // Give more time since we were dexopting.
8518                    mDidDexOpt = false;
8519                    return false;
8520                }
8521
8522                if (proc.instrumentationClass != null) {
8523                    Bundle info = new Bundle();
8524                    info.putString("shortMsg", "keyDispatchingTimedOut");
8525                    info.putString("longMsg", annotation);
8526                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8527                    return true;
8528                }
8529            }
8530            mHandler.post(new Runnable() {
8531                @Override
8532                public void run() {
8533                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8534                }
8535            });
8536        }
8537
8538        return true;
8539    }
8540
8541    public Bundle getAssistContextExtras(int requestType) {
8542        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8543                "getAssistContextExtras()");
8544        PendingAssistExtras pae;
8545        Bundle extras = new Bundle();
8546        synchronized (this) {
8547            ActivityRecord activity = getFocusedStack().mResumedActivity;
8548            if (activity == null) {
8549                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8550                return null;
8551            }
8552            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8553            if (activity.app == null || activity.app.thread == null) {
8554                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8555                return extras;
8556            }
8557            if (activity.app.pid == Binder.getCallingPid()) {
8558                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8559                return extras;
8560            }
8561            pae = new PendingAssistExtras(activity);
8562            try {
8563                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8564                        requestType);
8565                mPendingAssistExtras.add(pae);
8566                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8567            } catch (RemoteException e) {
8568                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8569                return extras;
8570            }
8571        }
8572        synchronized (pae) {
8573            while (!pae.haveResult) {
8574                try {
8575                    pae.wait();
8576                } catch (InterruptedException e) {
8577                }
8578            }
8579            if (pae.result != null) {
8580                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8581            }
8582        }
8583        synchronized (this) {
8584            mPendingAssistExtras.remove(pae);
8585            mHandler.removeCallbacks(pae);
8586        }
8587        return extras;
8588    }
8589
8590    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8591        PendingAssistExtras pae = (PendingAssistExtras)token;
8592        synchronized (pae) {
8593            pae.result = extras;
8594            pae.haveResult = true;
8595            pae.notifyAll();
8596        }
8597    }
8598
8599    public void registerProcessObserver(IProcessObserver observer) {
8600        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8601                "registerProcessObserver()");
8602        synchronized (this) {
8603            mProcessObservers.register(observer);
8604        }
8605    }
8606
8607    @Override
8608    public void unregisterProcessObserver(IProcessObserver observer) {
8609        synchronized (this) {
8610            mProcessObservers.unregister(observer);
8611        }
8612    }
8613
8614    @Override
8615    public boolean convertFromTranslucent(IBinder token) {
8616        final long origId = Binder.clearCallingIdentity();
8617        try {
8618            synchronized (this) {
8619                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8620                if (r == null) {
8621                    return false;
8622                }
8623                if (r.changeWindowTranslucency(true)) {
8624                    mWindowManager.setAppFullscreen(token, true);
8625                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8626                    return true;
8627                }
8628                return false;
8629            }
8630        } finally {
8631            Binder.restoreCallingIdentity(origId);
8632        }
8633    }
8634
8635    @Override
8636    public boolean convertToTranslucent(IBinder token) {
8637        final long origId = Binder.clearCallingIdentity();
8638        try {
8639            synchronized (this) {
8640                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8641                if (r == null) {
8642                    return false;
8643                }
8644                if (r.changeWindowTranslucency(false)) {
8645                    r.task.stack.convertToTranslucent(r);
8646                    mWindowManager.setAppFullscreen(token, false);
8647                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8648                    return true;
8649                }
8650                return false;
8651            }
8652        } finally {
8653            Binder.restoreCallingIdentity(origId);
8654        }
8655    }
8656
8657    @Override
8658    public void setImmersive(IBinder token, boolean immersive) {
8659        synchronized(this) {
8660            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8661            if (r == null) {
8662                throw new IllegalArgumentException();
8663            }
8664            r.immersive = immersive;
8665
8666            // update associated state if we're frontmost
8667            if (r == mFocusedActivity) {
8668                if (DEBUG_IMMERSIVE) {
8669                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8670                }
8671                applyUpdateLockStateLocked(r);
8672            }
8673        }
8674    }
8675
8676    @Override
8677    public boolean isImmersive(IBinder token) {
8678        synchronized (this) {
8679            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8680            if (r == null) {
8681                throw new IllegalArgumentException();
8682            }
8683            return r.immersive;
8684        }
8685    }
8686
8687    public boolean isTopActivityImmersive() {
8688        enforceNotIsolatedCaller("startActivity");
8689        synchronized (this) {
8690            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8691            return (r != null) ? r.immersive : false;
8692        }
8693    }
8694
8695    public final void enterSafeMode() {
8696        synchronized(this) {
8697            // It only makes sense to do this before the system is ready
8698            // and started launching other packages.
8699            if (!mSystemReady) {
8700                try {
8701                    AppGlobals.getPackageManager().enterSafeMode();
8702                } catch (RemoteException e) {
8703                }
8704            }
8705        }
8706    }
8707
8708    public final void showSafeModeOverlay() {
8709        View v = LayoutInflater.from(mContext).inflate(
8710                com.android.internal.R.layout.safe_mode, null);
8711        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8712        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8713        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8714        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8715        lp.gravity = Gravity.BOTTOM | Gravity.START;
8716        lp.format = v.getBackground().getOpacity();
8717        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8718                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8719        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8720        ((WindowManager)mContext.getSystemService(
8721                Context.WINDOW_SERVICE)).addView(v, lp);
8722    }
8723
8724    public void noteWakeupAlarm(IIntentSender sender) {
8725        if (!(sender instanceof PendingIntentRecord)) {
8726            return;
8727        }
8728        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8729        synchronized (stats) {
8730            if (mBatteryStatsService.isOnBattery()) {
8731                mBatteryStatsService.enforceCallingPermission();
8732                PendingIntentRecord rec = (PendingIntentRecord)sender;
8733                int MY_UID = Binder.getCallingUid();
8734                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8735                BatteryStatsImpl.Uid.Pkg pkg =
8736                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8737                pkg.incWakeupsLocked();
8738            }
8739        }
8740    }
8741
8742    public boolean killPids(int[] pids, String pReason, boolean secure) {
8743        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8744            throw new SecurityException("killPids only available to the system");
8745        }
8746        String reason = (pReason == null) ? "Unknown" : pReason;
8747        // XXX Note: don't acquire main activity lock here, because the window
8748        // manager calls in with its locks held.
8749
8750        boolean killed = false;
8751        synchronized (mPidsSelfLocked) {
8752            int[] types = new int[pids.length];
8753            int worstType = 0;
8754            for (int i=0; i<pids.length; i++) {
8755                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8756                if (proc != null) {
8757                    int type = proc.setAdj;
8758                    types[i] = type;
8759                    if (type > worstType) {
8760                        worstType = type;
8761                    }
8762                }
8763            }
8764
8765            // If the worst oom_adj is somewhere in the cached proc LRU range,
8766            // then constrain it so we will kill all cached procs.
8767            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8768                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8769                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8770            }
8771
8772            // If this is not a secure call, don't let it kill processes that
8773            // are important.
8774            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8775                worstType = ProcessList.SERVICE_ADJ;
8776            }
8777
8778            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8779            for (int i=0; i<pids.length; i++) {
8780                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8781                if (proc == null) {
8782                    continue;
8783                }
8784                int adj = proc.setAdj;
8785                if (adj >= worstType && !proc.killedByAm) {
8786                    killUnneededProcessLocked(proc, reason);
8787                    killed = true;
8788                }
8789            }
8790        }
8791        return killed;
8792    }
8793
8794    @Override
8795    public void killUid(int uid, String reason) {
8796        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8797            throw new SecurityException("killUid only available to the system");
8798        }
8799        synchronized (this) {
8800            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8801                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8802                    reason != null ? reason : "kill uid");
8803        }
8804    }
8805
8806    @Override
8807    public boolean killProcessesBelowForeground(String reason) {
8808        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8809            throw new SecurityException("killProcessesBelowForeground() only available to system");
8810        }
8811
8812        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8813    }
8814
8815    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8816        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8817            throw new SecurityException("killProcessesBelowAdj() only available to system");
8818        }
8819
8820        boolean killed = false;
8821        synchronized (mPidsSelfLocked) {
8822            final int size = mPidsSelfLocked.size();
8823            for (int i = 0; i < size; i++) {
8824                final int pid = mPidsSelfLocked.keyAt(i);
8825                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8826                if (proc == null) continue;
8827
8828                final int adj = proc.setAdj;
8829                if (adj > belowAdj && !proc.killedByAm) {
8830                    killUnneededProcessLocked(proc, reason);
8831                    killed = true;
8832                }
8833            }
8834        }
8835        return killed;
8836    }
8837
8838    @Override
8839    public void hang(final IBinder who, boolean allowRestart) {
8840        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8841                != PackageManager.PERMISSION_GRANTED) {
8842            throw new SecurityException("Requires permission "
8843                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8844        }
8845
8846        final IBinder.DeathRecipient death = new DeathRecipient() {
8847            @Override
8848            public void binderDied() {
8849                synchronized (this) {
8850                    notifyAll();
8851                }
8852            }
8853        };
8854
8855        try {
8856            who.linkToDeath(death, 0);
8857        } catch (RemoteException e) {
8858            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8859            return;
8860        }
8861
8862        synchronized (this) {
8863            Watchdog.getInstance().setAllowRestart(allowRestart);
8864            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8865            synchronized (death) {
8866                while (who.isBinderAlive()) {
8867                    try {
8868                        death.wait();
8869                    } catch (InterruptedException e) {
8870                    }
8871                }
8872            }
8873            Watchdog.getInstance().setAllowRestart(true);
8874        }
8875    }
8876
8877    @Override
8878    public void restart() {
8879        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8880                != PackageManager.PERMISSION_GRANTED) {
8881            throw new SecurityException("Requires permission "
8882                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8883        }
8884
8885        Log.i(TAG, "Sending shutdown broadcast...");
8886
8887        BroadcastReceiver br = new BroadcastReceiver() {
8888            @Override public void onReceive(Context context, Intent intent) {
8889                // Now the broadcast is done, finish up the low-level shutdown.
8890                Log.i(TAG, "Shutting down activity manager...");
8891                shutdown(10000);
8892                Log.i(TAG, "Shutdown complete, restarting!");
8893                Process.killProcess(Process.myPid());
8894                System.exit(10);
8895            }
8896        };
8897
8898        // First send the high-level shut down broadcast.
8899        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8900        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8901        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8902        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8903        mContext.sendOrderedBroadcastAsUser(intent,
8904                UserHandle.ALL, null, br, mHandler, 0, null, null);
8905        */
8906        br.onReceive(mContext, intent);
8907    }
8908
8909    private long getLowRamTimeSinceIdle(long now) {
8910        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8911    }
8912
8913    @Override
8914    public void performIdleMaintenance() {
8915        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8916                != PackageManager.PERMISSION_GRANTED) {
8917            throw new SecurityException("Requires permission "
8918                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8919        }
8920
8921        synchronized (this) {
8922            final long now = SystemClock.uptimeMillis();
8923            final long timeSinceLastIdle = now - mLastIdleTime;
8924            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8925            mLastIdleTime = now;
8926            mLowRamTimeSinceLastIdle = 0;
8927            if (mLowRamStartTime != 0) {
8928                mLowRamStartTime = now;
8929            }
8930
8931            StringBuilder sb = new StringBuilder(128);
8932            sb.append("Idle maintenance over ");
8933            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8934            sb.append(" low RAM for ");
8935            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8936            Slog.i(TAG, sb.toString());
8937
8938            // If at least 1/3 of our time since the last idle period has been spent
8939            // with RAM low, then we want to kill processes.
8940            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8941
8942            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8943                ProcessRecord proc = mLruProcesses.get(i);
8944                if (proc.notCachedSinceIdle) {
8945                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8946                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8947                        if (doKilling && proc.initialIdlePss != 0
8948                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8949                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8950                                    + " from " + proc.initialIdlePss + ")");
8951                        }
8952                    }
8953                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8954                    proc.notCachedSinceIdle = true;
8955                    proc.initialIdlePss = 0;
8956                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8957                            mSleeping, now);
8958                }
8959            }
8960
8961            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8962            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8963        }
8964    }
8965
8966    public final void startRunning(String pkg, String cls, String action,
8967            String data) {
8968        synchronized(this) {
8969            if (mStartRunning) {
8970                return;
8971            }
8972            mStartRunning = true;
8973            mTopComponent = pkg != null && cls != null
8974                    ? new ComponentName(pkg, cls) : null;
8975            mTopAction = action != null ? action : Intent.ACTION_MAIN;
8976            mTopData = data;
8977            if (!mSystemReady) {
8978                return;
8979            }
8980        }
8981
8982        systemReady(null);
8983    }
8984
8985    private void retrieveSettings() {
8986        final ContentResolver resolver = mContext.getContentResolver();
8987        String debugApp = Settings.Global.getString(
8988            resolver, Settings.Global.DEBUG_APP);
8989        boolean waitForDebugger = Settings.Global.getInt(
8990            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
8991        boolean alwaysFinishActivities = Settings.Global.getInt(
8992            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
8993        boolean forceRtl = Settings.Global.getInt(
8994                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
8995        // Transfer any global setting for forcing RTL layout, into a System Property
8996        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
8997
8998        Configuration configuration = new Configuration();
8999        Settings.System.getConfiguration(resolver, configuration);
9000        if (forceRtl) {
9001            // This will take care of setting the correct layout direction flags
9002            configuration.setLayoutDirection(configuration.locale);
9003        }
9004
9005        synchronized (this) {
9006            mDebugApp = mOrigDebugApp = debugApp;
9007            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9008            mAlwaysFinishActivities = alwaysFinishActivities;
9009            // This happens before any activities are started, so we can
9010            // change mConfiguration in-place.
9011            updateConfigurationLocked(configuration, null, false, true);
9012            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9013        }
9014    }
9015
9016    public boolean testIsSystemReady() {
9017        // no need to synchronize(this) just to read & return the value
9018        return mSystemReady;
9019    }
9020
9021    private static File getCalledPreBootReceiversFile() {
9022        File dataDir = Environment.getDataDirectory();
9023        File systemDir = new File(dataDir, "system");
9024        File fname = new File(systemDir, "called_pre_boots.dat");
9025        return fname;
9026    }
9027
9028    static final int LAST_DONE_VERSION = 10000;
9029
9030    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9031        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9032        File file = getCalledPreBootReceiversFile();
9033        FileInputStream fis = null;
9034        try {
9035            fis = new FileInputStream(file);
9036            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9037            int fvers = dis.readInt();
9038            if (fvers == LAST_DONE_VERSION) {
9039                String vers = dis.readUTF();
9040                String codename = dis.readUTF();
9041                String build = dis.readUTF();
9042                if (android.os.Build.VERSION.RELEASE.equals(vers)
9043                        && android.os.Build.VERSION.CODENAME.equals(codename)
9044                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9045                    int num = dis.readInt();
9046                    while (num > 0) {
9047                        num--;
9048                        String pkg = dis.readUTF();
9049                        String cls = dis.readUTF();
9050                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9051                    }
9052                }
9053            }
9054        } catch (FileNotFoundException e) {
9055        } catch (IOException e) {
9056            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9057        } finally {
9058            if (fis != null) {
9059                try {
9060                    fis.close();
9061                } catch (IOException e) {
9062                }
9063            }
9064        }
9065        return lastDoneReceivers;
9066    }
9067
9068    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9069        File file = getCalledPreBootReceiversFile();
9070        FileOutputStream fos = null;
9071        DataOutputStream dos = null;
9072        try {
9073            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9074            fos = new FileOutputStream(file);
9075            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9076            dos.writeInt(LAST_DONE_VERSION);
9077            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9078            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9079            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9080            dos.writeInt(list.size());
9081            for (int i=0; i<list.size(); i++) {
9082                dos.writeUTF(list.get(i).getPackageName());
9083                dos.writeUTF(list.get(i).getClassName());
9084            }
9085        } catch (IOException e) {
9086            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9087            file.delete();
9088        } finally {
9089            FileUtils.sync(fos);
9090            if (dos != null) {
9091                try {
9092                    dos.close();
9093                } catch (IOException e) {
9094                    // TODO Auto-generated catch block
9095                    e.printStackTrace();
9096                }
9097            }
9098        }
9099    }
9100
9101    public void systemReady(final Runnable goingCallback) {
9102        synchronized(this) {
9103            if (mSystemReady) {
9104                if (goingCallback != null) goingCallback.run();
9105                return;
9106            }
9107
9108            // Check to see if there are any update receivers to run.
9109            if (!mDidUpdate) {
9110                if (mWaitingUpdate) {
9111                    return;
9112                }
9113                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9114                List<ResolveInfo> ris = null;
9115                try {
9116                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9117                            intent, null, 0, 0);
9118                } catch (RemoteException e) {
9119                }
9120                if (ris != null) {
9121                    for (int i=ris.size()-1; i>=0; i--) {
9122                        if ((ris.get(i).activityInfo.applicationInfo.flags
9123                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9124                            ris.remove(i);
9125                        }
9126                    }
9127                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9128
9129                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9130
9131                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9132                    for (int i=0; i<ris.size(); i++) {
9133                        ActivityInfo ai = ris.get(i).activityInfo;
9134                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9135                        if (lastDoneReceivers.contains(comp)) {
9136                            ris.remove(i);
9137                            i--;
9138                        }
9139                    }
9140
9141                    final int[] users = getUsersLocked();
9142                    for (int i=0; i<ris.size(); i++) {
9143                        ActivityInfo ai = ris.get(i).activityInfo;
9144                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9145                        doneReceivers.add(comp);
9146                        intent.setComponent(comp);
9147                        for (int j=0; j<users.length; j++) {
9148                            IIntentReceiver finisher = null;
9149                            if (i == ris.size()-1 && j == users.length-1) {
9150                                finisher = new IIntentReceiver.Stub() {
9151                                    public void performReceive(Intent intent, int resultCode,
9152                                            String data, Bundle extras, boolean ordered,
9153                                            boolean sticky, int sendingUser) {
9154                                        // The raw IIntentReceiver interface is called
9155                                        // with the AM lock held, so redispatch to
9156                                        // execute our code without the lock.
9157                                        mHandler.post(new Runnable() {
9158                                            public void run() {
9159                                                synchronized (ActivityManagerService.this) {
9160                                                    mDidUpdate = true;
9161                                                }
9162                                                writeLastDonePreBootReceivers(doneReceivers);
9163                                                showBootMessage(mContext.getText(
9164                                                        R.string.android_upgrading_complete),
9165                                                        false);
9166                                                systemReady(goingCallback);
9167                                            }
9168                                        });
9169                                    }
9170                                };
9171                            }
9172                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9173                                    + " for user " + users[j]);
9174                            broadcastIntentLocked(null, null, intent, null, finisher,
9175                                    0, null, null, null, AppOpsManager.OP_NONE,
9176                                    true, false, MY_PID, Process.SYSTEM_UID,
9177                                    users[j]);
9178                            if (finisher != null) {
9179                                mWaitingUpdate = true;
9180                            }
9181                        }
9182                    }
9183                }
9184                if (mWaitingUpdate) {
9185                    return;
9186                }
9187                mDidUpdate = true;
9188            }
9189
9190            mAppOpsService.systemReady();
9191            mSystemReady = true;
9192            if (!mStartRunning) {
9193                return;
9194            }
9195        }
9196
9197        ArrayList<ProcessRecord> procsToKill = null;
9198        synchronized(mPidsSelfLocked) {
9199            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9200                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9201                if (!isAllowedWhileBooting(proc.info)){
9202                    if (procsToKill == null) {
9203                        procsToKill = new ArrayList<ProcessRecord>();
9204                    }
9205                    procsToKill.add(proc);
9206                }
9207            }
9208        }
9209
9210        synchronized(this) {
9211            if (procsToKill != null) {
9212                for (int i=procsToKill.size()-1; i>=0; i--) {
9213                    ProcessRecord proc = procsToKill.get(i);
9214                    Slog.i(TAG, "Removing system update proc: " + proc);
9215                    removeProcessLocked(proc, true, false, "system update done");
9216                }
9217            }
9218
9219            // Now that we have cleaned up any update processes, we
9220            // are ready to start launching real processes and know that
9221            // we won't trample on them any more.
9222            mProcessesReady = true;
9223        }
9224
9225        Slog.i(TAG, "System now ready");
9226        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9227            SystemClock.uptimeMillis());
9228
9229        synchronized(this) {
9230            // Make sure we have no pre-ready processes sitting around.
9231
9232            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9233                ResolveInfo ri = mContext.getPackageManager()
9234                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9235                                STOCK_PM_FLAGS);
9236                CharSequence errorMsg = null;
9237                if (ri != null) {
9238                    ActivityInfo ai = ri.activityInfo;
9239                    ApplicationInfo app = ai.applicationInfo;
9240                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9241                        mTopAction = Intent.ACTION_FACTORY_TEST;
9242                        mTopData = null;
9243                        mTopComponent = new ComponentName(app.packageName,
9244                                ai.name);
9245                    } else {
9246                        errorMsg = mContext.getResources().getText(
9247                                com.android.internal.R.string.factorytest_not_system);
9248                    }
9249                } else {
9250                    errorMsg = mContext.getResources().getText(
9251                            com.android.internal.R.string.factorytest_no_action);
9252                }
9253                if (errorMsg != null) {
9254                    mTopAction = null;
9255                    mTopData = null;
9256                    mTopComponent = null;
9257                    Message msg = Message.obtain();
9258                    msg.what = SHOW_FACTORY_ERROR_MSG;
9259                    msg.getData().putCharSequence("msg", errorMsg);
9260                    mHandler.sendMessage(msg);
9261                }
9262            }
9263        }
9264
9265        retrieveSettings();
9266
9267        synchronized (this) {
9268            readGrantedUriPermissionsLocked();
9269        }
9270
9271        if (goingCallback != null) goingCallback.run();
9272
9273        synchronized (this) {
9274            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9275                try {
9276                    List apps = AppGlobals.getPackageManager().
9277                        getPersistentApplications(STOCK_PM_FLAGS);
9278                    if (apps != null) {
9279                        int N = apps.size();
9280                        int i;
9281                        for (i=0; i<N; i++) {
9282                            ApplicationInfo info
9283                                = (ApplicationInfo)apps.get(i);
9284                            if (info != null &&
9285                                    !info.packageName.equals("android")) {
9286                                addAppLocked(info, false);
9287                            }
9288                        }
9289                    }
9290                } catch (RemoteException ex) {
9291                    // pm is in same process, this will never happen.
9292                }
9293            }
9294
9295            // Start up initial activity.
9296            mBooting = true;
9297
9298            try {
9299                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9300                    Message msg = Message.obtain();
9301                    msg.what = SHOW_UID_ERROR_MSG;
9302                    mHandler.sendMessage(msg);
9303                }
9304            } catch (RemoteException e) {
9305            }
9306
9307            long ident = Binder.clearCallingIdentity();
9308            try {
9309                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9310                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9311                        | Intent.FLAG_RECEIVER_FOREGROUND);
9312                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9313                broadcastIntentLocked(null, null, intent,
9314                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9315                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9316                intent = new Intent(Intent.ACTION_USER_STARTING);
9317                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9318                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9319                broadcastIntentLocked(null, null, intent,
9320                        null, new IIntentReceiver.Stub() {
9321                            @Override
9322                            public void performReceive(Intent intent, int resultCode, String data,
9323                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9324                                    throws RemoteException {
9325                            }
9326                        }, 0, null, null,
9327                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9328                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9329            } finally {
9330                Binder.restoreCallingIdentity(ident);
9331            }
9332            mStackSupervisor.resumeTopActivitiesLocked();
9333            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9334        }
9335    }
9336
9337    private boolean makeAppCrashingLocked(ProcessRecord app,
9338            String shortMsg, String longMsg, String stackTrace) {
9339        app.crashing = true;
9340        app.crashingReport = generateProcessError(app,
9341                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9342        startAppProblemLocked(app);
9343        app.stopFreezingAllLocked();
9344        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9345    }
9346
9347    private void makeAppNotRespondingLocked(ProcessRecord app,
9348            String activity, String shortMsg, String longMsg) {
9349        app.notResponding = true;
9350        app.notRespondingReport = generateProcessError(app,
9351                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9352                activity, shortMsg, longMsg, null);
9353        startAppProblemLocked(app);
9354        app.stopFreezingAllLocked();
9355    }
9356
9357    /**
9358     * Generate a process error record, suitable for attachment to a ProcessRecord.
9359     *
9360     * @param app The ProcessRecord in which the error occurred.
9361     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9362     *                      ActivityManager.AppErrorStateInfo
9363     * @param activity The activity associated with the crash, if known.
9364     * @param shortMsg Short message describing the crash.
9365     * @param longMsg Long message describing the crash.
9366     * @param stackTrace Full crash stack trace, may be null.
9367     *
9368     * @return Returns a fully-formed AppErrorStateInfo record.
9369     */
9370    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9371            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9372        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9373
9374        report.condition = condition;
9375        report.processName = app.processName;
9376        report.pid = app.pid;
9377        report.uid = app.info.uid;
9378        report.tag = activity;
9379        report.shortMsg = shortMsg;
9380        report.longMsg = longMsg;
9381        report.stackTrace = stackTrace;
9382
9383        return report;
9384    }
9385
9386    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9387        synchronized (this) {
9388            app.crashing = false;
9389            app.crashingReport = null;
9390            app.notResponding = false;
9391            app.notRespondingReport = null;
9392            if (app.anrDialog == fromDialog) {
9393                app.anrDialog = null;
9394            }
9395            if (app.waitDialog == fromDialog) {
9396                app.waitDialog = null;
9397            }
9398            if (app.pid > 0 && app.pid != MY_PID) {
9399                handleAppCrashLocked(app, null, null, null);
9400                killUnneededProcessLocked(app, "user request after error");
9401            }
9402        }
9403    }
9404
9405    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9406            String stackTrace) {
9407        long now = SystemClock.uptimeMillis();
9408
9409        Long crashTime;
9410        if (!app.isolated) {
9411            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9412        } else {
9413            crashTime = null;
9414        }
9415        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9416            // This process loses!
9417            Slog.w(TAG, "Process " + app.info.processName
9418                    + " has crashed too many times: killing!");
9419            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9420                    app.userId, app.info.processName, app.uid);
9421            mStackSupervisor.handleAppCrashLocked(app);
9422            if (!app.persistent) {
9423                // We don't want to start this process again until the user
9424                // explicitly does so...  but for persistent process, we really
9425                // need to keep it running.  If a persistent process is actually
9426                // repeatedly crashing, then badness for everyone.
9427                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9428                        app.info.processName);
9429                if (!app.isolated) {
9430                    // XXX We don't have a way to mark isolated processes
9431                    // as bad, since they don't have a peristent identity.
9432                    mBadProcesses.put(app.info.processName, app.uid,
9433                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9434                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9435                }
9436                app.bad = true;
9437                app.removed = true;
9438                // Don't let services in this process be restarted and potentially
9439                // annoy the user repeatedly.  Unless it is persistent, since those
9440                // processes run critical code.
9441                removeProcessLocked(app, false, false, "crash");
9442                mStackSupervisor.resumeTopActivitiesLocked();
9443                return false;
9444            }
9445            mStackSupervisor.resumeTopActivitiesLocked();
9446        } else {
9447            mStackSupervisor.finishTopRunningActivityLocked(app);
9448        }
9449
9450        // Bump up the crash count of any services currently running in the proc.
9451        for (int i=app.services.size()-1; i>=0; i--) {
9452            // Any services running in the application need to be placed
9453            // back in the pending list.
9454            ServiceRecord sr = app.services.valueAt(i);
9455            sr.crashCount++;
9456        }
9457
9458        // If the crashing process is what we consider to be the "home process" and it has been
9459        // replaced by a third-party app, clear the package preferred activities from packages
9460        // with a home activity running in the process to prevent a repeatedly crashing app
9461        // from blocking the user to manually clear the list.
9462        final ArrayList<ActivityRecord> activities = app.activities;
9463        if (app == mHomeProcess && activities.size() > 0
9464                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9465            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9466                final ActivityRecord r = activities.get(activityNdx);
9467                if (r.isHomeActivity()) {
9468                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9469                    try {
9470                        ActivityThread.getPackageManager()
9471                                .clearPackagePreferredActivities(r.packageName);
9472                    } catch (RemoteException c) {
9473                        // pm is in same process, this will never happen.
9474                    }
9475                }
9476            }
9477        }
9478
9479        if (!app.isolated) {
9480            // XXX Can't keep track of crash times for isolated processes,
9481            // because they don't have a perisistent identity.
9482            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9483        }
9484
9485        return true;
9486    }
9487
9488    void startAppProblemLocked(ProcessRecord app) {
9489        if (app.userId == mCurrentUserId) {
9490            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9491                    mContext, app.info.packageName, app.info.flags);
9492        } else {
9493            // If this app is not running under the current user, then we
9494            // can't give it a report button because that would require
9495            // launching the report UI under a different user.
9496            app.errorReportReceiver = null;
9497        }
9498        skipCurrentReceiverLocked(app);
9499    }
9500
9501    void skipCurrentReceiverLocked(ProcessRecord app) {
9502        for (BroadcastQueue queue : mBroadcastQueues) {
9503            queue.skipCurrentReceiverLocked(app);
9504        }
9505    }
9506
9507    /**
9508     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9509     * The application process will exit immediately after this call returns.
9510     * @param app object of the crashing app, null for the system server
9511     * @param crashInfo describing the exception
9512     */
9513    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9514        ProcessRecord r = findAppProcess(app, "Crash");
9515        final String processName = app == null ? "system_server"
9516                : (r == null ? "unknown" : r.processName);
9517
9518        handleApplicationCrashInner("crash", r, processName, crashInfo);
9519    }
9520
9521    /* Native crash reporting uses this inner version because it needs to be somewhat
9522     * decoupled from the AM-managed cleanup lifecycle
9523     */
9524    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9525            ApplicationErrorReport.CrashInfo crashInfo) {
9526        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9527                UserHandle.getUserId(Binder.getCallingUid()), processName,
9528                r == null ? -1 : r.info.flags,
9529                crashInfo.exceptionClassName,
9530                crashInfo.exceptionMessage,
9531                crashInfo.throwFileName,
9532                crashInfo.throwLineNumber);
9533
9534        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9535
9536        crashApplication(r, crashInfo);
9537    }
9538
9539    public void handleApplicationStrictModeViolation(
9540            IBinder app,
9541            int violationMask,
9542            StrictMode.ViolationInfo info) {
9543        ProcessRecord r = findAppProcess(app, "StrictMode");
9544        if (r == null) {
9545            return;
9546        }
9547
9548        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9549            Integer stackFingerprint = info.hashCode();
9550            boolean logIt = true;
9551            synchronized (mAlreadyLoggedViolatedStacks) {
9552                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9553                    logIt = false;
9554                    // TODO: sub-sample into EventLog for these, with
9555                    // the info.durationMillis?  Then we'd get
9556                    // the relative pain numbers, without logging all
9557                    // the stack traces repeatedly.  We'd want to do
9558                    // likewise in the client code, which also does
9559                    // dup suppression, before the Binder call.
9560                } else {
9561                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9562                        mAlreadyLoggedViolatedStacks.clear();
9563                    }
9564                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9565                }
9566            }
9567            if (logIt) {
9568                logStrictModeViolationToDropBox(r, info);
9569            }
9570        }
9571
9572        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9573            AppErrorResult result = new AppErrorResult();
9574            synchronized (this) {
9575                final long origId = Binder.clearCallingIdentity();
9576
9577                Message msg = Message.obtain();
9578                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9579                HashMap<String, Object> data = new HashMap<String, Object>();
9580                data.put("result", result);
9581                data.put("app", r);
9582                data.put("violationMask", violationMask);
9583                data.put("info", info);
9584                msg.obj = data;
9585                mHandler.sendMessage(msg);
9586
9587                Binder.restoreCallingIdentity(origId);
9588            }
9589            int res = result.get();
9590            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9591        }
9592    }
9593
9594    // Depending on the policy in effect, there could be a bunch of
9595    // these in quick succession so we try to batch these together to
9596    // minimize disk writes, number of dropbox entries, and maximize
9597    // compression, by having more fewer, larger records.
9598    private void logStrictModeViolationToDropBox(
9599            ProcessRecord process,
9600            StrictMode.ViolationInfo info) {
9601        if (info == null) {
9602            return;
9603        }
9604        final boolean isSystemApp = process == null ||
9605                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9606                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9607        final String processName = process == null ? "unknown" : process.processName;
9608        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9609        final DropBoxManager dbox = (DropBoxManager)
9610                mContext.getSystemService(Context.DROPBOX_SERVICE);
9611
9612        // Exit early if the dropbox isn't configured to accept this report type.
9613        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9614
9615        boolean bufferWasEmpty;
9616        boolean needsFlush;
9617        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9618        synchronized (sb) {
9619            bufferWasEmpty = sb.length() == 0;
9620            appendDropBoxProcessHeaders(process, processName, sb);
9621            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9622            sb.append("System-App: ").append(isSystemApp).append("\n");
9623            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9624            if (info.violationNumThisLoop != 0) {
9625                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9626            }
9627            if (info.numAnimationsRunning != 0) {
9628                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9629            }
9630            if (info.broadcastIntentAction != null) {
9631                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9632            }
9633            if (info.durationMillis != -1) {
9634                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9635            }
9636            if (info.numInstances != -1) {
9637                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9638            }
9639            if (info.tags != null) {
9640                for (String tag : info.tags) {
9641                    sb.append("Span-Tag: ").append(tag).append("\n");
9642                }
9643            }
9644            sb.append("\n");
9645            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9646                sb.append(info.crashInfo.stackTrace);
9647            }
9648            sb.append("\n");
9649
9650            // Only buffer up to ~64k.  Various logging bits truncate
9651            // things at 128k.
9652            needsFlush = (sb.length() > 64 * 1024);
9653        }
9654
9655        // Flush immediately if the buffer's grown too large, or this
9656        // is a non-system app.  Non-system apps are isolated with a
9657        // different tag & policy and not batched.
9658        //
9659        // Batching is useful during internal testing with
9660        // StrictMode settings turned up high.  Without batching,
9661        // thousands of separate files could be created on boot.
9662        if (!isSystemApp || needsFlush) {
9663            new Thread("Error dump: " + dropboxTag) {
9664                @Override
9665                public void run() {
9666                    String report;
9667                    synchronized (sb) {
9668                        report = sb.toString();
9669                        sb.delete(0, sb.length());
9670                        sb.trimToSize();
9671                    }
9672                    if (report.length() != 0) {
9673                        dbox.addText(dropboxTag, report);
9674                    }
9675                }
9676            }.start();
9677            return;
9678        }
9679
9680        // System app batching:
9681        if (!bufferWasEmpty) {
9682            // An existing dropbox-writing thread is outstanding, so
9683            // we don't need to start it up.  The existing thread will
9684            // catch the buffer appends we just did.
9685            return;
9686        }
9687
9688        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9689        // (After this point, we shouldn't access AMS internal data structures.)
9690        new Thread("Error dump: " + dropboxTag) {
9691            @Override
9692            public void run() {
9693                // 5 second sleep to let stacks arrive and be batched together
9694                try {
9695                    Thread.sleep(5000);  // 5 seconds
9696                } catch (InterruptedException e) {}
9697
9698                String errorReport;
9699                synchronized (mStrictModeBuffer) {
9700                    errorReport = mStrictModeBuffer.toString();
9701                    if (errorReport.length() == 0) {
9702                        return;
9703                    }
9704                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9705                    mStrictModeBuffer.trimToSize();
9706                }
9707                dbox.addText(dropboxTag, errorReport);
9708            }
9709        }.start();
9710    }
9711
9712    /**
9713     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9714     * @param app object of the crashing app, null for the system server
9715     * @param tag reported by the caller
9716     * @param crashInfo describing the context of the error
9717     * @return true if the process should exit immediately (WTF is fatal)
9718     */
9719    public boolean handleApplicationWtf(IBinder app, String tag,
9720            ApplicationErrorReport.CrashInfo crashInfo) {
9721        ProcessRecord r = findAppProcess(app, "WTF");
9722        final String processName = app == null ? "system_server"
9723                : (r == null ? "unknown" : r.processName);
9724
9725        EventLog.writeEvent(EventLogTags.AM_WTF,
9726                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9727                processName,
9728                r == null ? -1 : r.info.flags,
9729                tag, crashInfo.exceptionMessage);
9730
9731        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9732
9733        if (r != null && r.pid != Process.myPid() &&
9734                Settings.Global.getInt(mContext.getContentResolver(),
9735                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9736            crashApplication(r, crashInfo);
9737            return true;
9738        } else {
9739            return false;
9740        }
9741    }
9742
9743    /**
9744     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9745     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9746     */
9747    private ProcessRecord findAppProcess(IBinder app, String reason) {
9748        if (app == null) {
9749            return null;
9750        }
9751
9752        synchronized (this) {
9753            final int NP = mProcessNames.getMap().size();
9754            for (int ip=0; ip<NP; ip++) {
9755                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9756                final int NA = apps.size();
9757                for (int ia=0; ia<NA; ia++) {
9758                    ProcessRecord p = apps.valueAt(ia);
9759                    if (p.thread != null && p.thread.asBinder() == app) {
9760                        return p;
9761                    }
9762                }
9763            }
9764
9765            Slog.w(TAG, "Can't find mystery application for " + reason
9766                    + " from pid=" + Binder.getCallingPid()
9767                    + " uid=" + Binder.getCallingUid() + ": " + app);
9768            return null;
9769        }
9770    }
9771
9772    /**
9773     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9774     * to append various headers to the dropbox log text.
9775     */
9776    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9777            StringBuilder sb) {
9778        // Watchdog thread ends up invoking this function (with
9779        // a null ProcessRecord) to add the stack file to dropbox.
9780        // Do not acquire a lock on this (am) in such cases, as it
9781        // could cause a potential deadlock, if and when watchdog
9782        // is invoked due to unavailability of lock on am and it
9783        // would prevent watchdog from killing system_server.
9784        if (process == null) {
9785            sb.append("Process: ").append(processName).append("\n");
9786            return;
9787        }
9788        // Note: ProcessRecord 'process' is guarded by the service
9789        // instance.  (notably process.pkgList, which could otherwise change
9790        // concurrently during execution of this method)
9791        synchronized (this) {
9792            sb.append("Process: ").append(processName).append("\n");
9793            int flags = process.info.flags;
9794            IPackageManager pm = AppGlobals.getPackageManager();
9795            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9796            for (int ip=0; ip<process.pkgList.size(); ip++) {
9797                String pkg = process.pkgList.keyAt(ip);
9798                sb.append("Package: ").append(pkg);
9799                try {
9800                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9801                    if (pi != null) {
9802                        sb.append(" v").append(pi.versionCode);
9803                        if (pi.versionName != null) {
9804                            sb.append(" (").append(pi.versionName).append(")");
9805                        }
9806                    }
9807                } catch (RemoteException e) {
9808                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9809                }
9810                sb.append("\n");
9811            }
9812        }
9813    }
9814
9815    private static String processClass(ProcessRecord process) {
9816        if (process == null || process.pid == MY_PID) {
9817            return "system_server";
9818        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9819            return "system_app";
9820        } else {
9821            return "data_app";
9822        }
9823    }
9824
9825    /**
9826     * Write a description of an error (crash, WTF, ANR) to the drop box.
9827     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9828     * @param process which caused the error, null means the system server
9829     * @param activity which triggered the error, null if unknown
9830     * @param parent activity related to the error, null if unknown
9831     * @param subject line related to the error, null if absent
9832     * @param report in long form describing the error, null if absent
9833     * @param logFile to include in the report, null if none
9834     * @param crashInfo giving an application stack trace, null if absent
9835     */
9836    public void addErrorToDropBox(String eventType,
9837            ProcessRecord process, String processName, ActivityRecord activity,
9838            ActivityRecord parent, String subject,
9839            final String report, final File logFile,
9840            final ApplicationErrorReport.CrashInfo crashInfo) {
9841        // NOTE -- this must never acquire the ActivityManagerService lock,
9842        // otherwise the watchdog may be prevented from resetting the system.
9843
9844        final String dropboxTag = processClass(process) + "_" + eventType;
9845        final DropBoxManager dbox = (DropBoxManager)
9846                mContext.getSystemService(Context.DROPBOX_SERVICE);
9847
9848        // Exit early if the dropbox isn't configured to accept this report type.
9849        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9850
9851        final StringBuilder sb = new StringBuilder(1024);
9852        appendDropBoxProcessHeaders(process, processName, sb);
9853        if (activity != null) {
9854            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9855        }
9856        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9857            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9858        }
9859        if (parent != null && parent != activity) {
9860            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9861        }
9862        if (subject != null) {
9863            sb.append("Subject: ").append(subject).append("\n");
9864        }
9865        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9866        if (Debug.isDebuggerConnected()) {
9867            sb.append("Debugger: Connected\n");
9868        }
9869        sb.append("\n");
9870
9871        // Do the rest in a worker thread to avoid blocking the caller on I/O
9872        // (After this point, we shouldn't access AMS internal data structures.)
9873        Thread worker = new Thread("Error dump: " + dropboxTag) {
9874            @Override
9875            public void run() {
9876                if (report != null) {
9877                    sb.append(report);
9878                }
9879                if (logFile != null) {
9880                    try {
9881                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9882                                    "\n\n[[TRUNCATED]]"));
9883                    } catch (IOException e) {
9884                        Slog.e(TAG, "Error reading " + logFile, e);
9885                    }
9886                }
9887                if (crashInfo != null && crashInfo.stackTrace != null) {
9888                    sb.append(crashInfo.stackTrace);
9889                }
9890
9891                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9892                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9893                if (lines > 0) {
9894                    sb.append("\n");
9895
9896                    // Merge several logcat streams, and take the last N lines
9897                    InputStreamReader input = null;
9898                    try {
9899                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9900                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9901                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9902
9903                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9904                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9905                        input = new InputStreamReader(logcat.getInputStream());
9906
9907                        int num;
9908                        char[] buf = new char[8192];
9909                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9910                    } catch (IOException e) {
9911                        Slog.e(TAG, "Error running logcat", e);
9912                    } finally {
9913                        if (input != null) try { input.close(); } catch (IOException e) {}
9914                    }
9915                }
9916
9917                dbox.addText(dropboxTag, sb.toString());
9918            }
9919        };
9920
9921        if (process == null) {
9922            // If process is null, we are being called from some internal code
9923            // and may be about to die -- run this synchronously.
9924            worker.run();
9925        } else {
9926            worker.start();
9927        }
9928    }
9929
9930    /**
9931     * Bring up the "unexpected error" dialog box for a crashing app.
9932     * Deal with edge cases (intercepts from instrumented applications,
9933     * ActivityController, error intent receivers, that sort of thing).
9934     * @param r the application crashing
9935     * @param crashInfo describing the failure
9936     */
9937    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9938        long timeMillis = System.currentTimeMillis();
9939        String shortMsg = crashInfo.exceptionClassName;
9940        String longMsg = crashInfo.exceptionMessage;
9941        String stackTrace = crashInfo.stackTrace;
9942        if (shortMsg != null && longMsg != null) {
9943            longMsg = shortMsg + ": " + longMsg;
9944        } else if (shortMsg != null) {
9945            longMsg = shortMsg;
9946        }
9947
9948        AppErrorResult result = new AppErrorResult();
9949        synchronized (this) {
9950            if (mController != null) {
9951                try {
9952                    String name = r != null ? r.processName : null;
9953                    int pid = r != null ? r.pid : Binder.getCallingPid();
9954                    if (!mController.appCrashed(name, pid,
9955                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9956                        Slog.w(TAG, "Force-killing crashed app " + name
9957                                + " at watcher's request");
9958                        Process.killProcess(pid);
9959                        return;
9960                    }
9961                } catch (RemoteException e) {
9962                    mController = null;
9963                    Watchdog.getInstance().setActivityController(null);
9964                }
9965            }
9966
9967            final long origId = Binder.clearCallingIdentity();
9968
9969            // If this process is running instrumentation, finish it.
9970            if (r != null && r.instrumentationClass != null) {
9971                Slog.w(TAG, "Error in app " + r.processName
9972                      + " running instrumentation " + r.instrumentationClass + ":");
9973                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
9974                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
9975                Bundle info = new Bundle();
9976                info.putString("shortMsg", shortMsg);
9977                info.putString("longMsg", longMsg);
9978                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
9979                Binder.restoreCallingIdentity(origId);
9980                return;
9981            }
9982
9983            // If we can't identify the process or it's already exceeded its crash quota,
9984            // quit right away without showing a crash dialog.
9985            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
9986                Binder.restoreCallingIdentity(origId);
9987                return;
9988            }
9989
9990            Message msg = Message.obtain();
9991            msg.what = SHOW_ERROR_MSG;
9992            HashMap data = new HashMap();
9993            data.put("result", result);
9994            data.put("app", r);
9995            msg.obj = data;
9996            mHandler.sendMessage(msg);
9997
9998            Binder.restoreCallingIdentity(origId);
9999        }
10000
10001        int res = result.get();
10002
10003        Intent appErrorIntent = null;
10004        synchronized (this) {
10005            if (r != null && !r.isolated) {
10006                // XXX Can't keep track of crash time for isolated processes,
10007                // since they don't have a persistent identity.
10008                mProcessCrashTimes.put(r.info.processName, r.uid,
10009                        SystemClock.uptimeMillis());
10010            }
10011            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10012                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10013            }
10014        }
10015
10016        if (appErrorIntent != null) {
10017            try {
10018                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10019            } catch (ActivityNotFoundException e) {
10020                Slog.w(TAG, "bug report receiver dissappeared", e);
10021            }
10022        }
10023    }
10024
10025    Intent createAppErrorIntentLocked(ProcessRecord r,
10026            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10027        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10028        if (report == null) {
10029            return null;
10030        }
10031        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10032        result.setComponent(r.errorReportReceiver);
10033        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10034        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10035        return result;
10036    }
10037
10038    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10039            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10040        if (r.errorReportReceiver == null) {
10041            return null;
10042        }
10043
10044        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10045            return null;
10046        }
10047
10048        ApplicationErrorReport report = new ApplicationErrorReport();
10049        report.packageName = r.info.packageName;
10050        report.installerPackageName = r.errorReportReceiver.getPackageName();
10051        report.processName = r.processName;
10052        report.time = timeMillis;
10053        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10054
10055        if (r.crashing || r.forceCrashReport) {
10056            report.type = ApplicationErrorReport.TYPE_CRASH;
10057            report.crashInfo = crashInfo;
10058        } else if (r.notResponding) {
10059            report.type = ApplicationErrorReport.TYPE_ANR;
10060            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10061
10062            report.anrInfo.activity = r.notRespondingReport.tag;
10063            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10064            report.anrInfo.info = r.notRespondingReport.longMsg;
10065        }
10066
10067        return report;
10068    }
10069
10070    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10071        enforceNotIsolatedCaller("getProcessesInErrorState");
10072        // assume our apps are happy - lazy create the list
10073        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10074
10075        final boolean allUsers = ActivityManager.checkUidPermission(
10076                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10077                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10078        int userId = UserHandle.getUserId(Binder.getCallingUid());
10079
10080        synchronized (this) {
10081
10082            // iterate across all processes
10083            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10084                ProcessRecord app = mLruProcesses.get(i);
10085                if (!allUsers && app.userId != userId) {
10086                    continue;
10087                }
10088                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10089                    // This one's in trouble, so we'll generate a report for it
10090                    // crashes are higher priority (in case there's a crash *and* an anr)
10091                    ActivityManager.ProcessErrorStateInfo report = null;
10092                    if (app.crashing) {
10093                        report = app.crashingReport;
10094                    } else if (app.notResponding) {
10095                        report = app.notRespondingReport;
10096                    }
10097
10098                    if (report != null) {
10099                        if (errList == null) {
10100                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10101                        }
10102                        errList.add(report);
10103                    } else {
10104                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10105                                " crashing = " + app.crashing +
10106                                " notResponding = " + app.notResponding);
10107                    }
10108                }
10109            }
10110        }
10111
10112        return errList;
10113    }
10114
10115    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10116        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10117            if (currApp != null) {
10118                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10119            }
10120            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10121        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10122            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10123        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10124            if (currApp != null) {
10125                currApp.lru = 0;
10126            }
10127            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10128        } else if (adj >= ProcessList.SERVICE_ADJ) {
10129            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10130        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10131            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10132        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10133            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10134        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10135            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10136        } else {
10137            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10138        }
10139    }
10140
10141    private void fillInProcMemInfo(ProcessRecord app,
10142            ActivityManager.RunningAppProcessInfo outInfo) {
10143        outInfo.pid = app.pid;
10144        outInfo.uid = app.info.uid;
10145        if (mHeavyWeightProcess == app) {
10146            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10147        }
10148        if (app.persistent) {
10149            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10150        }
10151        if (app.activities.size() > 0) {
10152            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10153        }
10154        outInfo.lastTrimLevel = app.trimMemoryLevel;
10155        int adj = app.curAdj;
10156        outInfo.importance = oomAdjToImportance(adj, outInfo);
10157        outInfo.importanceReasonCode = app.adjTypeCode;
10158    }
10159
10160    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10161        enforceNotIsolatedCaller("getRunningAppProcesses");
10162        // Lazy instantiation of list
10163        List<ActivityManager.RunningAppProcessInfo> runList = null;
10164        final boolean allUsers = ActivityManager.checkUidPermission(
10165                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10166                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10167        int userId = UserHandle.getUserId(Binder.getCallingUid());
10168        synchronized (this) {
10169            // Iterate across all processes
10170            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10171                ProcessRecord app = mLruProcesses.get(i);
10172                if (!allUsers && app.userId != userId) {
10173                    continue;
10174                }
10175                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10176                    // Generate process state info for running application
10177                    ActivityManager.RunningAppProcessInfo currApp =
10178                        new ActivityManager.RunningAppProcessInfo(app.processName,
10179                                app.pid, app.getPackageList());
10180                    fillInProcMemInfo(app, currApp);
10181                    if (app.adjSource instanceof ProcessRecord) {
10182                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10183                        currApp.importanceReasonImportance = oomAdjToImportance(
10184                                app.adjSourceOom, null);
10185                    } else if (app.adjSource instanceof ActivityRecord) {
10186                        ActivityRecord r = (ActivityRecord)app.adjSource;
10187                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10188                    }
10189                    if (app.adjTarget instanceof ComponentName) {
10190                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10191                    }
10192                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10193                    //        + " lru=" + currApp.lru);
10194                    if (runList == null) {
10195                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10196                    }
10197                    runList.add(currApp);
10198                }
10199            }
10200        }
10201        return runList;
10202    }
10203
10204    public List<ApplicationInfo> getRunningExternalApplications() {
10205        enforceNotIsolatedCaller("getRunningExternalApplications");
10206        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10207        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10208        if (runningApps != null && runningApps.size() > 0) {
10209            Set<String> extList = new HashSet<String>();
10210            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10211                if (app.pkgList != null) {
10212                    for (String pkg : app.pkgList) {
10213                        extList.add(pkg);
10214                    }
10215                }
10216            }
10217            IPackageManager pm = AppGlobals.getPackageManager();
10218            for (String pkg : extList) {
10219                try {
10220                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10221                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10222                        retList.add(info);
10223                    }
10224                } catch (RemoteException e) {
10225                }
10226            }
10227        }
10228        return retList;
10229    }
10230
10231    @Override
10232    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10233        enforceNotIsolatedCaller("getMyMemoryState");
10234        synchronized (this) {
10235            ProcessRecord proc;
10236            synchronized (mPidsSelfLocked) {
10237                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10238            }
10239            fillInProcMemInfo(proc, outInfo);
10240        }
10241    }
10242
10243    @Override
10244    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10245        if (checkCallingPermission(android.Manifest.permission.DUMP)
10246                != PackageManager.PERMISSION_GRANTED) {
10247            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10248                    + Binder.getCallingPid()
10249                    + ", uid=" + Binder.getCallingUid()
10250                    + " without permission "
10251                    + android.Manifest.permission.DUMP);
10252            return;
10253        }
10254
10255        boolean dumpAll = false;
10256        boolean dumpClient = false;
10257        String dumpPackage = null;
10258
10259        int opti = 0;
10260        while (opti < args.length) {
10261            String opt = args[opti];
10262            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10263                break;
10264            }
10265            opti++;
10266            if ("-a".equals(opt)) {
10267                dumpAll = true;
10268            } else if ("-c".equals(opt)) {
10269                dumpClient = true;
10270            } else if ("-h".equals(opt)) {
10271                pw.println("Activity manager dump options:");
10272                pw.println("  [-a] [-c] [-h] [cmd] ...");
10273                pw.println("  cmd may be one of:");
10274                pw.println("    a[ctivities]: activity stack state");
10275                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10276                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10277                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10278                pw.println("    o[om]: out of memory management");
10279                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10280                pw.println("    provider [COMP_SPEC]: provider client-side state");
10281                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10282                pw.println("    service [COMP_SPEC]: service client-side state");
10283                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10284                pw.println("    all: dump all activities");
10285                pw.println("    top: dump the top activity");
10286                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10287                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10288                pw.println("    a partial substring in a component name, a");
10289                pw.println("    hex object identifier.");
10290                pw.println("  -a: include all available server state.");
10291                pw.println("  -c: include client state.");
10292                return;
10293            } else {
10294                pw.println("Unknown argument: " + opt + "; use -h for help");
10295            }
10296        }
10297
10298        long origId = Binder.clearCallingIdentity();
10299        boolean more = false;
10300        // Is the caller requesting to dump a particular piece of data?
10301        if (opti < args.length) {
10302            String cmd = args[opti];
10303            opti++;
10304            if ("activities".equals(cmd) || "a".equals(cmd)) {
10305                synchronized (this) {
10306                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10307                }
10308            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10309                String[] newArgs;
10310                String name;
10311                if (opti >= args.length) {
10312                    name = null;
10313                    newArgs = EMPTY_STRING_ARRAY;
10314                } else {
10315                    name = args[opti];
10316                    opti++;
10317                    newArgs = new String[args.length - opti];
10318                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10319                            args.length - opti);
10320                }
10321                synchronized (this) {
10322                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10323                }
10324            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10325                String[] newArgs;
10326                String name;
10327                if (opti >= args.length) {
10328                    name = null;
10329                    newArgs = EMPTY_STRING_ARRAY;
10330                } else {
10331                    name = args[opti];
10332                    opti++;
10333                    newArgs = new String[args.length - opti];
10334                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10335                            args.length - opti);
10336                }
10337                synchronized (this) {
10338                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10339                }
10340            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10341                String[] newArgs;
10342                String name;
10343                if (opti >= args.length) {
10344                    name = null;
10345                    newArgs = EMPTY_STRING_ARRAY;
10346                } else {
10347                    name = args[opti];
10348                    opti++;
10349                    newArgs = new String[args.length - opti];
10350                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10351                            args.length - opti);
10352                }
10353                synchronized (this) {
10354                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10355                }
10356            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10357                synchronized (this) {
10358                    dumpOomLocked(fd, pw, args, opti, true);
10359                }
10360            } else if ("provider".equals(cmd)) {
10361                String[] newArgs;
10362                String name;
10363                if (opti >= args.length) {
10364                    name = null;
10365                    newArgs = EMPTY_STRING_ARRAY;
10366                } else {
10367                    name = args[opti];
10368                    opti++;
10369                    newArgs = new String[args.length - opti];
10370                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10371                }
10372                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10373                    pw.println("No providers match: " + name);
10374                    pw.println("Use -h for help.");
10375                }
10376            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10377                synchronized (this) {
10378                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10379                }
10380            } else if ("service".equals(cmd)) {
10381                String[] newArgs;
10382                String name;
10383                if (opti >= args.length) {
10384                    name = null;
10385                    newArgs = EMPTY_STRING_ARRAY;
10386                } else {
10387                    name = args[opti];
10388                    opti++;
10389                    newArgs = new String[args.length - opti];
10390                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10391                            args.length - opti);
10392                }
10393                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10394                    pw.println("No services match: " + name);
10395                    pw.println("Use -h for help.");
10396                }
10397            } else if ("package".equals(cmd)) {
10398                String[] newArgs;
10399                if (opti >= args.length) {
10400                    pw.println("package: no package name specified");
10401                    pw.println("Use -h for help.");
10402                } else {
10403                    dumpPackage = args[opti];
10404                    opti++;
10405                    newArgs = new String[args.length - opti];
10406                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10407                            args.length - opti);
10408                    args = newArgs;
10409                    opti = 0;
10410                    more = true;
10411                }
10412            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10413                synchronized (this) {
10414                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10415                }
10416            } else {
10417                // Dumping a single activity?
10418                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10419                    pw.println("Bad activity command, or no activities match: " + cmd);
10420                    pw.println("Use -h for help.");
10421                }
10422            }
10423            if (!more) {
10424                Binder.restoreCallingIdentity(origId);
10425                return;
10426            }
10427        }
10428
10429        // No piece of data specified, dump everything.
10430        synchronized (this) {
10431            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10432            pw.println();
10433            if (dumpAll) {
10434                pw.println("-------------------------------------------------------------------------------");
10435            }
10436            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10437            pw.println();
10438            if (dumpAll) {
10439                pw.println("-------------------------------------------------------------------------------");
10440            }
10441            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10442            pw.println();
10443            if (dumpAll) {
10444                pw.println("-------------------------------------------------------------------------------");
10445            }
10446            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10447            pw.println();
10448            if (dumpAll) {
10449                pw.println("-------------------------------------------------------------------------------");
10450            }
10451            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10452            pw.println();
10453            if (dumpAll) {
10454                pw.println("-------------------------------------------------------------------------------");
10455            }
10456            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10457        }
10458        Binder.restoreCallingIdentity(origId);
10459    }
10460
10461    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10462            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10463        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10464
10465        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10466                dumpPackage);
10467        boolean needSep = printedAnything;
10468
10469        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10470                dumpPackage, needSep, "  mFocusedActivity: ");
10471        if (printed) {
10472            printedAnything = true;
10473            needSep = false;
10474        }
10475
10476        if (dumpPackage == null) {
10477            if (needSep) {
10478                pw.println();
10479            }
10480            needSep = true;
10481            printedAnything = true;
10482            mStackSupervisor.dump(pw, "  ");
10483        }
10484
10485        if (mRecentTasks.size() > 0) {
10486            boolean printedHeader = false;
10487
10488            final int N = mRecentTasks.size();
10489            for (int i=0; i<N; i++) {
10490                TaskRecord tr = mRecentTasks.get(i);
10491                if (dumpPackage != null) {
10492                    if (tr.realActivity == null ||
10493                            !dumpPackage.equals(tr.realActivity)) {
10494                        continue;
10495                    }
10496                }
10497                if (!printedHeader) {
10498                    if (needSep) {
10499                        pw.println();
10500                    }
10501                    pw.println("  Recent tasks:");
10502                    printedHeader = true;
10503                    printedAnything = true;
10504                }
10505                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10506                        pw.println(tr);
10507                if (dumpAll) {
10508                    mRecentTasks.get(i).dump(pw, "    ");
10509                }
10510            }
10511        }
10512
10513        if (!printedAnything) {
10514            pw.println("  (nothing)");
10515        }
10516    }
10517
10518    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10519            int opti, boolean dumpAll, String dumpPackage) {
10520        boolean needSep = false;
10521        boolean printedAnything = false;
10522        int numPers = 0;
10523
10524        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10525
10526        if (dumpAll) {
10527            final int NP = mProcessNames.getMap().size();
10528            for (int ip=0; ip<NP; ip++) {
10529                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10530                final int NA = procs.size();
10531                for (int ia=0; ia<NA; ia++) {
10532                    ProcessRecord r = procs.valueAt(ia);
10533                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10534                        continue;
10535                    }
10536                    if (!needSep) {
10537                        pw.println("  All known processes:");
10538                        needSep = true;
10539                        printedAnything = true;
10540                    }
10541                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10542                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10543                        pw.print(" "); pw.println(r);
10544                    r.dump(pw, "    ");
10545                    if (r.persistent) {
10546                        numPers++;
10547                    }
10548                }
10549            }
10550        }
10551
10552        if (mIsolatedProcesses.size() > 0) {
10553            boolean printed = false;
10554            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10555                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10556                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10557                    continue;
10558                }
10559                if (!printed) {
10560                    if (needSep) {
10561                        pw.println();
10562                    }
10563                    pw.println("  Isolated process list (sorted by uid):");
10564                    printedAnything = true;
10565                    printed = true;
10566                    needSep = true;
10567                }
10568                pw.println(String.format("%sIsolated #%2d: %s",
10569                        "    ", i, r.toString()));
10570            }
10571        }
10572
10573        if (mLruProcesses.size() > 0) {
10574            if (needSep) {
10575                pw.println();
10576            }
10577            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10578                    pw.print(" total, non-act at ");
10579                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10580                    pw.print(", non-svc at ");
10581                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10582                    pw.println("):");
10583            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10584            needSep = true;
10585            printedAnything = true;
10586        }
10587
10588        if (dumpAll || dumpPackage != null) {
10589            synchronized (mPidsSelfLocked) {
10590                boolean printed = false;
10591                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10592                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10593                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10594                        continue;
10595                    }
10596                    if (!printed) {
10597                        if (needSep) pw.println();
10598                        needSep = true;
10599                        pw.println("  PID mappings:");
10600                        printed = true;
10601                        printedAnything = true;
10602                    }
10603                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10604                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10605                }
10606            }
10607        }
10608
10609        if (mForegroundProcesses.size() > 0) {
10610            synchronized (mPidsSelfLocked) {
10611                boolean printed = false;
10612                for (int i=0; i<mForegroundProcesses.size(); i++) {
10613                    ProcessRecord r = mPidsSelfLocked.get(
10614                            mForegroundProcesses.valueAt(i).pid);
10615                    if (dumpPackage != null && (r == null
10616                            || !r.pkgList.containsKey(dumpPackage))) {
10617                        continue;
10618                    }
10619                    if (!printed) {
10620                        if (needSep) pw.println();
10621                        needSep = true;
10622                        pw.println("  Foreground Processes:");
10623                        printed = true;
10624                        printedAnything = true;
10625                    }
10626                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10627                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10628                }
10629            }
10630        }
10631
10632        if (mPersistentStartingProcesses.size() > 0) {
10633            if (needSep) pw.println();
10634            needSep = true;
10635            printedAnything = true;
10636            pw.println("  Persisent processes that are starting:");
10637            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10638                    "Starting Norm", "Restarting PERS", dumpPackage);
10639        }
10640
10641        if (mRemovedProcesses.size() > 0) {
10642            if (needSep) pw.println();
10643            needSep = true;
10644            printedAnything = true;
10645            pw.println("  Processes that are being removed:");
10646            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10647                    "Removed Norm", "Removed PERS", dumpPackage);
10648        }
10649
10650        if (mProcessesOnHold.size() > 0) {
10651            if (needSep) pw.println();
10652            needSep = true;
10653            printedAnything = true;
10654            pw.println("  Processes that are on old until the system is ready:");
10655            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10656                    "OnHold Norm", "OnHold PERS", dumpPackage);
10657        }
10658
10659        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10660
10661        if (mProcessCrashTimes.getMap().size() > 0) {
10662            boolean printed = false;
10663            long now = SystemClock.uptimeMillis();
10664            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10665            final int NP = pmap.size();
10666            for (int ip=0; ip<NP; ip++) {
10667                String pname = pmap.keyAt(ip);
10668                SparseArray<Long> uids = pmap.valueAt(ip);
10669                final int N = uids.size();
10670                for (int i=0; i<N; i++) {
10671                    int puid = uids.keyAt(i);
10672                    ProcessRecord r = mProcessNames.get(pname, puid);
10673                    if (dumpPackage != null && (r == null
10674                            || !r.pkgList.containsKey(dumpPackage))) {
10675                        continue;
10676                    }
10677                    if (!printed) {
10678                        if (needSep) pw.println();
10679                        needSep = true;
10680                        pw.println("  Time since processes crashed:");
10681                        printed = true;
10682                        printedAnything = true;
10683                    }
10684                    pw.print("    Process "); pw.print(pname);
10685                            pw.print(" uid "); pw.print(puid);
10686                            pw.print(": last crashed ");
10687                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10688                            pw.println(" ago");
10689                }
10690            }
10691        }
10692
10693        if (mBadProcesses.getMap().size() > 0) {
10694            boolean printed = false;
10695            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10696            final int NP = pmap.size();
10697            for (int ip=0; ip<NP; ip++) {
10698                String pname = pmap.keyAt(ip);
10699                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10700                final int N = uids.size();
10701                for (int i=0; i<N; i++) {
10702                    int puid = uids.keyAt(i);
10703                    ProcessRecord r = mProcessNames.get(pname, puid);
10704                    if (dumpPackage != null && (r == null
10705                            || !r.pkgList.containsKey(dumpPackage))) {
10706                        continue;
10707                    }
10708                    if (!printed) {
10709                        if (needSep) pw.println();
10710                        needSep = true;
10711                        pw.println("  Bad processes:");
10712                        printedAnything = true;
10713                    }
10714                    BadProcessInfo info = uids.valueAt(i);
10715                    pw.print("    Bad process "); pw.print(pname);
10716                            pw.print(" uid "); pw.print(puid);
10717                            pw.print(": crashed at time "); pw.println(info.time);
10718                    if (info.shortMsg != null) {
10719                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10720                    }
10721                    if (info.longMsg != null) {
10722                        pw.print("      Long msg: "); pw.println(info.longMsg);
10723                    }
10724                    if (info.stack != null) {
10725                        pw.println("      Stack:");
10726                        int lastPos = 0;
10727                        for (int pos=0; pos<info.stack.length(); pos++) {
10728                            if (info.stack.charAt(pos) == '\n') {
10729                                pw.print("        ");
10730                                pw.write(info.stack, lastPos, pos-lastPos);
10731                                pw.println();
10732                                lastPos = pos+1;
10733                            }
10734                        }
10735                        if (lastPos < info.stack.length()) {
10736                            pw.print("        ");
10737                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10738                            pw.println();
10739                        }
10740                    }
10741                }
10742            }
10743        }
10744
10745        if (dumpPackage == null) {
10746            pw.println();
10747            needSep = false;
10748            pw.println("  mStartedUsers:");
10749            for (int i=0; i<mStartedUsers.size(); i++) {
10750                UserStartedState uss = mStartedUsers.valueAt(i);
10751                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10752                        pw.print(": "); uss.dump("", pw);
10753            }
10754            pw.print("  mStartedUserArray: [");
10755            for (int i=0; i<mStartedUserArray.length; i++) {
10756                if (i > 0) pw.print(", ");
10757                pw.print(mStartedUserArray[i]);
10758            }
10759            pw.println("]");
10760            pw.print("  mUserLru: [");
10761            for (int i=0; i<mUserLru.size(); i++) {
10762                if (i > 0) pw.print(", ");
10763                pw.print(mUserLru.get(i));
10764            }
10765            pw.println("]");
10766            if (dumpAll) {
10767                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10768            }
10769        }
10770        if (mHomeProcess != null && (dumpPackage == null
10771                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10772            if (needSep) {
10773                pw.println();
10774                needSep = false;
10775            }
10776            pw.println("  mHomeProcess: " + mHomeProcess);
10777        }
10778        if (mPreviousProcess != null && (dumpPackage == null
10779                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10780            if (needSep) {
10781                pw.println();
10782                needSep = false;
10783            }
10784            pw.println("  mPreviousProcess: " + mPreviousProcess);
10785        }
10786        if (dumpAll) {
10787            StringBuilder sb = new StringBuilder(128);
10788            sb.append("  mPreviousProcessVisibleTime: ");
10789            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10790            pw.println(sb);
10791        }
10792        if (mHeavyWeightProcess != null && (dumpPackage == null
10793                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10794            if (needSep) {
10795                pw.println();
10796                needSep = false;
10797            }
10798            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10799        }
10800        if (dumpPackage == null) {
10801            pw.println("  mConfiguration: " + mConfiguration);
10802        }
10803        if (dumpAll) {
10804            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10805            if (mCompatModePackages.getPackages().size() > 0) {
10806                boolean printed = false;
10807                for (Map.Entry<String, Integer> entry
10808                        : mCompatModePackages.getPackages().entrySet()) {
10809                    String pkg = entry.getKey();
10810                    int mode = entry.getValue();
10811                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10812                        continue;
10813                    }
10814                    if (!printed) {
10815                        pw.println("  mScreenCompatPackages:");
10816                        printed = true;
10817                    }
10818                    pw.print("    "); pw.print(pkg); pw.print(": ");
10819                            pw.print(mode); pw.println();
10820                }
10821            }
10822        }
10823        if (dumpPackage == null) {
10824            if (mSleeping || mWentToSleep || mLockScreenShown) {
10825                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10826                        + " mLockScreenShown " + mLockScreenShown);
10827            }
10828            if (mShuttingDown) {
10829                pw.println("  mShuttingDown=" + mShuttingDown);
10830            }
10831        }
10832        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10833                || mOrigWaitForDebugger) {
10834            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10835                    || dumpPackage.equals(mOrigDebugApp)) {
10836                if (needSep) {
10837                    pw.println();
10838                    needSep = false;
10839                }
10840                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10841                        + " mDebugTransient=" + mDebugTransient
10842                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10843            }
10844        }
10845        if (mOpenGlTraceApp != null) {
10846            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10847                if (needSep) {
10848                    pw.println();
10849                    needSep = false;
10850                }
10851                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10852            }
10853        }
10854        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10855                || mProfileFd != null) {
10856            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10857                if (needSep) {
10858                    pw.println();
10859                    needSep = false;
10860                }
10861                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10862                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10863                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10864                        + mAutoStopProfiler);
10865            }
10866        }
10867        if (dumpPackage == null) {
10868            if (mAlwaysFinishActivities || mController != null) {
10869                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10870                        + " mController=" + mController);
10871            }
10872            if (dumpAll) {
10873                pw.println("  Total persistent processes: " + numPers);
10874                pw.println("  mStartRunning=" + mStartRunning
10875                        + " mProcessesReady=" + mProcessesReady
10876                        + " mSystemReady=" + mSystemReady);
10877                pw.println("  mBooting=" + mBooting
10878                        + " mBooted=" + mBooted
10879                        + " mFactoryTest=" + mFactoryTest);
10880                pw.print("  mLastPowerCheckRealtime=");
10881                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10882                        pw.println("");
10883                pw.print("  mLastPowerCheckUptime=");
10884                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10885                        pw.println("");
10886                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10887                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10888                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10889                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10890                        + " (" + mLruProcesses.size() + " total)"
10891                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10892                        + " mNumServiceProcs=" + mNumServiceProcs
10893                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10894                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10895                        + " mLastMemoryLevel" + mLastMemoryLevel
10896                        + " mLastNumProcesses" + mLastNumProcesses);
10897                long now = SystemClock.uptimeMillis();
10898                pw.print("  mLastIdleTime=");
10899                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10900                        pw.print(" mLowRamSinceLastIdle=");
10901                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10902                        pw.println();
10903            }
10904        }
10905
10906        if (!printedAnything) {
10907            pw.println("  (nothing)");
10908        }
10909    }
10910
10911    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10912            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10913        if (mProcessesToGc.size() > 0) {
10914            boolean printed = false;
10915            long now = SystemClock.uptimeMillis();
10916            for (int i=0; i<mProcessesToGc.size(); i++) {
10917                ProcessRecord proc = mProcessesToGc.get(i);
10918                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10919                    continue;
10920                }
10921                if (!printed) {
10922                    if (needSep) pw.println();
10923                    needSep = true;
10924                    pw.println("  Processes that are waiting to GC:");
10925                    printed = true;
10926                }
10927                pw.print("    Process "); pw.println(proc);
10928                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10929                        pw.print(", last gced=");
10930                        pw.print(now-proc.lastRequestedGc);
10931                        pw.print(" ms ago, last lowMem=");
10932                        pw.print(now-proc.lastLowMemory);
10933                        pw.println(" ms ago");
10934
10935            }
10936        }
10937        return needSep;
10938    }
10939
10940    void printOomLevel(PrintWriter pw, String name, int adj) {
10941        pw.print("    ");
10942        if (adj >= 0) {
10943            pw.print(' ');
10944            if (adj < 10) pw.print(' ');
10945        } else {
10946            if (adj > -10) pw.print(' ');
10947        }
10948        pw.print(adj);
10949        pw.print(": ");
10950        pw.print(name);
10951        pw.print(" (");
10952        pw.print(mProcessList.getMemLevel(adj)/1024);
10953        pw.println(" kB)");
10954    }
10955
10956    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10957            int opti, boolean dumpAll) {
10958        boolean needSep = false;
10959
10960        if (mLruProcesses.size() > 0) {
10961            if (needSep) pw.println();
10962            needSep = true;
10963            pw.println("  OOM levels:");
10964            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10965            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10966            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10967            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10968            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10969            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10970            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10971            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10972            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
10973            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
10974            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
10975            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
10976            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
10977
10978            if (needSep) pw.println();
10979            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
10980                    pw.print(" total, non-act at ");
10981                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10982                    pw.print(", non-svc at ");
10983                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10984                    pw.println("):");
10985            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
10986            needSep = true;
10987        }
10988
10989        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
10990
10991        pw.println();
10992        pw.println("  mHomeProcess: " + mHomeProcess);
10993        pw.println("  mPreviousProcess: " + mPreviousProcess);
10994        if (mHeavyWeightProcess != null) {
10995            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10996        }
10997
10998        return true;
10999    }
11000
11001    /**
11002     * There are three ways to call this:
11003     *  - no provider specified: dump all the providers
11004     *  - a flattened component name that matched an existing provider was specified as the
11005     *    first arg: dump that one provider
11006     *  - the first arg isn't the flattened component name of an existing provider:
11007     *    dump all providers whose component contains the first arg as a substring
11008     */
11009    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11010            int opti, boolean dumpAll) {
11011        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11012    }
11013
11014    static class ItemMatcher {
11015        ArrayList<ComponentName> components;
11016        ArrayList<String> strings;
11017        ArrayList<Integer> objects;
11018        boolean all;
11019
11020        ItemMatcher() {
11021            all = true;
11022        }
11023
11024        void build(String name) {
11025            ComponentName componentName = ComponentName.unflattenFromString(name);
11026            if (componentName != null) {
11027                if (components == null) {
11028                    components = new ArrayList<ComponentName>();
11029                }
11030                components.add(componentName);
11031                all = false;
11032            } else {
11033                int objectId = 0;
11034                // Not a '/' separated full component name; maybe an object ID?
11035                try {
11036                    objectId = Integer.parseInt(name, 16);
11037                    if (objects == null) {
11038                        objects = new ArrayList<Integer>();
11039                    }
11040                    objects.add(objectId);
11041                    all = false;
11042                } catch (RuntimeException e) {
11043                    // Not an integer; just do string match.
11044                    if (strings == null) {
11045                        strings = new ArrayList<String>();
11046                    }
11047                    strings.add(name);
11048                    all = false;
11049                }
11050            }
11051        }
11052
11053        int build(String[] args, int opti) {
11054            for (; opti<args.length; opti++) {
11055                String name = args[opti];
11056                if ("--".equals(name)) {
11057                    return opti+1;
11058                }
11059                build(name);
11060            }
11061            return opti;
11062        }
11063
11064        boolean match(Object object, ComponentName comp) {
11065            if (all) {
11066                return true;
11067            }
11068            if (components != null) {
11069                for (int i=0; i<components.size(); i++) {
11070                    if (components.get(i).equals(comp)) {
11071                        return true;
11072                    }
11073                }
11074            }
11075            if (objects != null) {
11076                for (int i=0; i<objects.size(); i++) {
11077                    if (System.identityHashCode(object) == objects.get(i)) {
11078                        return true;
11079                    }
11080                }
11081            }
11082            if (strings != null) {
11083                String flat = comp.flattenToString();
11084                for (int i=0; i<strings.size(); i++) {
11085                    if (flat.contains(strings.get(i))) {
11086                        return true;
11087                    }
11088                }
11089            }
11090            return false;
11091        }
11092    }
11093
11094    /**
11095     * There are three things that cmd can be:
11096     *  - a flattened component name that matches an existing activity
11097     *  - the cmd arg isn't the flattened component name of an existing activity:
11098     *    dump all activity whose component contains the cmd as a substring
11099     *  - A hex number of the ActivityRecord object instance.
11100     */
11101    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11102            int opti, boolean dumpAll) {
11103        ArrayList<ActivityRecord> activities;
11104
11105        synchronized (this) {
11106            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11107        }
11108
11109        if (activities.size() <= 0) {
11110            return false;
11111        }
11112
11113        String[] newArgs = new String[args.length - opti];
11114        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11115
11116        TaskRecord lastTask = null;
11117        boolean needSep = false;
11118        for (int i=activities.size()-1; i>=0; i--) {
11119            ActivityRecord r = activities.get(i);
11120            if (needSep) {
11121                pw.println();
11122            }
11123            needSep = true;
11124            synchronized (this) {
11125                if (lastTask != r.task) {
11126                    lastTask = r.task;
11127                    pw.print("TASK "); pw.print(lastTask.affinity);
11128                            pw.print(" id="); pw.println(lastTask.taskId);
11129                    if (dumpAll) {
11130                        lastTask.dump(pw, "  ");
11131                    }
11132                }
11133            }
11134            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11135        }
11136        return true;
11137    }
11138
11139    /**
11140     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11141     * there is a thread associated with the activity.
11142     */
11143    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11144            final ActivityRecord r, String[] args, boolean dumpAll) {
11145        String innerPrefix = prefix + "  ";
11146        synchronized (this) {
11147            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11148                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11149                    pw.print(" pid=");
11150                    if (r.app != null) pw.println(r.app.pid);
11151                    else pw.println("(not running)");
11152            if (dumpAll) {
11153                r.dump(pw, innerPrefix);
11154            }
11155        }
11156        if (r.app != null && r.app.thread != null) {
11157            // flush anything that is already in the PrintWriter since the thread is going
11158            // to write to the file descriptor directly
11159            pw.flush();
11160            try {
11161                TransferPipe tp = new TransferPipe();
11162                try {
11163                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11164                            r.appToken, innerPrefix, args);
11165                    tp.go(fd);
11166                } finally {
11167                    tp.kill();
11168                }
11169            } catch (IOException e) {
11170                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11171            } catch (RemoteException e) {
11172                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11173            }
11174        }
11175    }
11176
11177    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11178            int opti, boolean dumpAll, String dumpPackage) {
11179        boolean needSep = false;
11180        boolean onlyHistory = false;
11181        boolean printedAnything = false;
11182
11183        if ("history".equals(dumpPackage)) {
11184            if (opti < args.length && "-s".equals(args[opti])) {
11185                dumpAll = false;
11186            }
11187            onlyHistory = true;
11188            dumpPackage = null;
11189        }
11190
11191        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11192        if (!onlyHistory && dumpAll) {
11193            if (mRegisteredReceivers.size() > 0) {
11194                boolean printed = false;
11195                Iterator it = mRegisteredReceivers.values().iterator();
11196                while (it.hasNext()) {
11197                    ReceiverList r = (ReceiverList)it.next();
11198                    if (dumpPackage != null && (r.app == null ||
11199                            !dumpPackage.equals(r.app.info.packageName))) {
11200                        continue;
11201                    }
11202                    if (!printed) {
11203                        pw.println("  Registered Receivers:");
11204                        needSep = true;
11205                        printed = true;
11206                        printedAnything = true;
11207                    }
11208                    pw.print("  * "); pw.println(r);
11209                    r.dump(pw, "    ");
11210                }
11211            }
11212
11213            if (mReceiverResolver.dump(pw, needSep ?
11214                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11215                    "    ", dumpPackage, false)) {
11216                needSep = true;
11217                printedAnything = true;
11218            }
11219        }
11220
11221        for (BroadcastQueue q : mBroadcastQueues) {
11222            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11223            printedAnything |= needSep;
11224        }
11225
11226        needSep = true;
11227
11228        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11229            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11230                if (needSep) {
11231                    pw.println();
11232                }
11233                needSep = true;
11234                printedAnything = true;
11235                pw.print("  Sticky broadcasts for user ");
11236                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11237                StringBuilder sb = new StringBuilder(128);
11238                for (Map.Entry<String, ArrayList<Intent>> ent
11239                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11240                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11241                    if (dumpAll) {
11242                        pw.println(":");
11243                        ArrayList<Intent> intents = ent.getValue();
11244                        final int N = intents.size();
11245                        for (int i=0; i<N; i++) {
11246                            sb.setLength(0);
11247                            sb.append("    Intent: ");
11248                            intents.get(i).toShortString(sb, false, true, false, false);
11249                            pw.println(sb.toString());
11250                            Bundle bundle = intents.get(i).getExtras();
11251                            if (bundle != null) {
11252                                pw.print("      ");
11253                                pw.println(bundle.toString());
11254                            }
11255                        }
11256                    } else {
11257                        pw.println("");
11258                    }
11259                }
11260            }
11261        }
11262
11263        if (!onlyHistory && dumpAll) {
11264            pw.println();
11265            for (BroadcastQueue queue : mBroadcastQueues) {
11266                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11267                        + queue.mBroadcastsScheduled);
11268            }
11269            pw.println("  mHandler:");
11270            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11271            needSep = true;
11272            printedAnything = true;
11273        }
11274
11275        if (!printedAnything) {
11276            pw.println("  (nothing)");
11277        }
11278    }
11279
11280    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11281            int opti, boolean dumpAll, String dumpPackage) {
11282        boolean needSep;
11283        boolean printedAnything = false;
11284
11285        ItemMatcher matcher = new ItemMatcher();
11286        matcher.build(args, opti);
11287
11288        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11289
11290        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11291        printedAnything |= needSep;
11292
11293        if (mLaunchingProviders.size() > 0) {
11294            boolean printed = false;
11295            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11296                ContentProviderRecord r = mLaunchingProviders.get(i);
11297                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11298                    continue;
11299                }
11300                if (!printed) {
11301                    if (needSep) pw.println();
11302                    needSep = true;
11303                    pw.println("  Launching content providers:");
11304                    printed = true;
11305                    printedAnything = true;
11306                }
11307                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11308                        pw.println(r);
11309            }
11310        }
11311
11312        if (mGrantedUriPermissions.size() > 0) {
11313            boolean printed = false;
11314            int dumpUid = -2;
11315            if (dumpPackage != null) {
11316                try {
11317                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11318                } catch (NameNotFoundException e) {
11319                    dumpUid = -1;
11320                }
11321            }
11322            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11323                int uid = mGrantedUriPermissions.keyAt(i);
11324                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11325                    continue;
11326                }
11327                ArrayMap<Uri, UriPermission> perms
11328                        = mGrantedUriPermissions.valueAt(i);
11329                if (!printed) {
11330                    if (needSep) pw.println();
11331                    needSep = true;
11332                    pw.println("  Granted Uri Permissions:");
11333                    printed = true;
11334                    printedAnything = true;
11335                }
11336                pw.print("  * UID "); pw.print(uid);
11337                        pw.println(" holds:");
11338                for (UriPermission perm : perms.values()) {
11339                    pw.print("    "); pw.println(perm);
11340                    if (dumpAll) {
11341                        perm.dump(pw, "      ");
11342                    }
11343                }
11344            }
11345        }
11346
11347        if (!printedAnything) {
11348            pw.println("  (nothing)");
11349        }
11350    }
11351
11352    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11353            int opti, boolean dumpAll, String dumpPackage) {
11354        boolean printed = false;
11355
11356        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11357
11358        if (mIntentSenderRecords.size() > 0) {
11359            Iterator<WeakReference<PendingIntentRecord>> it
11360                    = mIntentSenderRecords.values().iterator();
11361            while (it.hasNext()) {
11362                WeakReference<PendingIntentRecord> ref = it.next();
11363                PendingIntentRecord rec = ref != null ? ref.get(): null;
11364                if (dumpPackage != null && (rec == null
11365                        || !dumpPackage.equals(rec.key.packageName))) {
11366                    continue;
11367                }
11368                printed = true;
11369                if (rec != null) {
11370                    pw.print("  * "); pw.println(rec);
11371                    if (dumpAll) {
11372                        rec.dump(pw, "    ");
11373                    }
11374                } else {
11375                    pw.print("  * "); pw.println(ref);
11376                }
11377            }
11378        }
11379
11380        if (!printed) {
11381            pw.println("  (nothing)");
11382        }
11383    }
11384
11385    private static final int dumpProcessList(PrintWriter pw,
11386            ActivityManagerService service, List list,
11387            String prefix, String normalLabel, String persistentLabel,
11388            String dumpPackage) {
11389        int numPers = 0;
11390        final int N = list.size()-1;
11391        for (int i=N; i>=0; i--) {
11392            ProcessRecord r = (ProcessRecord)list.get(i);
11393            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11394                continue;
11395            }
11396            pw.println(String.format("%s%s #%2d: %s",
11397                    prefix, (r.persistent ? persistentLabel : normalLabel),
11398                    i, r.toString()));
11399            if (r.persistent) {
11400                numPers++;
11401            }
11402        }
11403        return numPers;
11404    }
11405
11406    private static final boolean dumpProcessOomList(PrintWriter pw,
11407            ActivityManagerService service, List<ProcessRecord> origList,
11408            String prefix, String normalLabel, String persistentLabel,
11409            boolean inclDetails, String dumpPackage) {
11410
11411        ArrayList<Pair<ProcessRecord, Integer>> list
11412                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11413        for (int i=0; i<origList.size(); i++) {
11414            ProcessRecord r = origList.get(i);
11415            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11416                continue;
11417            }
11418            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11419        }
11420
11421        if (list.size() <= 0) {
11422            return false;
11423        }
11424
11425        Comparator<Pair<ProcessRecord, Integer>> comparator
11426                = new Comparator<Pair<ProcessRecord, Integer>>() {
11427            @Override
11428            public int compare(Pair<ProcessRecord, Integer> object1,
11429                    Pair<ProcessRecord, Integer> object2) {
11430                if (object1.first.setAdj != object2.first.setAdj) {
11431                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11432                }
11433                if (object1.second.intValue() != object2.second.intValue()) {
11434                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11435                }
11436                return 0;
11437            }
11438        };
11439
11440        Collections.sort(list, comparator);
11441
11442        final long curRealtime = SystemClock.elapsedRealtime();
11443        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11444        final long curUptime = SystemClock.uptimeMillis();
11445        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11446
11447        for (int i=list.size()-1; i>=0; i--) {
11448            ProcessRecord r = list.get(i).first;
11449            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11450            char schedGroup;
11451            switch (r.setSchedGroup) {
11452                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11453                    schedGroup = 'B';
11454                    break;
11455                case Process.THREAD_GROUP_DEFAULT:
11456                    schedGroup = 'F';
11457                    break;
11458                default:
11459                    schedGroup = '?';
11460                    break;
11461            }
11462            char foreground;
11463            if (r.foregroundActivities) {
11464                foreground = 'A';
11465            } else if (r.foregroundServices) {
11466                foreground = 'S';
11467            } else {
11468                foreground = ' ';
11469            }
11470            String procState = ProcessList.makeProcStateString(r.curProcState);
11471            pw.print(prefix);
11472            pw.print(r.persistent ? persistentLabel : normalLabel);
11473            pw.print(" #");
11474            int num = (origList.size()-1)-list.get(i).second;
11475            if (num < 10) pw.print(' ');
11476            pw.print(num);
11477            pw.print(": ");
11478            pw.print(oomAdj);
11479            pw.print(' ');
11480            pw.print(schedGroup);
11481            pw.print('/');
11482            pw.print(foreground);
11483            pw.print('/');
11484            pw.print(procState);
11485            pw.print(" trm:");
11486            if (r.trimMemoryLevel < 10) pw.print(' ');
11487            pw.print(r.trimMemoryLevel);
11488            pw.print(' ');
11489            pw.print(r.toShortString());
11490            pw.print(" (");
11491            pw.print(r.adjType);
11492            pw.println(')');
11493            if (r.adjSource != null || r.adjTarget != null) {
11494                pw.print(prefix);
11495                pw.print("    ");
11496                if (r.adjTarget instanceof ComponentName) {
11497                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11498                } else if (r.adjTarget != null) {
11499                    pw.print(r.adjTarget.toString());
11500                } else {
11501                    pw.print("{null}");
11502                }
11503                pw.print("<=");
11504                if (r.adjSource instanceof ProcessRecord) {
11505                    pw.print("Proc{");
11506                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11507                    pw.println("}");
11508                } else if (r.adjSource != null) {
11509                    pw.println(r.adjSource.toString());
11510                } else {
11511                    pw.println("{null}");
11512                }
11513            }
11514            if (inclDetails) {
11515                pw.print(prefix);
11516                pw.print("    ");
11517                pw.print("oom: max="); pw.print(r.maxAdj);
11518                pw.print(" curRaw="); pw.print(r.curRawAdj);
11519                pw.print(" setRaw="); pw.print(r.setRawAdj);
11520                pw.print(" cur="); pw.print(r.curAdj);
11521                pw.print(" set="); pw.println(r.setAdj);
11522                pw.print(prefix);
11523                pw.print("    ");
11524                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11525                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11526                pw.print(" lastPss="); pw.print(r.lastPss);
11527                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11528                pw.print(prefix);
11529                pw.print("    ");
11530                pw.print("keeping="); pw.print(r.keeping);
11531                pw.print(" cached="); pw.print(r.cached);
11532                pw.print(" empty="); pw.print(r.empty);
11533                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11534
11535                if (!r.keeping) {
11536                    if (r.lastWakeTime != 0) {
11537                        long wtime;
11538                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11539                        synchronized (stats) {
11540                            wtime = stats.getProcessWakeTime(r.info.uid,
11541                                    r.pid, curRealtime);
11542                        }
11543                        long timeUsed = wtime - r.lastWakeTime;
11544                        pw.print(prefix);
11545                        pw.print("    ");
11546                        pw.print("keep awake over ");
11547                        TimeUtils.formatDuration(realtimeSince, pw);
11548                        pw.print(" used ");
11549                        TimeUtils.formatDuration(timeUsed, pw);
11550                        pw.print(" (");
11551                        pw.print((timeUsed*100)/realtimeSince);
11552                        pw.println("%)");
11553                    }
11554                    if (r.lastCpuTime != 0) {
11555                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11556                        pw.print(prefix);
11557                        pw.print("    ");
11558                        pw.print("run cpu over ");
11559                        TimeUtils.formatDuration(uptimeSince, pw);
11560                        pw.print(" used ");
11561                        TimeUtils.formatDuration(timeUsed, pw);
11562                        pw.print(" (");
11563                        pw.print((timeUsed*100)/uptimeSince);
11564                        pw.println("%)");
11565                    }
11566                }
11567            }
11568        }
11569        return true;
11570    }
11571
11572    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11573        ArrayList<ProcessRecord> procs;
11574        synchronized (this) {
11575            if (args != null && args.length > start
11576                    && args[start].charAt(0) != '-') {
11577                procs = new ArrayList<ProcessRecord>();
11578                int pid = -1;
11579                try {
11580                    pid = Integer.parseInt(args[start]);
11581                } catch (NumberFormatException e) {
11582                }
11583                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11584                    ProcessRecord proc = mLruProcesses.get(i);
11585                    if (proc.pid == pid) {
11586                        procs.add(proc);
11587                    } else if (proc.processName.equals(args[start])) {
11588                        procs.add(proc);
11589                    }
11590                }
11591                if (procs.size() <= 0) {
11592                    return null;
11593                }
11594            } else {
11595                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11596            }
11597        }
11598        return procs;
11599    }
11600
11601    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11602            PrintWriter pw, String[] args) {
11603        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11604        if (procs == null) {
11605            pw.println("No process found for: " + args[0]);
11606            return;
11607        }
11608
11609        long uptime = SystemClock.uptimeMillis();
11610        long realtime = SystemClock.elapsedRealtime();
11611        pw.println("Applications Graphics Acceleration Info:");
11612        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11613
11614        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11615            ProcessRecord r = procs.get(i);
11616            if (r.thread != null) {
11617                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11618                pw.flush();
11619                try {
11620                    TransferPipe tp = new TransferPipe();
11621                    try {
11622                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11623                        tp.go(fd);
11624                    } finally {
11625                        tp.kill();
11626                    }
11627                } catch (IOException e) {
11628                    pw.println("Failure while dumping the app: " + r);
11629                    pw.flush();
11630                } catch (RemoteException e) {
11631                    pw.println("Got a RemoteException while dumping the app " + r);
11632                    pw.flush();
11633                }
11634            }
11635        }
11636    }
11637
11638    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11639        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11640        if (procs == null) {
11641            pw.println("No process found for: " + args[0]);
11642            return;
11643        }
11644
11645        pw.println("Applications Database Info:");
11646
11647        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11648            ProcessRecord r = procs.get(i);
11649            if (r.thread != null) {
11650                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11651                pw.flush();
11652                try {
11653                    TransferPipe tp = new TransferPipe();
11654                    try {
11655                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11656                        tp.go(fd);
11657                    } finally {
11658                        tp.kill();
11659                    }
11660                } catch (IOException e) {
11661                    pw.println("Failure while dumping the app: " + r);
11662                    pw.flush();
11663                } catch (RemoteException e) {
11664                    pw.println("Got a RemoteException while dumping the app " + r);
11665                    pw.flush();
11666                }
11667            }
11668        }
11669    }
11670
11671    final static class MemItem {
11672        final boolean isProc;
11673        final String label;
11674        final String shortLabel;
11675        final long pss;
11676        final int id;
11677        final boolean hasActivities;
11678        ArrayList<MemItem> subitems;
11679
11680        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11681                boolean _hasActivities) {
11682            isProc = true;
11683            label = _label;
11684            shortLabel = _shortLabel;
11685            pss = _pss;
11686            id = _id;
11687            hasActivities = _hasActivities;
11688        }
11689
11690        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11691            isProc = false;
11692            label = _label;
11693            shortLabel = _shortLabel;
11694            pss = _pss;
11695            id = _id;
11696            hasActivities = false;
11697        }
11698    }
11699
11700    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11701            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11702        if (sort && !isCompact) {
11703            Collections.sort(items, new Comparator<MemItem>() {
11704                @Override
11705                public int compare(MemItem lhs, MemItem rhs) {
11706                    if (lhs.pss < rhs.pss) {
11707                        return 1;
11708                    } else if (lhs.pss > rhs.pss) {
11709                        return -1;
11710                    }
11711                    return 0;
11712                }
11713            });
11714        }
11715
11716        for (int i=0; i<items.size(); i++) {
11717            MemItem mi = items.get(i);
11718            if (!isCompact) {
11719                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11720            } else if (mi.isProc) {
11721                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11722                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11723                pw.println(mi.hasActivities ? ",a" : ",e");
11724            } else {
11725                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11726                pw.println(mi.pss);
11727            }
11728            if (mi.subitems != null) {
11729                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11730                        true, isCompact);
11731            }
11732        }
11733    }
11734
11735    // These are in KB.
11736    static final long[] DUMP_MEM_BUCKETS = new long[] {
11737        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11738        120*1024, 160*1024, 200*1024,
11739        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11740        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11741    };
11742
11743    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11744            boolean stackLike) {
11745        int start = label.lastIndexOf('.');
11746        if (start >= 0) start++;
11747        else start = 0;
11748        int end = label.length();
11749        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11750            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11751                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11752                out.append(bucket);
11753                out.append(stackLike ? "MB." : "MB ");
11754                out.append(label, start, end);
11755                return;
11756            }
11757        }
11758        out.append(memKB/1024);
11759        out.append(stackLike ? "MB." : "MB ");
11760        out.append(label, start, end);
11761    }
11762
11763    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11764            ProcessList.NATIVE_ADJ,
11765            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11766            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11767            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11768            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11769            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11770    };
11771    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11772            "Native",
11773            "System", "Persistent", "Foreground",
11774            "Visible", "Perceptible",
11775            "Heavy Weight", "Backup",
11776            "A Services", "Home",
11777            "Previous", "B Services", "Cached"
11778    };
11779    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11780            "native",
11781            "sys", "pers", "fore",
11782            "vis", "percept",
11783            "heavy", "backup",
11784            "servicea", "home",
11785            "prev", "serviceb", "cached"
11786    };
11787
11788    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11789            long realtime, boolean isCheckinRequest, boolean isCompact) {
11790        if (isCheckinRequest || isCompact) {
11791            // short checkin version
11792            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11793        } else {
11794            pw.println("Applications Memory Usage (kB):");
11795            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11796        }
11797    }
11798
11799    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11800            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11801        boolean dumpDetails = false;
11802        boolean dumpFullDetails = false;
11803        boolean dumpDalvik = false;
11804        boolean oomOnly = false;
11805        boolean isCompact = false;
11806        boolean localOnly = false;
11807
11808        int opti = 0;
11809        while (opti < args.length) {
11810            String opt = args[opti];
11811            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11812                break;
11813            }
11814            opti++;
11815            if ("-a".equals(opt)) {
11816                dumpDetails = true;
11817                dumpFullDetails = true;
11818                dumpDalvik = true;
11819            } else if ("-d".equals(opt)) {
11820                dumpDalvik = true;
11821            } else if ("-c".equals(opt)) {
11822                isCompact = true;
11823            } else if ("--oom".equals(opt)) {
11824                oomOnly = true;
11825            } else if ("--local".equals(opt)) {
11826                localOnly = true;
11827            } else if ("-h".equals(opt)) {
11828                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11829                pw.println("  -a: include all available information for each process.");
11830                pw.println("  -d: include dalvik details when dumping process details.");
11831                pw.println("  -c: dump in a compact machine-parseable representation.");
11832                pw.println("  --oom: only show processes organized by oom adj.");
11833                pw.println("  --local: only collect details locally, don't call process.");
11834                pw.println("If [process] is specified it can be the name or ");
11835                pw.println("pid of a specific process to dump.");
11836                return;
11837            } else {
11838                pw.println("Unknown argument: " + opt + "; use -h for help");
11839            }
11840        }
11841
11842        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11843        long uptime = SystemClock.uptimeMillis();
11844        long realtime = SystemClock.elapsedRealtime();
11845        final long[] tmpLong = new long[1];
11846
11847        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11848        if (procs == null) {
11849            // No Java processes.  Maybe they want to print a native process.
11850            if (args != null && args.length > opti
11851                    && args[opti].charAt(0) != '-') {
11852                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11853                        = new ArrayList<ProcessCpuTracker.Stats>();
11854                updateCpuStatsNow();
11855                int findPid = -1;
11856                try {
11857                    findPid = Integer.parseInt(args[opti]);
11858                } catch (NumberFormatException e) {
11859                }
11860                synchronized (mProcessCpuThread) {
11861                    final int N = mProcessCpuTracker.countStats();
11862                    for (int i=0; i<N; i++) {
11863                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11864                        if (st.pid == findPid || (st.baseName != null
11865                                && st.baseName.equals(args[opti]))) {
11866                            nativeProcs.add(st);
11867                        }
11868                    }
11869                }
11870                if (nativeProcs.size() > 0) {
11871                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11872                            isCompact);
11873                    Debug.MemoryInfo mi = null;
11874                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11875                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11876                        final int pid = r.pid;
11877                        if (!isCheckinRequest && dumpDetails) {
11878                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11879                        }
11880                        if (mi == null) {
11881                            mi = new Debug.MemoryInfo();
11882                        }
11883                        if (dumpDetails || (!brief && !oomOnly)) {
11884                            Debug.getMemoryInfo(pid, mi);
11885                        } else {
11886                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11887                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11888                        }
11889                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11890                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11891                        if (isCheckinRequest) {
11892                            pw.println();
11893                        }
11894                    }
11895                    return;
11896                }
11897            }
11898            pw.println("No process found for: " + args[opti]);
11899            return;
11900        }
11901
11902        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11903            dumpDetails = true;
11904        }
11905
11906        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11907
11908        String[] innerArgs = new String[args.length-opti];
11909        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11910
11911        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11912        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11913        long nativePss=0, dalvikPss=0, otherPss=0;
11914        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11915
11916        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11917        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11918                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11919
11920        long totalPss = 0;
11921        long cachedPss = 0;
11922
11923        Debug.MemoryInfo mi = null;
11924        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11925            final ProcessRecord r = procs.get(i);
11926            final IApplicationThread thread;
11927            final int pid;
11928            final int oomAdj;
11929            final boolean hasActivities;
11930            synchronized (this) {
11931                thread = r.thread;
11932                pid = r.pid;
11933                oomAdj = r.getSetAdjWithServices();
11934                hasActivities = r.activities.size() > 0;
11935            }
11936            if (thread != null) {
11937                if (!isCheckinRequest && dumpDetails) {
11938                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11939                }
11940                if (mi == null) {
11941                    mi = new Debug.MemoryInfo();
11942                }
11943                if (dumpDetails || (!brief && !oomOnly)) {
11944                    Debug.getMemoryInfo(pid, mi);
11945                } else {
11946                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11947                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11948                }
11949                if (dumpDetails) {
11950                    if (localOnly) {
11951                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11952                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11953                        if (isCheckinRequest) {
11954                            pw.println();
11955                        }
11956                    } else {
11957                        try {
11958                            pw.flush();
11959                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11960                                    dumpDalvik, innerArgs);
11961                        } catch (RemoteException e) {
11962                            if (!isCheckinRequest) {
11963                                pw.println("Got RemoteException!");
11964                                pw.flush();
11965                            }
11966                        }
11967                    }
11968                }
11969
11970                final long myTotalPss = mi.getTotalPss();
11971                final long myTotalUss = mi.getTotalUss();
11972
11973                synchronized (this) {
11974                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
11975                        // Record this for posterity if the process has been stable.
11976                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
11977                    }
11978                }
11979
11980                if (!isCheckinRequest && mi != null) {
11981                    totalPss += myTotalPss;
11982                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
11983                            (hasActivities ? " / activities)" : ")"),
11984                            r.processName, myTotalPss, pid, hasActivities);
11985                    procMems.add(pssItem);
11986                    procMemsMap.put(pid, pssItem);
11987
11988                    nativePss += mi.nativePss;
11989                    dalvikPss += mi.dalvikPss;
11990                    otherPss += mi.otherPss;
11991                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
11992                        long mem = mi.getOtherPss(j);
11993                        miscPss[j] += mem;
11994                        otherPss -= mem;
11995                    }
11996
11997                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
11998                        cachedPss += myTotalPss;
11999                    }
12000
12001                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12002                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12003                                || oomIndex == (oomPss.length-1)) {
12004                            oomPss[oomIndex] += myTotalPss;
12005                            if (oomProcs[oomIndex] == null) {
12006                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12007                            }
12008                            oomProcs[oomIndex].add(pssItem);
12009                            break;
12010                        }
12011                    }
12012                }
12013            }
12014        }
12015
12016        if (!isCheckinRequest && procs.size() > 1) {
12017            // If we are showing aggregations, also look for native processes to
12018            // include so that our aggregations are more accurate.
12019            updateCpuStatsNow();
12020            synchronized (mProcessCpuThread) {
12021                final int N = mProcessCpuTracker.countStats();
12022                for (int i=0; i<N; i++) {
12023                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12024                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12025                        if (mi == null) {
12026                            mi = new Debug.MemoryInfo();
12027                        }
12028                        if (!brief && !oomOnly) {
12029                            Debug.getMemoryInfo(st.pid, mi);
12030                        } else {
12031                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12032                            mi.nativePrivateDirty = (int)tmpLong[0];
12033                        }
12034
12035                        final long myTotalPss = mi.getTotalPss();
12036                        totalPss += myTotalPss;
12037
12038                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12039                                st.name, myTotalPss, st.pid, false);
12040                        procMems.add(pssItem);
12041
12042                        nativePss += mi.nativePss;
12043                        dalvikPss += mi.dalvikPss;
12044                        otherPss += mi.otherPss;
12045                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12046                            long mem = mi.getOtherPss(j);
12047                            miscPss[j] += mem;
12048                            otherPss -= mem;
12049                        }
12050                        oomPss[0] += myTotalPss;
12051                        if (oomProcs[0] == null) {
12052                            oomProcs[0] = new ArrayList<MemItem>();
12053                        }
12054                        oomProcs[0].add(pssItem);
12055                    }
12056                }
12057            }
12058
12059            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12060
12061            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12062            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12063            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12064            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12065                String label = Debug.MemoryInfo.getOtherLabel(j);
12066                catMems.add(new MemItem(label, label, miscPss[j], j));
12067            }
12068
12069            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12070            for (int j=0; j<oomPss.length; j++) {
12071                if (oomPss[j] != 0) {
12072                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12073                            : DUMP_MEM_OOM_LABEL[j];
12074                    MemItem item = new MemItem(label, label, oomPss[j],
12075                            DUMP_MEM_OOM_ADJ[j]);
12076                    item.subitems = oomProcs[j];
12077                    oomMems.add(item);
12078                }
12079            }
12080
12081            if (!brief && !oomOnly && !isCompact) {
12082                pw.println();
12083                pw.println("Total PSS by process:");
12084                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12085                pw.println();
12086            }
12087            if (!isCompact) {
12088                pw.println("Total PSS by OOM adjustment:");
12089            }
12090            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12091            if (!brief && !oomOnly) {
12092                PrintWriter out = categoryPw != null ? categoryPw : pw;
12093                if (!isCompact) {
12094                    out.println();
12095                    out.println("Total PSS by category:");
12096                }
12097                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12098            }
12099            if (!isCompact) {
12100                pw.println();
12101            }
12102            MemInfoReader memInfo = new MemInfoReader();
12103            memInfo.readMemInfo();
12104            if (!brief) {
12105                if (!isCompact) {
12106                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12107                    pw.println(" kB");
12108                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12109                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12110                            pw.print(cachedPss); pw.print(" cached pss + ");
12111                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12112                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12113                } else {
12114                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12115                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12116                            + memInfo.getFreeSizeKb()); pw.print(",");
12117                    pw.println(totalPss - cachedPss);
12118                }
12119            }
12120            if (!isCompact) {
12121                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12122                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12123                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12124                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12125                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12126                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12127                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12128                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12129                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12130                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12131                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12132            }
12133            if (!brief) {
12134                if (memInfo.getZramTotalSizeKb() != 0) {
12135                    if (!isCompact) {
12136                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12137                                pw.print(" kB physical used for ");
12138                                pw.print(memInfo.getSwapTotalSizeKb()
12139                                        - memInfo.getSwapFreeSizeKb());
12140                                pw.print(" kB in swap (");
12141                                pw.print(memInfo.getSwapTotalSizeKb());
12142                                pw.println(" kB total swap)");
12143                    } else {
12144                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12145                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12146                                pw.println(memInfo.getSwapFreeSizeKb());
12147                    }
12148                }
12149                final int[] SINGLE_LONG_FORMAT = new int[] {
12150                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12151                };
12152                long[] longOut = new long[1];
12153                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12154                        SINGLE_LONG_FORMAT, null, longOut, null);
12155                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12156                longOut[0] = 0;
12157                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12158                        SINGLE_LONG_FORMAT, null, longOut, null);
12159                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12160                longOut[0] = 0;
12161                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12162                        SINGLE_LONG_FORMAT, null, longOut, null);
12163                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12164                longOut[0] = 0;
12165                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12166                        SINGLE_LONG_FORMAT, null, longOut, null);
12167                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12168                if (!isCompact) {
12169                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12170                        pw.print("      KSM: "); pw.print(sharing);
12171                                pw.print(" kB saved from shared ");
12172                                pw.print(shared); pw.println(" kB");
12173                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12174                                pw.print(voltile); pw.println(" kB volatile");
12175                    }
12176                    pw.print("   Tuning: ");
12177                    pw.print(ActivityManager.staticGetMemoryClass());
12178                    pw.print(" (large ");
12179                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12180                    pw.print("), oom ");
12181                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12182                    pw.print(" kB");
12183                    pw.print(", restore limit ");
12184                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12185                    pw.print(" kB");
12186                    if (ActivityManager.isLowRamDeviceStatic()) {
12187                        pw.print(" (low-ram)");
12188                    }
12189                    if (ActivityManager.isHighEndGfx()) {
12190                        pw.print(" (high-end-gfx)");
12191                    }
12192                    pw.println();
12193                } else {
12194                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12195                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12196                    pw.println(voltile);
12197                    pw.print("tuning,");
12198                    pw.print(ActivityManager.staticGetMemoryClass());
12199                    pw.print(',');
12200                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12201                    pw.print(',');
12202                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12203                    if (ActivityManager.isLowRamDeviceStatic()) {
12204                        pw.print(",low-ram");
12205                    }
12206                    if (ActivityManager.isHighEndGfx()) {
12207                        pw.print(",high-end-gfx");
12208                    }
12209                    pw.println();
12210                }
12211            }
12212        }
12213    }
12214
12215    /**
12216     * Searches array of arguments for the specified string
12217     * @param args array of argument strings
12218     * @param value value to search for
12219     * @return true if the value is contained in the array
12220     */
12221    private static boolean scanArgs(String[] args, String value) {
12222        if (args != null) {
12223            for (String arg : args) {
12224                if (value.equals(arg)) {
12225                    return true;
12226                }
12227            }
12228        }
12229        return false;
12230    }
12231
12232    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12233            ContentProviderRecord cpr, boolean always) {
12234        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12235
12236        if (!inLaunching || always) {
12237            synchronized (cpr) {
12238                cpr.launchingApp = null;
12239                cpr.notifyAll();
12240            }
12241            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12242            String names[] = cpr.info.authority.split(";");
12243            for (int j = 0; j < names.length; j++) {
12244                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12245            }
12246        }
12247
12248        for (int i=0; i<cpr.connections.size(); i++) {
12249            ContentProviderConnection conn = cpr.connections.get(i);
12250            if (conn.waiting) {
12251                // If this connection is waiting for the provider, then we don't
12252                // need to mess with its process unless we are always removing
12253                // or for some reason the provider is not currently launching.
12254                if (inLaunching && !always) {
12255                    continue;
12256                }
12257            }
12258            ProcessRecord capp = conn.client;
12259            conn.dead = true;
12260            if (conn.stableCount > 0) {
12261                if (!capp.persistent && capp.thread != null
12262                        && capp.pid != 0
12263                        && capp.pid != MY_PID) {
12264                    killUnneededProcessLocked(capp, "depends on provider "
12265                            + cpr.name.flattenToShortString()
12266                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12267                }
12268            } else if (capp.thread != null && conn.provider.provider != null) {
12269                try {
12270                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12271                } catch (RemoteException e) {
12272                }
12273                // In the protocol here, we don't expect the client to correctly
12274                // clean up this connection, we'll just remove it.
12275                cpr.connections.remove(i);
12276                conn.client.conProviders.remove(conn);
12277            }
12278        }
12279
12280        if (inLaunching && always) {
12281            mLaunchingProviders.remove(cpr);
12282        }
12283        return inLaunching;
12284    }
12285
12286    /**
12287     * Main code for cleaning up a process when it has gone away.  This is
12288     * called both as a result of the process dying, or directly when stopping
12289     * a process when running in single process mode.
12290     */
12291    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12292            boolean restarting, boolean allowRestart, int index) {
12293        if (index >= 0) {
12294            removeLruProcessLocked(app);
12295            ProcessList.remove(app.pid);
12296        }
12297
12298        mProcessesToGc.remove(app);
12299        mPendingPssProcesses.remove(app);
12300
12301        // Dismiss any open dialogs.
12302        if (app.crashDialog != null && !app.forceCrashReport) {
12303            app.crashDialog.dismiss();
12304            app.crashDialog = null;
12305        }
12306        if (app.anrDialog != null) {
12307            app.anrDialog.dismiss();
12308            app.anrDialog = null;
12309        }
12310        if (app.waitDialog != null) {
12311            app.waitDialog.dismiss();
12312            app.waitDialog = null;
12313        }
12314
12315        app.crashing = false;
12316        app.notResponding = false;
12317
12318        app.resetPackageList(mProcessStats);
12319        app.unlinkDeathRecipient();
12320        app.makeInactive(mProcessStats);
12321        app.forcingToForeground = null;
12322        app.foregroundServices = false;
12323        app.foregroundActivities = false;
12324        app.hasShownUi = false;
12325        app.hasAboveClient = false;
12326
12327        mServices.killServicesLocked(app, allowRestart);
12328
12329        boolean restart = false;
12330
12331        // Remove published content providers.
12332        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12333            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12334            final boolean always = app.bad || !allowRestart;
12335            if (removeDyingProviderLocked(app, cpr, always) || always) {
12336                // We left the provider in the launching list, need to
12337                // restart it.
12338                restart = true;
12339            }
12340
12341            cpr.provider = null;
12342            cpr.proc = null;
12343        }
12344        app.pubProviders.clear();
12345
12346        // Take care of any launching providers waiting for this process.
12347        if (checkAppInLaunchingProvidersLocked(app, false)) {
12348            restart = true;
12349        }
12350
12351        // Unregister from connected content providers.
12352        if (!app.conProviders.isEmpty()) {
12353            for (int i=0; i<app.conProviders.size(); i++) {
12354                ContentProviderConnection conn = app.conProviders.get(i);
12355                conn.provider.connections.remove(conn);
12356            }
12357            app.conProviders.clear();
12358        }
12359
12360        // At this point there may be remaining entries in mLaunchingProviders
12361        // where we were the only one waiting, so they are no longer of use.
12362        // Look for these and clean up if found.
12363        // XXX Commented out for now.  Trying to figure out a way to reproduce
12364        // the actual situation to identify what is actually going on.
12365        if (false) {
12366            for (int i=0; i<mLaunchingProviders.size(); i++) {
12367                ContentProviderRecord cpr = (ContentProviderRecord)
12368                        mLaunchingProviders.get(i);
12369                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12370                    synchronized (cpr) {
12371                        cpr.launchingApp = null;
12372                        cpr.notifyAll();
12373                    }
12374                }
12375            }
12376        }
12377
12378        skipCurrentReceiverLocked(app);
12379
12380        // Unregister any receivers.
12381        for (int i=app.receivers.size()-1; i>=0; i--) {
12382            removeReceiverLocked(app.receivers.valueAt(i));
12383        }
12384        app.receivers.clear();
12385
12386        // If the app is undergoing backup, tell the backup manager about it
12387        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12388            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12389                    + mBackupTarget.appInfo + " died during backup");
12390            try {
12391                IBackupManager bm = IBackupManager.Stub.asInterface(
12392                        ServiceManager.getService(Context.BACKUP_SERVICE));
12393                bm.agentDisconnected(app.info.packageName);
12394            } catch (RemoteException e) {
12395                // can't happen; backup manager is local
12396            }
12397        }
12398
12399        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12400            ProcessChangeItem item = mPendingProcessChanges.get(i);
12401            if (item.pid == app.pid) {
12402                mPendingProcessChanges.remove(i);
12403                mAvailProcessChanges.add(item);
12404            }
12405        }
12406        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12407
12408        // If the caller is restarting this app, then leave it in its
12409        // current lists and let the caller take care of it.
12410        if (restarting) {
12411            return;
12412        }
12413
12414        if (!app.persistent || app.isolated) {
12415            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12416                    "Removing non-persistent process during cleanup: " + app);
12417            mProcessNames.remove(app.processName, app.uid);
12418            mIsolatedProcesses.remove(app.uid);
12419            if (mHeavyWeightProcess == app) {
12420                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12421                        mHeavyWeightProcess.userId, 0));
12422                mHeavyWeightProcess = null;
12423            }
12424        } else if (!app.removed) {
12425            // This app is persistent, so we need to keep its record around.
12426            // If it is not already on the pending app list, add it there
12427            // and start a new process for it.
12428            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12429                mPersistentStartingProcesses.add(app);
12430                restart = true;
12431            }
12432        }
12433        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12434                "Clean-up removing on hold: " + app);
12435        mProcessesOnHold.remove(app);
12436
12437        if (app == mHomeProcess) {
12438            mHomeProcess = null;
12439        }
12440        if (app == mPreviousProcess) {
12441            mPreviousProcess = null;
12442        }
12443
12444        if (restart && !app.isolated) {
12445            // We have components that still need to be running in the
12446            // process, so re-launch it.
12447            mProcessNames.put(app.processName, app.uid, app);
12448            startProcessLocked(app, "restart", app.processName);
12449        } else if (app.pid > 0 && app.pid != MY_PID) {
12450            // Goodbye!
12451            synchronized (mPidsSelfLocked) {
12452                mPidsSelfLocked.remove(app.pid);
12453                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12454            }
12455            app.setPid(0);
12456        }
12457    }
12458
12459    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12460        // Look through the content providers we are waiting to have launched,
12461        // and if any run in this process then either schedule a restart of
12462        // the process or kill the client waiting for it if this process has
12463        // gone bad.
12464        int NL = mLaunchingProviders.size();
12465        boolean restart = false;
12466        for (int i=0; i<NL; i++) {
12467            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12468            if (cpr.launchingApp == app) {
12469                if (!alwaysBad && !app.bad) {
12470                    restart = true;
12471                } else {
12472                    removeDyingProviderLocked(app, cpr, true);
12473                    // cpr should have been removed from mLaunchingProviders
12474                    NL = mLaunchingProviders.size();
12475                    i--;
12476                }
12477            }
12478        }
12479        return restart;
12480    }
12481
12482    // =========================================================
12483    // SERVICES
12484    // =========================================================
12485
12486    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12487            int flags) {
12488        enforceNotIsolatedCaller("getServices");
12489        synchronized (this) {
12490            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12491        }
12492    }
12493
12494    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12495        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12496        synchronized (this) {
12497            return mServices.getRunningServiceControlPanelLocked(name);
12498        }
12499    }
12500
12501    public ComponentName startService(IApplicationThread caller, Intent service,
12502            String resolvedType, int userId) {
12503        enforceNotIsolatedCaller("startService");
12504        // Refuse possible leaked file descriptors
12505        if (service != null && service.hasFileDescriptors() == true) {
12506            throw new IllegalArgumentException("File descriptors passed in Intent");
12507        }
12508
12509        if (DEBUG_SERVICE)
12510            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12511        synchronized(this) {
12512            final int callingPid = Binder.getCallingPid();
12513            final int callingUid = Binder.getCallingUid();
12514            final long origId = Binder.clearCallingIdentity();
12515            ComponentName res = mServices.startServiceLocked(caller, service,
12516                    resolvedType, callingPid, callingUid, userId);
12517            Binder.restoreCallingIdentity(origId);
12518            return res;
12519        }
12520    }
12521
12522    ComponentName startServiceInPackage(int uid,
12523            Intent service, String resolvedType, int userId) {
12524        synchronized(this) {
12525            if (DEBUG_SERVICE)
12526                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12527            final long origId = Binder.clearCallingIdentity();
12528            ComponentName res = mServices.startServiceLocked(null, service,
12529                    resolvedType, -1, uid, userId);
12530            Binder.restoreCallingIdentity(origId);
12531            return res;
12532        }
12533    }
12534
12535    public int stopService(IApplicationThread caller, Intent service,
12536            String resolvedType, int userId) {
12537        enforceNotIsolatedCaller("stopService");
12538        // Refuse possible leaked file descriptors
12539        if (service != null && service.hasFileDescriptors() == true) {
12540            throw new IllegalArgumentException("File descriptors passed in Intent");
12541        }
12542
12543        synchronized(this) {
12544            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12545        }
12546    }
12547
12548    public IBinder peekService(Intent service, String resolvedType) {
12549        enforceNotIsolatedCaller("peekService");
12550        // Refuse possible leaked file descriptors
12551        if (service != null && service.hasFileDescriptors() == true) {
12552            throw new IllegalArgumentException("File descriptors passed in Intent");
12553        }
12554        synchronized(this) {
12555            return mServices.peekServiceLocked(service, resolvedType);
12556        }
12557    }
12558
12559    public boolean stopServiceToken(ComponentName className, IBinder token,
12560            int startId) {
12561        synchronized(this) {
12562            return mServices.stopServiceTokenLocked(className, token, startId);
12563        }
12564    }
12565
12566    public void setServiceForeground(ComponentName className, IBinder token,
12567            int id, Notification notification, boolean removeNotification) {
12568        synchronized(this) {
12569            mServices.setServiceForegroundLocked(className, token, id, notification,
12570                    removeNotification);
12571        }
12572    }
12573
12574    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12575            boolean requireFull, String name, String callerPackage) {
12576        final int callingUserId = UserHandle.getUserId(callingUid);
12577        if (callingUserId != userId) {
12578            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12579                if ((requireFull || checkComponentPermission(
12580                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12581                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12582                        && checkComponentPermission(
12583                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12584                                callingPid, callingUid, -1, true)
12585                                != PackageManager.PERMISSION_GRANTED) {
12586                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12587                        // In this case, they would like to just execute as their
12588                        // owner user instead of failing.
12589                        userId = callingUserId;
12590                    } else {
12591                        StringBuilder builder = new StringBuilder(128);
12592                        builder.append("Permission Denial: ");
12593                        builder.append(name);
12594                        if (callerPackage != null) {
12595                            builder.append(" from ");
12596                            builder.append(callerPackage);
12597                        }
12598                        builder.append(" asks to run as user ");
12599                        builder.append(userId);
12600                        builder.append(" but is calling from user ");
12601                        builder.append(UserHandle.getUserId(callingUid));
12602                        builder.append("; this requires ");
12603                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12604                        if (!requireFull) {
12605                            builder.append(" or ");
12606                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12607                        }
12608                        String msg = builder.toString();
12609                        Slog.w(TAG, msg);
12610                        throw new SecurityException(msg);
12611                    }
12612                }
12613            }
12614            if (userId == UserHandle.USER_CURRENT
12615                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12616                // Note that we may be accessing this outside of a lock...
12617                // shouldn't be a big deal, if this is being called outside
12618                // of a locked context there is intrinsically a race with
12619                // the value the caller will receive and someone else changing it.
12620                userId = mCurrentUserId;
12621            }
12622            if (!allowAll && userId < 0) {
12623                throw new IllegalArgumentException(
12624                        "Call does not support special user #" + userId);
12625            }
12626        }
12627        return userId;
12628    }
12629
12630    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12631            String className, int flags) {
12632        boolean result = false;
12633        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12634            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12635                if (ActivityManager.checkUidPermission(
12636                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12637                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12638                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12639                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12640                            + " requests FLAG_SINGLE_USER, but app does not hold "
12641                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12642                    Slog.w(TAG, msg);
12643                    throw new SecurityException(msg);
12644                }
12645                result = true;
12646            }
12647        } else if (componentProcessName == aInfo.packageName) {
12648            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12649        } else if ("system".equals(componentProcessName)) {
12650            result = true;
12651        }
12652        if (DEBUG_MU) {
12653            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12654                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12655        }
12656        return result;
12657    }
12658
12659    public int bindService(IApplicationThread caller, IBinder token,
12660            Intent service, String resolvedType,
12661            IServiceConnection connection, int flags, int userId) {
12662        enforceNotIsolatedCaller("bindService");
12663        // Refuse possible leaked file descriptors
12664        if (service != null && service.hasFileDescriptors() == true) {
12665            throw new IllegalArgumentException("File descriptors passed in Intent");
12666        }
12667
12668        synchronized(this) {
12669            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12670                    connection, flags, userId);
12671        }
12672    }
12673
12674    public boolean unbindService(IServiceConnection connection) {
12675        synchronized (this) {
12676            return mServices.unbindServiceLocked(connection);
12677        }
12678    }
12679
12680    public void publishService(IBinder token, Intent intent, IBinder service) {
12681        // Refuse possible leaked file descriptors
12682        if (intent != null && intent.hasFileDescriptors() == true) {
12683            throw new IllegalArgumentException("File descriptors passed in Intent");
12684        }
12685
12686        synchronized(this) {
12687            if (!(token instanceof ServiceRecord)) {
12688                throw new IllegalArgumentException("Invalid service token");
12689            }
12690            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12691        }
12692    }
12693
12694    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12695        // Refuse possible leaked file descriptors
12696        if (intent != null && intent.hasFileDescriptors() == true) {
12697            throw new IllegalArgumentException("File descriptors passed in Intent");
12698        }
12699
12700        synchronized(this) {
12701            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12702        }
12703    }
12704
12705    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12706        synchronized(this) {
12707            if (!(token instanceof ServiceRecord)) {
12708                throw new IllegalArgumentException("Invalid service token");
12709            }
12710            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12711        }
12712    }
12713
12714    // =========================================================
12715    // BACKUP AND RESTORE
12716    // =========================================================
12717
12718    // Cause the target app to be launched if necessary and its backup agent
12719    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12720    // activity manager to announce its creation.
12721    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12722        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12723        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12724
12725        synchronized(this) {
12726            // !!! TODO: currently no check here that we're already bound
12727            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12728            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12729            synchronized (stats) {
12730                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12731            }
12732
12733            // Backup agent is now in use, its package can't be stopped.
12734            try {
12735                AppGlobals.getPackageManager().setPackageStoppedState(
12736                        app.packageName, false, UserHandle.getUserId(app.uid));
12737            } catch (RemoteException e) {
12738            } catch (IllegalArgumentException e) {
12739                Slog.w(TAG, "Failed trying to unstop package "
12740                        + app.packageName + ": " + e);
12741            }
12742
12743            BackupRecord r = new BackupRecord(ss, app, backupMode);
12744            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12745                    ? new ComponentName(app.packageName, app.backupAgentName)
12746                    : new ComponentName("android", "FullBackupAgent");
12747            // startProcessLocked() returns existing proc's record if it's already running
12748            ProcessRecord proc = startProcessLocked(app.processName, app,
12749                    false, 0, "backup", hostingName, false, false, false);
12750            if (proc == null) {
12751                Slog.e(TAG, "Unable to start backup agent process " + r);
12752                return false;
12753            }
12754
12755            r.app = proc;
12756            mBackupTarget = r;
12757            mBackupAppName = app.packageName;
12758
12759            // Try not to kill the process during backup
12760            updateOomAdjLocked(proc);
12761
12762            // If the process is already attached, schedule the creation of the backup agent now.
12763            // If it is not yet live, this will be done when it attaches to the framework.
12764            if (proc.thread != null) {
12765                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12766                try {
12767                    proc.thread.scheduleCreateBackupAgent(app,
12768                            compatibilityInfoForPackageLocked(app), backupMode);
12769                } catch (RemoteException e) {
12770                    // Will time out on the backup manager side
12771                }
12772            } else {
12773                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12774            }
12775            // Invariants: at this point, the target app process exists and the application
12776            // is either already running or in the process of coming up.  mBackupTarget and
12777            // mBackupAppName describe the app, so that when it binds back to the AM we
12778            // know that it's scheduled for a backup-agent operation.
12779        }
12780
12781        return true;
12782    }
12783
12784    @Override
12785    public void clearPendingBackup() {
12786        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12787        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12788
12789        synchronized (this) {
12790            mBackupTarget = null;
12791            mBackupAppName = null;
12792        }
12793    }
12794
12795    // A backup agent has just come up
12796    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12797        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12798                + " = " + agent);
12799
12800        synchronized(this) {
12801            if (!agentPackageName.equals(mBackupAppName)) {
12802                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12803                return;
12804            }
12805        }
12806
12807        long oldIdent = Binder.clearCallingIdentity();
12808        try {
12809            IBackupManager bm = IBackupManager.Stub.asInterface(
12810                    ServiceManager.getService(Context.BACKUP_SERVICE));
12811            bm.agentConnected(agentPackageName, agent);
12812        } catch (RemoteException e) {
12813            // can't happen; the backup manager service is local
12814        } catch (Exception e) {
12815            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12816            e.printStackTrace();
12817        } finally {
12818            Binder.restoreCallingIdentity(oldIdent);
12819        }
12820    }
12821
12822    // done with this agent
12823    public void unbindBackupAgent(ApplicationInfo appInfo) {
12824        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12825        if (appInfo == null) {
12826            Slog.w(TAG, "unbind backup agent for null app");
12827            return;
12828        }
12829
12830        synchronized(this) {
12831            try {
12832                if (mBackupAppName == null) {
12833                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12834                    return;
12835                }
12836
12837                if (!mBackupAppName.equals(appInfo.packageName)) {
12838                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12839                    return;
12840                }
12841
12842                // Not backing this app up any more; reset its OOM adjustment
12843                final ProcessRecord proc = mBackupTarget.app;
12844                updateOomAdjLocked(proc);
12845
12846                // If the app crashed during backup, 'thread' will be null here
12847                if (proc.thread != null) {
12848                    try {
12849                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12850                                compatibilityInfoForPackageLocked(appInfo));
12851                    } catch (Exception e) {
12852                        Slog.e(TAG, "Exception when unbinding backup agent:");
12853                        e.printStackTrace();
12854                    }
12855                }
12856            } finally {
12857                mBackupTarget = null;
12858                mBackupAppName = null;
12859            }
12860        }
12861    }
12862    // =========================================================
12863    // BROADCASTS
12864    // =========================================================
12865
12866    private final List getStickiesLocked(String action, IntentFilter filter,
12867            List cur, int userId) {
12868        final ContentResolver resolver = mContext.getContentResolver();
12869        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12870        if (stickies == null) {
12871            return cur;
12872        }
12873        final ArrayList<Intent> list = stickies.get(action);
12874        if (list == null) {
12875            return cur;
12876        }
12877        int N = list.size();
12878        for (int i=0; i<N; i++) {
12879            Intent intent = list.get(i);
12880            if (filter.match(resolver, intent, true, TAG) >= 0) {
12881                if (cur == null) {
12882                    cur = new ArrayList<Intent>();
12883                }
12884                cur.add(intent);
12885            }
12886        }
12887        return cur;
12888    }
12889
12890    boolean isPendingBroadcastProcessLocked(int pid) {
12891        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12892                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12893    }
12894
12895    void skipPendingBroadcastLocked(int pid) {
12896            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12897            for (BroadcastQueue queue : mBroadcastQueues) {
12898                queue.skipPendingBroadcastLocked(pid);
12899            }
12900    }
12901
12902    // The app just attached; send any pending broadcasts that it should receive
12903    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12904        boolean didSomething = false;
12905        for (BroadcastQueue queue : mBroadcastQueues) {
12906            didSomething |= queue.sendPendingBroadcastsLocked(app);
12907        }
12908        return didSomething;
12909    }
12910
12911    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12912            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12913        enforceNotIsolatedCaller("registerReceiver");
12914        int callingUid;
12915        int callingPid;
12916        synchronized(this) {
12917            ProcessRecord callerApp = null;
12918            if (caller != null) {
12919                callerApp = getRecordForAppLocked(caller);
12920                if (callerApp == null) {
12921                    throw new SecurityException(
12922                            "Unable to find app for caller " + caller
12923                            + " (pid=" + Binder.getCallingPid()
12924                            + ") when registering receiver " + receiver);
12925                }
12926                if (callerApp.info.uid != Process.SYSTEM_UID &&
12927                        !callerApp.pkgList.containsKey(callerPackage) &&
12928                        !"android".equals(callerPackage)) {
12929                    throw new SecurityException("Given caller package " + callerPackage
12930                            + " is not running in process " + callerApp);
12931                }
12932                callingUid = callerApp.info.uid;
12933                callingPid = callerApp.pid;
12934            } else {
12935                callerPackage = null;
12936                callingUid = Binder.getCallingUid();
12937                callingPid = Binder.getCallingPid();
12938            }
12939
12940            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12941                    true, true, "registerReceiver", callerPackage);
12942
12943            List allSticky = null;
12944
12945            // Look for any matching sticky broadcasts...
12946            Iterator actions = filter.actionsIterator();
12947            if (actions != null) {
12948                while (actions.hasNext()) {
12949                    String action = (String)actions.next();
12950                    allSticky = getStickiesLocked(action, filter, allSticky,
12951                            UserHandle.USER_ALL);
12952                    allSticky = getStickiesLocked(action, filter, allSticky,
12953                            UserHandle.getUserId(callingUid));
12954                }
12955            } else {
12956                allSticky = getStickiesLocked(null, filter, allSticky,
12957                        UserHandle.USER_ALL);
12958                allSticky = getStickiesLocked(null, filter, allSticky,
12959                        UserHandle.getUserId(callingUid));
12960            }
12961
12962            // The first sticky in the list is returned directly back to
12963            // the client.
12964            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12965
12966            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12967                    + ": " + sticky);
12968
12969            if (receiver == null) {
12970                return sticky;
12971            }
12972
12973            ReceiverList rl
12974                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12975            if (rl == null) {
12976                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
12977                        userId, receiver);
12978                if (rl.app != null) {
12979                    rl.app.receivers.add(rl);
12980                } else {
12981                    try {
12982                        receiver.asBinder().linkToDeath(rl, 0);
12983                    } catch (RemoteException e) {
12984                        return sticky;
12985                    }
12986                    rl.linkedToDeath = true;
12987                }
12988                mRegisteredReceivers.put(receiver.asBinder(), rl);
12989            } else if (rl.uid != callingUid) {
12990                throw new IllegalArgumentException(
12991                        "Receiver requested to register for uid " + callingUid
12992                        + " was previously registered for uid " + rl.uid);
12993            } else if (rl.pid != callingPid) {
12994                throw new IllegalArgumentException(
12995                        "Receiver requested to register for pid " + callingPid
12996                        + " was previously registered for pid " + rl.pid);
12997            } else if (rl.userId != userId) {
12998                throw new IllegalArgumentException(
12999                        "Receiver requested to register for user " + userId
13000                        + " was previously registered for user " + rl.userId);
13001            }
13002            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13003                    permission, callingUid, userId);
13004            rl.add(bf);
13005            if (!bf.debugCheck()) {
13006                Slog.w(TAG, "==> For Dynamic broadast");
13007            }
13008            mReceiverResolver.addFilter(bf);
13009
13010            // Enqueue broadcasts for all existing stickies that match
13011            // this filter.
13012            if (allSticky != null) {
13013                ArrayList receivers = new ArrayList();
13014                receivers.add(bf);
13015
13016                int N = allSticky.size();
13017                for (int i=0; i<N; i++) {
13018                    Intent intent = (Intent)allSticky.get(i);
13019                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13020                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13021                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13022                            null, null, false, true, true, -1);
13023                    queue.enqueueParallelBroadcastLocked(r);
13024                    queue.scheduleBroadcastsLocked();
13025                }
13026            }
13027
13028            return sticky;
13029        }
13030    }
13031
13032    public void unregisterReceiver(IIntentReceiver receiver) {
13033        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13034
13035        final long origId = Binder.clearCallingIdentity();
13036        try {
13037            boolean doTrim = false;
13038
13039            synchronized(this) {
13040                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13041                if (rl != null) {
13042                    if (rl.curBroadcast != null) {
13043                        BroadcastRecord r = rl.curBroadcast;
13044                        final boolean doNext = finishReceiverLocked(
13045                                receiver.asBinder(), r.resultCode, r.resultData,
13046                                r.resultExtras, r.resultAbort);
13047                        if (doNext) {
13048                            doTrim = true;
13049                            r.queue.processNextBroadcast(false);
13050                        }
13051                    }
13052
13053                    if (rl.app != null) {
13054                        rl.app.receivers.remove(rl);
13055                    }
13056                    removeReceiverLocked(rl);
13057                    if (rl.linkedToDeath) {
13058                        rl.linkedToDeath = false;
13059                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13060                    }
13061                }
13062            }
13063
13064            // If we actually concluded any broadcasts, we might now be able
13065            // to trim the recipients' apps from our working set
13066            if (doTrim) {
13067                trimApplications();
13068                return;
13069            }
13070
13071        } finally {
13072            Binder.restoreCallingIdentity(origId);
13073        }
13074    }
13075
13076    void removeReceiverLocked(ReceiverList rl) {
13077        mRegisteredReceivers.remove(rl.receiver.asBinder());
13078        int N = rl.size();
13079        for (int i=0; i<N; i++) {
13080            mReceiverResolver.removeFilter(rl.get(i));
13081        }
13082    }
13083
13084    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13085        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13086            ProcessRecord r = mLruProcesses.get(i);
13087            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13088                try {
13089                    r.thread.dispatchPackageBroadcast(cmd, packages);
13090                } catch (RemoteException ex) {
13091                }
13092            }
13093        }
13094    }
13095
13096    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13097            int[] users) {
13098        List<ResolveInfo> receivers = null;
13099        try {
13100            HashSet<ComponentName> singleUserReceivers = null;
13101            boolean scannedFirstReceivers = false;
13102            for (int user : users) {
13103                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13104                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13105                if (user != 0 && newReceivers != null) {
13106                    // If this is not the primary user, we need to check for
13107                    // any receivers that should be filtered out.
13108                    for (int i=0; i<newReceivers.size(); i++) {
13109                        ResolveInfo ri = newReceivers.get(i);
13110                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13111                            newReceivers.remove(i);
13112                            i--;
13113                        }
13114                    }
13115                }
13116                if (newReceivers != null && newReceivers.size() == 0) {
13117                    newReceivers = null;
13118                }
13119                if (receivers == null) {
13120                    receivers = newReceivers;
13121                } else if (newReceivers != null) {
13122                    // We need to concatenate the additional receivers
13123                    // found with what we have do far.  This would be easy,
13124                    // but we also need to de-dup any receivers that are
13125                    // singleUser.
13126                    if (!scannedFirstReceivers) {
13127                        // Collect any single user receivers we had already retrieved.
13128                        scannedFirstReceivers = true;
13129                        for (int i=0; i<receivers.size(); i++) {
13130                            ResolveInfo ri = receivers.get(i);
13131                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13132                                ComponentName cn = new ComponentName(
13133                                        ri.activityInfo.packageName, ri.activityInfo.name);
13134                                if (singleUserReceivers == null) {
13135                                    singleUserReceivers = new HashSet<ComponentName>();
13136                                }
13137                                singleUserReceivers.add(cn);
13138                            }
13139                        }
13140                    }
13141                    // Add the new results to the existing results, tracking
13142                    // and de-dupping single user receivers.
13143                    for (int i=0; i<newReceivers.size(); i++) {
13144                        ResolveInfo ri = newReceivers.get(i);
13145                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13146                            ComponentName cn = new ComponentName(
13147                                    ri.activityInfo.packageName, ri.activityInfo.name);
13148                            if (singleUserReceivers == null) {
13149                                singleUserReceivers = new HashSet<ComponentName>();
13150                            }
13151                            if (!singleUserReceivers.contains(cn)) {
13152                                singleUserReceivers.add(cn);
13153                                receivers.add(ri);
13154                            }
13155                        } else {
13156                            receivers.add(ri);
13157                        }
13158                    }
13159                }
13160            }
13161        } catch (RemoteException ex) {
13162            // pm is in same process, this will never happen.
13163        }
13164        return receivers;
13165    }
13166
13167    private final int broadcastIntentLocked(ProcessRecord callerApp,
13168            String callerPackage, Intent intent, String resolvedType,
13169            IIntentReceiver resultTo, int resultCode, String resultData,
13170            Bundle map, String requiredPermission, int appOp,
13171            boolean ordered, boolean sticky, int callingPid, int callingUid,
13172            int userId) {
13173        intent = new Intent(intent);
13174
13175        // By default broadcasts do not go to stopped apps.
13176        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13177
13178        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13179            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13180            + " ordered=" + ordered + " userid=" + userId);
13181        if ((resultTo != null) && !ordered) {
13182            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13183        }
13184
13185        userId = handleIncomingUser(callingPid, callingUid, userId,
13186                true, false, "broadcast", callerPackage);
13187
13188        // Make sure that the user who is receiving this broadcast is started.
13189        // If not, we will just skip it.
13190        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13191            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13192                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13193                Slog.w(TAG, "Skipping broadcast of " + intent
13194                        + ": user " + userId + " is stopped");
13195                return ActivityManager.BROADCAST_SUCCESS;
13196            }
13197        }
13198
13199        /*
13200         * Prevent non-system code (defined here to be non-persistent
13201         * processes) from sending protected broadcasts.
13202         */
13203        int callingAppId = UserHandle.getAppId(callingUid);
13204        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13205            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13206            callingUid == 0) {
13207            // Always okay.
13208        } else if (callerApp == null || !callerApp.persistent) {
13209            try {
13210                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13211                        intent.getAction())) {
13212                    String msg = "Permission Denial: not allowed to send broadcast "
13213                            + intent.getAction() + " from pid="
13214                            + callingPid + ", uid=" + callingUid;
13215                    Slog.w(TAG, msg);
13216                    throw new SecurityException(msg);
13217                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13218                    // Special case for compatibility: we don't want apps to send this,
13219                    // but historically it has not been protected and apps may be using it
13220                    // to poke their own app widget.  So, instead of making it protected,
13221                    // just limit it to the caller.
13222                    if (callerApp == null) {
13223                        String msg = "Permission Denial: not allowed to send broadcast "
13224                                + intent.getAction() + " from unknown caller.";
13225                        Slog.w(TAG, msg);
13226                        throw new SecurityException(msg);
13227                    } else if (intent.getComponent() != null) {
13228                        // They are good enough to send to an explicit component...  verify
13229                        // it is being sent to the calling app.
13230                        if (!intent.getComponent().getPackageName().equals(
13231                                callerApp.info.packageName)) {
13232                            String msg = "Permission Denial: not allowed to send broadcast "
13233                                    + intent.getAction() + " to "
13234                                    + intent.getComponent().getPackageName() + " from "
13235                                    + callerApp.info.packageName;
13236                            Slog.w(TAG, msg);
13237                            throw new SecurityException(msg);
13238                        }
13239                    } else {
13240                        // Limit broadcast to their own package.
13241                        intent.setPackage(callerApp.info.packageName);
13242                    }
13243                }
13244            } catch (RemoteException e) {
13245                Slog.w(TAG, "Remote exception", e);
13246                return ActivityManager.BROADCAST_SUCCESS;
13247            }
13248        }
13249
13250        // Handle special intents: if this broadcast is from the package
13251        // manager about a package being removed, we need to remove all of
13252        // its activities from the history stack.
13253        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13254                intent.getAction());
13255        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13256                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13257                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13258                || uidRemoved) {
13259            if (checkComponentPermission(
13260                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13261                    callingPid, callingUid, -1, true)
13262                    == PackageManager.PERMISSION_GRANTED) {
13263                if (uidRemoved) {
13264                    final Bundle intentExtras = intent.getExtras();
13265                    final int uid = intentExtras != null
13266                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13267                    if (uid >= 0) {
13268                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13269                        synchronized (bs) {
13270                            bs.removeUidStatsLocked(uid);
13271                        }
13272                        mAppOpsService.uidRemoved(uid);
13273                    }
13274                } else {
13275                    // If resources are unavailable just force stop all
13276                    // those packages and flush the attribute cache as well.
13277                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13278                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13279                        if (list != null && (list.length > 0)) {
13280                            for (String pkg : list) {
13281                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
13282                                        "storage unmount");
13283                            }
13284                            sendPackageBroadcastLocked(
13285                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13286                        }
13287                    } else {
13288                        Uri data = intent.getData();
13289                        String ssp;
13290                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13291                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13292                                    intent.getAction());
13293                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13294                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13295                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13296                                        false, userId, removed ? "pkg removed" : "pkg changed");
13297                            }
13298                            if (removed) {
13299                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13300                                        new String[] {ssp}, userId);
13301                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13302                                    mAppOpsService.packageRemoved(
13303                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13304
13305                                    // Remove all permissions granted from/to this package
13306                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13307                                }
13308                            }
13309                        }
13310                    }
13311                }
13312            } else {
13313                String msg = "Permission Denial: " + intent.getAction()
13314                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13315                        + ", uid=" + callingUid + ")"
13316                        + " requires "
13317                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13318                Slog.w(TAG, msg);
13319                throw new SecurityException(msg);
13320            }
13321
13322        // Special case for adding a package: by default turn on compatibility
13323        // mode.
13324        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13325            Uri data = intent.getData();
13326            String ssp;
13327            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13328                mCompatModePackages.handlePackageAddedLocked(ssp,
13329                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13330            }
13331        }
13332
13333        /*
13334         * If this is the time zone changed action, queue up a message that will reset the timezone
13335         * of all currently running processes. This message will get queued up before the broadcast
13336         * happens.
13337         */
13338        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13339            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13340        }
13341
13342        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13343            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13344        }
13345
13346        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13347            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13348            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13349        }
13350
13351        // Add to the sticky list if requested.
13352        if (sticky) {
13353            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13354                    callingPid, callingUid)
13355                    != PackageManager.PERMISSION_GRANTED) {
13356                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13357                        + callingPid + ", uid=" + callingUid
13358                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13359                Slog.w(TAG, msg);
13360                throw new SecurityException(msg);
13361            }
13362            if (requiredPermission != null) {
13363                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13364                        + " and enforce permission " + requiredPermission);
13365                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13366            }
13367            if (intent.getComponent() != null) {
13368                throw new SecurityException(
13369                        "Sticky broadcasts can't target a specific component");
13370            }
13371            // We use userId directly here, since the "all" target is maintained
13372            // as a separate set of sticky broadcasts.
13373            if (userId != UserHandle.USER_ALL) {
13374                // But first, if this is not a broadcast to all users, then
13375                // make sure it doesn't conflict with an existing broadcast to
13376                // all users.
13377                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13378                        UserHandle.USER_ALL);
13379                if (stickies != null) {
13380                    ArrayList<Intent> list = stickies.get(intent.getAction());
13381                    if (list != null) {
13382                        int N = list.size();
13383                        int i;
13384                        for (i=0; i<N; i++) {
13385                            if (intent.filterEquals(list.get(i))) {
13386                                throw new IllegalArgumentException(
13387                                        "Sticky broadcast " + intent + " for user "
13388                                        + userId + " conflicts with existing global broadcast");
13389                            }
13390                        }
13391                    }
13392                }
13393            }
13394            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13395            if (stickies == null) {
13396                stickies = new ArrayMap<String, ArrayList<Intent>>();
13397                mStickyBroadcasts.put(userId, stickies);
13398            }
13399            ArrayList<Intent> list = stickies.get(intent.getAction());
13400            if (list == null) {
13401                list = new ArrayList<Intent>();
13402                stickies.put(intent.getAction(), list);
13403            }
13404            int N = list.size();
13405            int i;
13406            for (i=0; i<N; i++) {
13407                if (intent.filterEquals(list.get(i))) {
13408                    // This sticky already exists, replace it.
13409                    list.set(i, new Intent(intent));
13410                    break;
13411                }
13412            }
13413            if (i >= N) {
13414                list.add(new Intent(intent));
13415            }
13416        }
13417
13418        int[] users;
13419        if (userId == UserHandle.USER_ALL) {
13420            // Caller wants broadcast to go to all started users.
13421            users = mStartedUserArray;
13422        } else {
13423            // Caller wants broadcast to go to one specific user.
13424            users = new int[] {userId};
13425        }
13426
13427        // Figure out who all will receive this broadcast.
13428        List receivers = null;
13429        List<BroadcastFilter> registeredReceivers = null;
13430        // Need to resolve the intent to interested receivers...
13431        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13432                 == 0) {
13433            receivers = collectReceiverComponents(intent, resolvedType, users);
13434        }
13435        if (intent.getComponent() == null) {
13436            registeredReceivers = mReceiverResolver.queryIntent(intent,
13437                    resolvedType, false, userId);
13438        }
13439
13440        final boolean replacePending =
13441                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13442
13443        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13444                + " replacePending=" + replacePending);
13445
13446        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13447        if (!ordered && NR > 0) {
13448            // If we are not serializing this broadcast, then send the
13449            // registered receivers separately so they don't wait for the
13450            // components to be launched.
13451            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13452            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13453                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13454                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13455                    ordered, sticky, false, userId);
13456            if (DEBUG_BROADCAST) Slog.v(
13457                    TAG, "Enqueueing parallel broadcast " + r);
13458            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13459            if (!replaced) {
13460                queue.enqueueParallelBroadcastLocked(r);
13461                queue.scheduleBroadcastsLocked();
13462            }
13463            registeredReceivers = null;
13464            NR = 0;
13465        }
13466
13467        // Merge into one list.
13468        int ir = 0;
13469        if (receivers != null) {
13470            // A special case for PACKAGE_ADDED: do not allow the package
13471            // being added to see this broadcast.  This prevents them from
13472            // using this as a back door to get run as soon as they are
13473            // installed.  Maybe in the future we want to have a special install
13474            // broadcast or such for apps, but we'd like to deliberately make
13475            // this decision.
13476            String skipPackages[] = null;
13477            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13478                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13479                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13480                Uri data = intent.getData();
13481                if (data != null) {
13482                    String pkgName = data.getSchemeSpecificPart();
13483                    if (pkgName != null) {
13484                        skipPackages = new String[] { pkgName };
13485                    }
13486                }
13487            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13488                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13489            }
13490            if (skipPackages != null && (skipPackages.length > 0)) {
13491                for (String skipPackage : skipPackages) {
13492                    if (skipPackage != null) {
13493                        int NT = receivers.size();
13494                        for (int it=0; it<NT; it++) {
13495                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13496                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13497                                receivers.remove(it);
13498                                it--;
13499                                NT--;
13500                            }
13501                        }
13502                    }
13503                }
13504            }
13505
13506            int NT = receivers != null ? receivers.size() : 0;
13507            int it = 0;
13508            ResolveInfo curt = null;
13509            BroadcastFilter curr = null;
13510            while (it < NT && ir < NR) {
13511                if (curt == null) {
13512                    curt = (ResolveInfo)receivers.get(it);
13513                }
13514                if (curr == null) {
13515                    curr = registeredReceivers.get(ir);
13516                }
13517                if (curr.getPriority() >= curt.priority) {
13518                    // Insert this broadcast record into the final list.
13519                    receivers.add(it, curr);
13520                    ir++;
13521                    curr = null;
13522                    it++;
13523                    NT++;
13524                } else {
13525                    // Skip to the next ResolveInfo in the final list.
13526                    it++;
13527                    curt = null;
13528                }
13529            }
13530        }
13531        while (ir < NR) {
13532            if (receivers == null) {
13533                receivers = new ArrayList();
13534            }
13535            receivers.add(registeredReceivers.get(ir));
13536            ir++;
13537        }
13538
13539        if ((receivers != null && receivers.size() > 0)
13540                || resultTo != null) {
13541            BroadcastQueue queue = broadcastQueueForIntent(intent);
13542            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13543                    callerPackage, callingPid, callingUid, resolvedType,
13544                    requiredPermission, appOp, receivers, resultTo, resultCode,
13545                    resultData, map, ordered, sticky, false, userId);
13546            if (DEBUG_BROADCAST) Slog.v(
13547                    TAG, "Enqueueing ordered broadcast " + r
13548                    + ": prev had " + queue.mOrderedBroadcasts.size());
13549            if (DEBUG_BROADCAST) {
13550                int seq = r.intent.getIntExtra("seq", -1);
13551                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13552            }
13553            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13554            if (!replaced) {
13555                queue.enqueueOrderedBroadcastLocked(r);
13556                queue.scheduleBroadcastsLocked();
13557            }
13558        }
13559
13560        return ActivityManager.BROADCAST_SUCCESS;
13561    }
13562
13563    final Intent verifyBroadcastLocked(Intent intent) {
13564        // Refuse possible leaked file descriptors
13565        if (intent != null && intent.hasFileDescriptors() == true) {
13566            throw new IllegalArgumentException("File descriptors passed in Intent");
13567        }
13568
13569        int flags = intent.getFlags();
13570
13571        if (!mProcessesReady) {
13572            // if the caller really truly claims to know what they're doing, go
13573            // ahead and allow the broadcast without launching any receivers
13574            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13575                intent = new Intent(intent);
13576                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13577            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13578                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13579                        + " before boot completion");
13580                throw new IllegalStateException("Cannot broadcast before boot completed");
13581            }
13582        }
13583
13584        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13585            throw new IllegalArgumentException(
13586                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13587        }
13588
13589        return intent;
13590    }
13591
13592    public final int broadcastIntent(IApplicationThread caller,
13593            Intent intent, String resolvedType, IIntentReceiver resultTo,
13594            int resultCode, String resultData, Bundle map,
13595            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13596        enforceNotIsolatedCaller("broadcastIntent");
13597        synchronized(this) {
13598            intent = verifyBroadcastLocked(intent);
13599
13600            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13601            final int callingPid = Binder.getCallingPid();
13602            final int callingUid = Binder.getCallingUid();
13603            final long origId = Binder.clearCallingIdentity();
13604            int res = broadcastIntentLocked(callerApp,
13605                    callerApp != null ? callerApp.info.packageName : null,
13606                    intent, resolvedType, resultTo,
13607                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13608                    callingPid, callingUid, userId);
13609            Binder.restoreCallingIdentity(origId);
13610            return res;
13611        }
13612    }
13613
13614    int broadcastIntentInPackage(String packageName, int uid,
13615            Intent intent, String resolvedType, IIntentReceiver resultTo,
13616            int resultCode, String resultData, Bundle map,
13617            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13618        synchronized(this) {
13619            intent = verifyBroadcastLocked(intent);
13620
13621            final long origId = Binder.clearCallingIdentity();
13622            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13623                    resultTo, resultCode, resultData, map, requiredPermission,
13624                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13625            Binder.restoreCallingIdentity(origId);
13626            return res;
13627        }
13628    }
13629
13630    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13631        // Refuse possible leaked file descriptors
13632        if (intent != null && intent.hasFileDescriptors() == true) {
13633            throw new IllegalArgumentException("File descriptors passed in Intent");
13634        }
13635
13636        userId = handleIncomingUser(Binder.getCallingPid(),
13637                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13638
13639        synchronized(this) {
13640            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13641                    != PackageManager.PERMISSION_GRANTED) {
13642                String msg = "Permission Denial: unbroadcastIntent() from pid="
13643                        + Binder.getCallingPid()
13644                        + ", uid=" + Binder.getCallingUid()
13645                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13646                Slog.w(TAG, msg);
13647                throw new SecurityException(msg);
13648            }
13649            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13650            if (stickies != null) {
13651                ArrayList<Intent> list = stickies.get(intent.getAction());
13652                if (list != null) {
13653                    int N = list.size();
13654                    int i;
13655                    for (i=0; i<N; i++) {
13656                        if (intent.filterEquals(list.get(i))) {
13657                            list.remove(i);
13658                            break;
13659                        }
13660                    }
13661                    if (list.size() <= 0) {
13662                        stickies.remove(intent.getAction());
13663                    }
13664                }
13665                if (stickies.size() <= 0) {
13666                    mStickyBroadcasts.remove(userId);
13667                }
13668            }
13669        }
13670    }
13671
13672    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13673            String resultData, Bundle resultExtras, boolean resultAbort) {
13674        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13675        if (r == null) {
13676            Slog.w(TAG, "finishReceiver called but not found on queue");
13677            return false;
13678        }
13679
13680        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13681    }
13682
13683    void backgroundServicesFinishedLocked(int userId) {
13684        for (BroadcastQueue queue : mBroadcastQueues) {
13685            queue.backgroundServicesFinishedLocked(userId);
13686        }
13687    }
13688
13689    public void finishReceiver(IBinder who, int resultCode, String resultData,
13690            Bundle resultExtras, boolean resultAbort) {
13691        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13692
13693        // Refuse possible leaked file descriptors
13694        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13695            throw new IllegalArgumentException("File descriptors passed in Bundle");
13696        }
13697
13698        final long origId = Binder.clearCallingIdentity();
13699        try {
13700            boolean doNext = false;
13701            BroadcastRecord r;
13702
13703            synchronized(this) {
13704                r = broadcastRecordForReceiverLocked(who);
13705                if (r != null) {
13706                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13707                        resultData, resultExtras, resultAbort, true);
13708                }
13709            }
13710
13711            if (doNext) {
13712                r.queue.processNextBroadcast(false);
13713            }
13714            trimApplications();
13715        } finally {
13716            Binder.restoreCallingIdentity(origId);
13717        }
13718    }
13719
13720    // =========================================================
13721    // INSTRUMENTATION
13722    // =========================================================
13723
13724    public boolean startInstrumentation(ComponentName className,
13725            String profileFile, int flags, Bundle arguments,
13726            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13727            int userId) {
13728        enforceNotIsolatedCaller("startInstrumentation");
13729        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13730                userId, false, true, "startInstrumentation", null);
13731        // Refuse possible leaked file descriptors
13732        if (arguments != null && arguments.hasFileDescriptors()) {
13733            throw new IllegalArgumentException("File descriptors passed in Bundle");
13734        }
13735
13736        synchronized(this) {
13737            InstrumentationInfo ii = null;
13738            ApplicationInfo ai = null;
13739            try {
13740                ii = mContext.getPackageManager().getInstrumentationInfo(
13741                    className, STOCK_PM_FLAGS);
13742                ai = AppGlobals.getPackageManager().getApplicationInfo(
13743                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13744            } catch (PackageManager.NameNotFoundException e) {
13745            } catch (RemoteException e) {
13746            }
13747            if (ii == null) {
13748                reportStartInstrumentationFailure(watcher, className,
13749                        "Unable to find instrumentation info for: " + className);
13750                return false;
13751            }
13752            if (ai == null) {
13753                reportStartInstrumentationFailure(watcher, className,
13754                        "Unable to find instrumentation target package: " + ii.targetPackage);
13755                return false;
13756            }
13757
13758            int match = mContext.getPackageManager().checkSignatures(
13759                    ii.targetPackage, ii.packageName);
13760            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13761                String msg = "Permission Denial: starting instrumentation "
13762                        + className + " from pid="
13763                        + Binder.getCallingPid()
13764                        + ", uid=" + Binder.getCallingPid()
13765                        + " not allowed because package " + ii.packageName
13766                        + " does not have a signature matching the target "
13767                        + ii.targetPackage;
13768                reportStartInstrumentationFailure(watcher, className, msg);
13769                throw new SecurityException(msg);
13770            }
13771
13772            final long origId = Binder.clearCallingIdentity();
13773            // Instrumentation can kill and relaunch even persistent processes
13774            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
13775                    "start instr");
13776            ProcessRecord app = addAppLocked(ai, false);
13777            app.instrumentationClass = className;
13778            app.instrumentationInfo = ai;
13779            app.instrumentationProfileFile = profileFile;
13780            app.instrumentationArguments = arguments;
13781            app.instrumentationWatcher = watcher;
13782            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13783            app.instrumentationResultClass = className;
13784            Binder.restoreCallingIdentity(origId);
13785        }
13786
13787        return true;
13788    }
13789
13790    /**
13791     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13792     * error to the logs, but if somebody is watching, send the report there too.  This enables
13793     * the "am" command to report errors with more information.
13794     *
13795     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13796     * @param cn The component name of the instrumentation.
13797     * @param report The error report.
13798     */
13799    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13800            ComponentName cn, String report) {
13801        Slog.w(TAG, report);
13802        try {
13803            if (watcher != null) {
13804                Bundle results = new Bundle();
13805                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13806                results.putString("Error", report);
13807                watcher.instrumentationStatus(cn, -1, results);
13808            }
13809        } catch (RemoteException e) {
13810            Slog.w(TAG, e);
13811        }
13812    }
13813
13814    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13815        if (app.instrumentationWatcher != null) {
13816            try {
13817                // NOTE:  IInstrumentationWatcher *must* be oneway here
13818                app.instrumentationWatcher.instrumentationFinished(
13819                    app.instrumentationClass,
13820                    resultCode,
13821                    results);
13822            } catch (RemoteException e) {
13823            }
13824        }
13825        if (app.instrumentationUiAutomationConnection != null) {
13826            try {
13827                app.instrumentationUiAutomationConnection.shutdown();
13828            } catch (RemoteException re) {
13829                /* ignore */
13830            }
13831            // Only a UiAutomation can set this flag and now that
13832            // it is finished we make sure it is reset to its default.
13833            mUserIsMonkey = false;
13834        }
13835        app.instrumentationWatcher = null;
13836        app.instrumentationUiAutomationConnection = null;
13837        app.instrumentationClass = null;
13838        app.instrumentationInfo = null;
13839        app.instrumentationProfileFile = null;
13840        app.instrumentationArguments = null;
13841
13842        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
13843                "finished inst");
13844    }
13845
13846    public void finishInstrumentation(IApplicationThread target,
13847            int resultCode, Bundle results) {
13848        int userId = UserHandle.getCallingUserId();
13849        // Refuse possible leaked file descriptors
13850        if (results != null && results.hasFileDescriptors()) {
13851            throw new IllegalArgumentException("File descriptors passed in Intent");
13852        }
13853
13854        synchronized(this) {
13855            ProcessRecord app = getRecordForAppLocked(target);
13856            if (app == null) {
13857                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13858                return;
13859            }
13860            final long origId = Binder.clearCallingIdentity();
13861            finishInstrumentationLocked(app, resultCode, results);
13862            Binder.restoreCallingIdentity(origId);
13863        }
13864    }
13865
13866    // =========================================================
13867    // CONFIGURATION
13868    // =========================================================
13869
13870    public ConfigurationInfo getDeviceConfigurationInfo() {
13871        ConfigurationInfo config = new ConfigurationInfo();
13872        synchronized (this) {
13873            config.reqTouchScreen = mConfiguration.touchscreen;
13874            config.reqKeyboardType = mConfiguration.keyboard;
13875            config.reqNavigation = mConfiguration.navigation;
13876            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13877                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13878                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13879            }
13880            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13881                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13882                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13883            }
13884            config.reqGlEsVersion = GL_ES_VERSION;
13885        }
13886        return config;
13887    }
13888
13889    ActivityStack getFocusedStack() {
13890        return mStackSupervisor.getFocusedStack();
13891    }
13892
13893    public Configuration getConfiguration() {
13894        Configuration ci;
13895        synchronized(this) {
13896            ci = new Configuration(mConfiguration);
13897        }
13898        return ci;
13899    }
13900
13901    public void updatePersistentConfiguration(Configuration values) {
13902        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13903                "updateConfiguration()");
13904        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13905                "updateConfiguration()");
13906        if (values == null) {
13907            throw new NullPointerException("Configuration must not be null");
13908        }
13909
13910        synchronized(this) {
13911            final long origId = Binder.clearCallingIdentity();
13912            updateConfigurationLocked(values, null, true, false);
13913            Binder.restoreCallingIdentity(origId);
13914        }
13915    }
13916
13917    public void updateConfiguration(Configuration values) {
13918        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13919                "updateConfiguration()");
13920
13921        synchronized(this) {
13922            if (values == null && mWindowManager != null) {
13923                // sentinel: fetch the current configuration from the window manager
13924                values = mWindowManager.computeNewConfiguration();
13925            }
13926
13927            if (mWindowManager != null) {
13928                mProcessList.applyDisplaySize(mWindowManager);
13929            }
13930
13931            final long origId = Binder.clearCallingIdentity();
13932            if (values != null) {
13933                Settings.System.clearConfiguration(values);
13934            }
13935            updateConfigurationLocked(values, null, false, false);
13936            Binder.restoreCallingIdentity(origId);
13937        }
13938    }
13939
13940    /**
13941     * Do either or both things: (1) change the current configuration, and (2)
13942     * make sure the given activity is running with the (now) current
13943     * configuration.  Returns true if the activity has been left running, or
13944     * false if <var>starting</var> is being destroyed to match the new
13945     * configuration.
13946     * @param persistent TODO
13947     */
13948    boolean updateConfigurationLocked(Configuration values,
13949            ActivityRecord starting, boolean persistent, boolean initLocale) {
13950        int changes = 0;
13951
13952        if (values != null) {
13953            Configuration newConfig = new Configuration(mConfiguration);
13954            changes = newConfig.updateFrom(values);
13955            if (changes != 0) {
13956                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13957                    Slog.i(TAG, "Updating configuration to: " + values);
13958                }
13959
13960                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13961
13962                if (values.locale != null && !initLocale) {
13963                    saveLocaleLocked(values.locale,
13964                                     !values.locale.equals(mConfiguration.locale),
13965                                     values.userSetLocale);
13966                }
13967
13968                mConfigurationSeq++;
13969                if (mConfigurationSeq <= 0) {
13970                    mConfigurationSeq = 1;
13971                }
13972                newConfig.seq = mConfigurationSeq;
13973                mConfiguration = newConfig;
13974                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
13975
13976                final Configuration configCopy = new Configuration(mConfiguration);
13977
13978                // TODO: If our config changes, should we auto dismiss any currently
13979                // showing dialogs?
13980                mShowDialogs = shouldShowDialogs(newConfig);
13981
13982                AttributeCache ac = AttributeCache.instance();
13983                if (ac != null) {
13984                    ac.updateConfiguration(configCopy);
13985                }
13986
13987                // Make sure all resources in our process are updated
13988                // right now, so that anyone who is going to retrieve
13989                // resource values after we return will be sure to get
13990                // the new ones.  This is especially important during
13991                // boot, where the first config change needs to guarantee
13992                // all resources have that config before following boot
13993                // code is executed.
13994                mSystemThread.applyConfigurationToResources(configCopy);
13995
13996                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
13997                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
13998                    msg.obj = new Configuration(configCopy);
13999                    mHandler.sendMessage(msg);
14000                }
14001
14002                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14003                    ProcessRecord app = mLruProcesses.get(i);
14004                    try {
14005                        if (app.thread != null) {
14006                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14007                                    + app.processName + " new config " + mConfiguration);
14008                            app.thread.scheduleConfigurationChanged(configCopy);
14009                        }
14010                    } catch (Exception e) {
14011                    }
14012                }
14013                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14014                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14015                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14016                        | Intent.FLAG_RECEIVER_FOREGROUND);
14017                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14018                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14019                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14020                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14021                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14022                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14023                    broadcastIntentLocked(null, null, intent,
14024                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14025                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14026                }
14027            }
14028        }
14029
14030        boolean kept = true;
14031        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14032        // mainStack is null during startup.
14033        if (mainStack != null) {
14034            if (changes != 0 && starting == null) {
14035                // If the configuration changed, and the caller is not already
14036                // in the process of starting an activity, then find the top
14037                // activity to check if its configuration needs to change.
14038                starting = mainStack.topRunningActivityLocked(null);
14039            }
14040
14041            if (starting != null) {
14042                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14043                // And we need to make sure at this point that all other activities
14044                // are made visible with the correct configuration.
14045                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14046            }
14047        }
14048
14049        if (values != null && mWindowManager != null) {
14050            mWindowManager.setNewConfiguration(mConfiguration);
14051        }
14052
14053        return kept;
14054    }
14055
14056    /**
14057     * Decide based on the configuration whether we should shouw the ANR,
14058     * crash, etc dialogs.  The idea is that if there is no affordnace to
14059     * press the on-screen buttons, we shouldn't show the dialog.
14060     *
14061     * A thought: SystemUI might also want to get told about this, the Power
14062     * dialog / global actions also might want different behaviors.
14063     */
14064    private static final boolean shouldShowDialogs(Configuration config) {
14065        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14066                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14067    }
14068
14069    /**
14070     * Save the locale.  You must be inside a synchronized (this) block.
14071     */
14072    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14073        if(isDiff) {
14074            SystemProperties.set("user.language", l.getLanguage());
14075            SystemProperties.set("user.region", l.getCountry());
14076        }
14077
14078        if(isPersist) {
14079            SystemProperties.set("persist.sys.language", l.getLanguage());
14080            SystemProperties.set("persist.sys.country", l.getCountry());
14081            SystemProperties.set("persist.sys.localevar", l.getVariant());
14082        }
14083    }
14084
14085    @Override
14086    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14087        ActivityRecord srec = ActivityRecord.forToken(token);
14088        return srec != null && srec.task.affinity != null &&
14089                srec.task.affinity.equals(destAffinity);
14090    }
14091
14092    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14093            Intent resultData) {
14094
14095        synchronized (this) {
14096            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14097            if (stack != null) {
14098                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14099            }
14100            return false;
14101        }
14102    }
14103
14104    public int getLaunchedFromUid(IBinder activityToken) {
14105        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14106        if (srec == null) {
14107            return -1;
14108        }
14109        return srec.launchedFromUid;
14110    }
14111
14112    public String getLaunchedFromPackage(IBinder activityToken) {
14113        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14114        if (srec == null) {
14115            return null;
14116        }
14117        return srec.launchedFromPackage;
14118    }
14119
14120    // =========================================================
14121    // LIFETIME MANAGEMENT
14122    // =========================================================
14123
14124    // Returns which broadcast queue the app is the current [or imminent] receiver
14125    // on, or 'null' if the app is not an active broadcast recipient.
14126    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14127        BroadcastRecord r = app.curReceiver;
14128        if (r != null) {
14129            return r.queue;
14130        }
14131
14132        // It's not the current receiver, but it might be starting up to become one
14133        synchronized (this) {
14134            for (BroadcastQueue queue : mBroadcastQueues) {
14135                r = queue.mPendingBroadcast;
14136                if (r != null && r.curApp == app) {
14137                    // found it; report which queue it's in
14138                    return queue;
14139                }
14140            }
14141        }
14142
14143        return null;
14144    }
14145
14146    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14147            boolean doingAll, long now) {
14148        if (mAdjSeq == app.adjSeq) {
14149            // This adjustment has already been computed.
14150            return app.curRawAdj;
14151        }
14152
14153        if (app.thread == null) {
14154            app.adjSeq = mAdjSeq;
14155            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14156            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14157            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14158        }
14159
14160        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14161        app.adjSource = null;
14162        app.adjTarget = null;
14163        app.empty = false;
14164        app.cached = false;
14165
14166        final int activitiesSize = app.activities.size();
14167
14168        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14169            // The max adjustment doesn't allow this app to be anything
14170            // below foreground, so it is not worth doing work for it.
14171            app.adjType = "fixed";
14172            app.adjSeq = mAdjSeq;
14173            app.curRawAdj = app.maxAdj;
14174            app.foregroundActivities = false;
14175            app.keeping = true;
14176            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14177            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14178            // System process can do UI, and when they do we want to have
14179            // them trim their memory after the user leaves the UI.  To
14180            // facilitate this, here we need to determine whether or not it
14181            // is currently showing UI.
14182            app.systemNoUi = true;
14183            if (app == TOP_APP) {
14184                app.systemNoUi = false;
14185            } else if (activitiesSize > 0) {
14186                for (int j = 0; j < activitiesSize; j++) {
14187                    final ActivityRecord r = app.activities.get(j);
14188                    if (r.visible) {
14189                        app.systemNoUi = false;
14190                    }
14191                }
14192            }
14193            if (!app.systemNoUi) {
14194                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14195            }
14196            return (app.curAdj=app.maxAdj);
14197        }
14198
14199        app.keeping = false;
14200        app.systemNoUi = false;
14201
14202        // Determine the importance of the process, starting with most
14203        // important to least, and assign an appropriate OOM adjustment.
14204        int adj;
14205        int schedGroup;
14206        int procState;
14207        boolean foregroundActivities = false;
14208        boolean interesting = false;
14209        BroadcastQueue queue;
14210        if (app == TOP_APP) {
14211            // The last app on the list is the foreground app.
14212            adj = ProcessList.FOREGROUND_APP_ADJ;
14213            schedGroup = Process.THREAD_GROUP_DEFAULT;
14214            app.adjType = "top-activity";
14215            foregroundActivities = true;
14216            interesting = true;
14217            procState = ActivityManager.PROCESS_STATE_TOP;
14218        } else if (app.instrumentationClass != null) {
14219            // Don't want to kill running instrumentation.
14220            adj = ProcessList.FOREGROUND_APP_ADJ;
14221            schedGroup = Process.THREAD_GROUP_DEFAULT;
14222            app.adjType = "instrumentation";
14223            interesting = true;
14224            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14225        } else if ((queue = isReceivingBroadcast(app)) != null) {
14226            // An app that is currently receiving a broadcast also
14227            // counts as being in the foreground for OOM killer purposes.
14228            // It's placed in a sched group based on the nature of the
14229            // broadcast as reflected by which queue it's active in.
14230            adj = ProcessList.FOREGROUND_APP_ADJ;
14231            schedGroup = (queue == mFgBroadcastQueue)
14232                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14233            app.adjType = "broadcast";
14234            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14235        } else if (app.executingServices.size() > 0) {
14236            // An app that is currently executing a service callback also
14237            // counts as being in the foreground.
14238            adj = ProcessList.FOREGROUND_APP_ADJ;
14239            schedGroup = app.execServicesFg ?
14240                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14241            app.adjType = "exec-service";
14242            procState = ActivityManager.PROCESS_STATE_SERVICE;
14243            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14244        } else {
14245            // As far as we know the process is empty.  We may change our mind later.
14246            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14247            // At this point we don't actually know the adjustment.  Use the cached adj
14248            // value that the caller wants us to.
14249            adj = cachedAdj;
14250            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14251            app.cached = true;
14252            app.empty = true;
14253            app.adjType = "cch-empty";
14254        }
14255
14256        // Examine all activities if not already foreground.
14257        if (!foregroundActivities && activitiesSize > 0) {
14258            for (int j = 0; j < activitiesSize; j++) {
14259                final ActivityRecord r = app.activities.get(j);
14260                if (r.app != app) {
14261                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14262                            + app + "?!?");
14263                    continue;
14264                }
14265                if (r.visible) {
14266                    // App has a visible activity; only upgrade adjustment.
14267                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14268                        adj = ProcessList.VISIBLE_APP_ADJ;
14269                        app.adjType = "visible";
14270                    }
14271                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14272                        procState = ActivityManager.PROCESS_STATE_TOP;
14273                    }
14274                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14275                    app.cached = false;
14276                    app.empty = false;
14277                    foregroundActivities = true;
14278                    break;
14279                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14280                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14281                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14282                        app.adjType = "pausing";
14283                    }
14284                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14285                        procState = ActivityManager.PROCESS_STATE_TOP;
14286                    }
14287                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14288                    app.cached = false;
14289                    app.empty = false;
14290                    foregroundActivities = true;
14291                } else if (r.state == ActivityState.STOPPING) {
14292                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14293                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14294                        app.adjType = "stopping";
14295                    }
14296                    // For the process state, we will at this point consider the
14297                    // process to be cached.  It will be cached either as an activity
14298                    // or empty depending on whether the activity is finishing.  We do
14299                    // this so that we can treat the process as cached for purposes of
14300                    // memory trimming (determing current memory level, trim command to
14301                    // send to process) since there can be an arbitrary number of stopping
14302                    // processes and they should soon all go into the cached state.
14303                    if (!r.finishing) {
14304                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14305                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14306                        }
14307                    }
14308                    app.cached = false;
14309                    app.empty = false;
14310                    foregroundActivities = true;
14311                } else {
14312                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14313                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14314                        app.adjType = "cch-act";
14315                    }
14316                }
14317            }
14318        }
14319
14320        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14321            if (app.foregroundServices) {
14322                // The user is aware of this app, so make it visible.
14323                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14324                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14325                app.cached = false;
14326                app.adjType = "fg-service";
14327                schedGroup = Process.THREAD_GROUP_DEFAULT;
14328            } else if (app.forcingToForeground != null) {
14329                // The user is aware of this app, so make it visible.
14330                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14331                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14332                app.cached = false;
14333                app.adjType = "force-fg";
14334                app.adjSource = app.forcingToForeground;
14335                schedGroup = Process.THREAD_GROUP_DEFAULT;
14336            }
14337        }
14338
14339        if (app.foregroundServices) {
14340            interesting = true;
14341        }
14342
14343        if (app == mHeavyWeightProcess) {
14344            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14345                // We don't want to kill the current heavy-weight process.
14346                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14347                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14348                app.cached = false;
14349                app.adjType = "heavy";
14350            }
14351            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14352                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14353            }
14354        }
14355
14356        if (app == mHomeProcess) {
14357            if (adj > ProcessList.HOME_APP_ADJ) {
14358                // This process is hosting what we currently consider to be the
14359                // home app, so we don't want to let it go into the background.
14360                adj = ProcessList.HOME_APP_ADJ;
14361                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14362                app.cached = false;
14363                app.adjType = "home";
14364            }
14365            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14366                procState = ActivityManager.PROCESS_STATE_HOME;
14367            }
14368        }
14369
14370        if (app == mPreviousProcess && app.activities.size() > 0) {
14371            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14372                // This was the previous process that showed UI to the user.
14373                // We want to try to keep it around more aggressively, to give
14374                // a good experience around switching between two apps.
14375                adj = ProcessList.PREVIOUS_APP_ADJ;
14376                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14377                app.cached = false;
14378                app.adjType = "previous";
14379            }
14380            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14381                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14382            }
14383        }
14384
14385        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14386                + " reason=" + app.adjType);
14387
14388        // By default, we use the computed adjustment.  It may be changed if
14389        // there are applications dependent on our services or providers, but
14390        // this gives us a baseline and makes sure we don't get into an
14391        // infinite recursion.
14392        app.adjSeq = mAdjSeq;
14393        app.curRawAdj = adj;
14394        app.hasStartedServices = false;
14395
14396        if (mBackupTarget != null && app == mBackupTarget.app) {
14397            // If possible we want to avoid killing apps while they're being backed up
14398            if (adj > ProcessList.BACKUP_APP_ADJ) {
14399                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14400                adj = ProcessList.BACKUP_APP_ADJ;
14401                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14402                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14403                }
14404                app.adjType = "backup";
14405                app.cached = false;
14406            }
14407            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14408                procState = ActivityManager.PROCESS_STATE_BACKUP;
14409            }
14410        }
14411
14412        boolean mayBeTop = false;
14413
14414        for (int is = app.services.size()-1;
14415                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14416                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14417                        || procState > ActivityManager.PROCESS_STATE_TOP);
14418                is--) {
14419            ServiceRecord s = app.services.valueAt(is);
14420            if (s.startRequested) {
14421                app.hasStartedServices = true;
14422                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14423                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14424                }
14425                if (app.hasShownUi && app != mHomeProcess) {
14426                    // If this process has shown some UI, let it immediately
14427                    // go to the LRU list because it may be pretty heavy with
14428                    // UI stuff.  We'll tag it with a label just to help
14429                    // debug and understand what is going on.
14430                    if (adj > ProcessList.SERVICE_ADJ) {
14431                        app.adjType = "cch-started-ui-services";
14432                    }
14433                } else {
14434                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14435                        // This service has seen some activity within
14436                        // recent memory, so we will keep its process ahead
14437                        // of the background processes.
14438                        if (adj > ProcessList.SERVICE_ADJ) {
14439                            adj = ProcessList.SERVICE_ADJ;
14440                            app.adjType = "started-services";
14441                            app.cached = false;
14442                        }
14443                    }
14444                    // If we have let the service slide into the background
14445                    // state, still have some text describing what it is doing
14446                    // even though the service no longer has an impact.
14447                    if (adj > ProcessList.SERVICE_ADJ) {
14448                        app.adjType = "cch-started-services";
14449                    }
14450                }
14451                // Don't kill this process because it is doing work; it
14452                // has said it is doing work.
14453                app.keeping = true;
14454            }
14455            for (int conni = s.connections.size()-1;
14456                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14457                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14458                            || procState > ActivityManager.PROCESS_STATE_TOP);
14459                    conni--) {
14460                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14461                for (int i = 0;
14462                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14463                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14464                                || procState > ActivityManager.PROCESS_STATE_TOP);
14465                        i++) {
14466                    // XXX should compute this based on the max of
14467                    // all connected clients.
14468                    ConnectionRecord cr = clist.get(i);
14469                    if (cr.binding.client == app) {
14470                        // Binding to ourself is not interesting.
14471                        continue;
14472                    }
14473                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14474                        ProcessRecord client = cr.binding.client;
14475                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14476                                TOP_APP, doingAll, now);
14477                        int clientProcState = client.curProcState;
14478                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14479                            // If the other app is cached for any reason, for purposes here
14480                            // we are going to consider it empty.  The specific cached state
14481                            // doesn't propagate except under certain conditions.
14482                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14483                        }
14484                        String adjType = null;
14485                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14486                            // Not doing bind OOM management, so treat
14487                            // this guy more like a started service.
14488                            if (app.hasShownUi && app != mHomeProcess) {
14489                                // If this process has shown some UI, let it immediately
14490                                // go to the LRU list because it may be pretty heavy with
14491                                // UI stuff.  We'll tag it with a label just to help
14492                                // debug and understand what is going on.
14493                                if (adj > clientAdj) {
14494                                    adjType = "cch-bound-ui-services";
14495                                }
14496                                app.cached = false;
14497                                clientAdj = adj;
14498                                clientProcState = procState;
14499                            } else {
14500                                if (now >= (s.lastActivity
14501                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14502                                    // This service has not seen activity within
14503                                    // recent memory, so allow it to drop to the
14504                                    // LRU list if there is no other reason to keep
14505                                    // it around.  We'll also tag it with a label just
14506                                    // to help debug and undertand what is going on.
14507                                    if (adj > clientAdj) {
14508                                        adjType = "cch-bound-services";
14509                                    }
14510                                    clientAdj = adj;
14511                                }
14512                            }
14513                        }
14514                        if (adj > clientAdj) {
14515                            // If this process has recently shown UI, and
14516                            // the process that is binding to it is less
14517                            // important than being visible, then we don't
14518                            // care about the binding as much as we care
14519                            // about letting this process get into the LRU
14520                            // list to be killed and restarted if needed for
14521                            // memory.
14522                            if (app.hasShownUi && app != mHomeProcess
14523                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14524                                adjType = "cch-bound-ui-services";
14525                            } else {
14526                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14527                                        |Context.BIND_IMPORTANT)) != 0) {
14528                                    adj = clientAdj;
14529                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14530                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14531                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14532                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14533                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14534                                    adj = clientAdj;
14535                                } else {
14536                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14537                                        adj = ProcessList.VISIBLE_APP_ADJ;
14538                                    }
14539                                }
14540                                if (!client.cached) {
14541                                    app.cached = false;
14542                                }
14543                                if (client.keeping) {
14544                                    app.keeping = true;
14545                                }
14546                                adjType = "service";
14547                            }
14548                        }
14549                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14550                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14551                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14552                            }
14553                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14554                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14555                                    // Special handling of clients who are in the top state.
14556                                    // We *may* want to consider this process to be in the
14557                                    // top state as well, but only if there is not another
14558                                    // reason for it to be running.  Being on the top is a
14559                                    // special state, meaning you are specifically running
14560                                    // for the current top app.  If the process is already
14561                                    // running in the background for some other reason, it
14562                                    // is more important to continue considering it to be
14563                                    // in the background state.
14564                                    mayBeTop = true;
14565                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14566                                } else {
14567                                    // Special handling for above-top states (persistent
14568                                    // processes).  These should not bring the current process
14569                                    // into the top state, since they are not on top.  Instead
14570                                    // give them the best state after that.
14571                                    clientProcState =
14572                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14573                                }
14574                            }
14575                        } else {
14576                            if (clientProcState <
14577                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14578                                clientProcState =
14579                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14580                            }
14581                        }
14582                        if (procState > clientProcState) {
14583                            procState = clientProcState;
14584                        }
14585                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14586                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14587                            app.pendingUiClean = true;
14588                        }
14589                        if (adjType != null) {
14590                            app.adjType = adjType;
14591                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14592                                    .REASON_SERVICE_IN_USE;
14593                            app.adjSource = cr.binding.client;
14594                            app.adjSourceOom = clientAdj;
14595                            app.adjTarget = s.name;
14596                        }
14597                    }
14598                    final ActivityRecord a = cr.activity;
14599                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14600                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14601                                (a.visible || a.state == ActivityState.RESUMED
14602                                 || a.state == ActivityState.PAUSING)) {
14603                            adj = ProcessList.FOREGROUND_APP_ADJ;
14604                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14605                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14606                            }
14607                            app.cached = false;
14608                            app.adjType = "service";
14609                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14610                                    .REASON_SERVICE_IN_USE;
14611                            app.adjSource = a;
14612                            app.adjSourceOom = adj;
14613                            app.adjTarget = s.name;
14614                        }
14615                    }
14616                }
14617            }
14618        }
14619
14620        for (int provi = app.pubProviders.size()-1;
14621                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14622                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14623                        || procState > ActivityManager.PROCESS_STATE_TOP);
14624                provi--) {
14625            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14626            for (int i = cpr.connections.size()-1;
14627                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14628                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14629                            || procState > ActivityManager.PROCESS_STATE_TOP);
14630                    i--) {
14631                ContentProviderConnection conn = cpr.connections.get(i);
14632                ProcessRecord client = conn.client;
14633                if (client == app) {
14634                    // Being our own client is not interesting.
14635                    continue;
14636                }
14637                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14638                int clientProcState = client.curProcState;
14639                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14640                    // If the other app is cached for any reason, for purposes here
14641                    // we are going to consider it empty.
14642                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14643                }
14644                if (adj > clientAdj) {
14645                    if (app.hasShownUi && app != mHomeProcess
14646                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14647                        app.adjType = "cch-ui-provider";
14648                    } else {
14649                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14650                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14651                        app.adjType = "provider";
14652                    }
14653                    app.cached &= client.cached;
14654                    app.keeping |= client.keeping;
14655                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14656                            .REASON_PROVIDER_IN_USE;
14657                    app.adjSource = client;
14658                    app.adjSourceOom = clientAdj;
14659                    app.adjTarget = cpr.name;
14660                }
14661                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14662                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14663                        // Special handling of clients who are in the top state.
14664                        // We *may* want to consider this process to be in the
14665                        // top state as well, but only if there is not another
14666                        // reason for it to be running.  Being on the top is a
14667                        // special state, meaning you are specifically running
14668                        // for the current top app.  If the process is already
14669                        // running in the background for some other reason, it
14670                        // is more important to continue considering it to be
14671                        // in the background state.
14672                        mayBeTop = true;
14673                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14674                    } else {
14675                        // Special handling for above-top states (persistent
14676                        // processes).  These should not bring the current process
14677                        // into the top state, since they are not on top.  Instead
14678                        // give them the best state after that.
14679                        clientProcState =
14680                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14681                    }
14682                }
14683                if (procState > clientProcState) {
14684                    procState = clientProcState;
14685                }
14686                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14687                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14688                }
14689            }
14690            // If the provider has external (non-framework) process
14691            // dependencies, ensure that its adjustment is at least
14692            // FOREGROUND_APP_ADJ.
14693            if (cpr.hasExternalProcessHandles()) {
14694                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14695                    adj = ProcessList.FOREGROUND_APP_ADJ;
14696                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14697                    app.cached = false;
14698                    app.keeping = true;
14699                    app.adjType = "provider";
14700                    app.adjTarget = cpr.name;
14701                }
14702                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14703                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14704                }
14705            }
14706        }
14707
14708        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14709            // A client of one of our services or providers is in the top state.  We
14710            // *may* want to be in the top state, but not if we are already running in
14711            // the background for some other reason.  For the decision here, we are going
14712            // to pick out a few specific states that we want to remain in when a client
14713            // is top (states that tend to be longer-term) and otherwise allow it to go
14714            // to the top state.
14715            switch (procState) {
14716                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14717                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14718                case ActivityManager.PROCESS_STATE_SERVICE:
14719                    // These all are longer-term states, so pull them up to the top
14720                    // of the background states, but not all the way to the top state.
14721                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14722                    break;
14723                default:
14724                    // Otherwise, top is a better choice, so take it.
14725                    procState = ActivityManager.PROCESS_STATE_TOP;
14726                    break;
14727            }
14728        }
14729
14730        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14731            // This is a cached process, but with client activities.  Mark it so.
14732            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14733            app.adjType = "cch-client-act";
14734        }
14735
14736        if (adj == ProcessList.SERVICE_ADJ) {
14737            if (doingAll) {
14738                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14739                mNewNumServiceProcs++;
14740                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14741                if (!app.serviceb) {
14742                    // This service isn't far enough down on the LRU list to
14743                    // normally be a B service, but if we are low on RAM and it
14744                    // is large we want to force it down since we would prefer to
14745                    // keep launcher over it.
14746                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14747                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14748                        app.serviceHighRam = true;
14749                        app.serviceb = true;
14750                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14751                    } else {
14752                        mNewNumAServiceProcs++;
14753                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14754                    }
14755                } else {
14756                    app.serviceHighRam = false;
14757                }
14758            }
14759            if (app.serviceb) {
14760                adj = ProcessList.SERVICE_B_ADJ;
14761            }
14762        }
14763
14764        app.curRawAdj = adj;
14765
14766        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14767        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14768        if (adj > app.maxAdj) {
14769            adj = app.maxAdj;
14770            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14771                schedGroup = Process.THREAD_GROUP_DEFAULT;
14772            }
14773        }
14774        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14775            app.keeping = true;
14776        }
14777
14778        // Do final modification to adj.  Everything we do between here and applying
14779        // the final setAdj must be done in this function, because we will also use
14780        // it when computing the final cached adj later.  Note that we don't need to
14781        // worry about this for max adj above, since max adj will always be used to
14782        // keep it out of the cached vaues.
14783        adj = app.modifyRawOomAdj(adj);
14784
14785        app.curProcState = procState;
14786
14787        int importance = app.memImportance;
14788        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14789            app.curAdj = adj;
14790            app.curSchedGroup = schedGroup;
14791            if (!interesting) {
14792                // For this reporting, if there is not something explicitly
14793                // interesting in this process then we will push it to the
14794                // background importance.
14795                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14796            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14797                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14798            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14799                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14800            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14801                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14802            } else if (adj >= ProcessList.SERVICE_ADJ) {
14803                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14804            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14805                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14806            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14807                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14808            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14809                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14810            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14811                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14812            } else {
14813                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14814            }
14815        }
14816
14817        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14818        if (foregroundActivities != app.foregroundActivities) {
14819            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14820        }
14821        if (changes != 0) {
14822            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14823            app.memImportance = importance;
14824            app.foregroundActivities = foregroundActivities;
14825            int i = mPendingProcessChanges.size()-1;
14826            ProcessChangeItem item = null;
14827            while (i >= 0) {
14828                item = mPendingProcessChanges.get(i);
14829                if (item.pid == app.pid) {
14830                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14831                    break;
14832                }
14833                i--;
14834            }
14835            if (i < 0) {
14836                // No existing item in pending changes; need a new one.
14837                final int NA = mAvailProcessChanges.size();
14838                if (NA > 0) {
14839                    item = mAvailProcessChanges.remove(NA-1);
14840                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14841                } else {
14842                    item = new ProcessChangeItem();
14843                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14844                }
14845                item.changes = 0;
14846                item.pid = app.pid;
14847                item.uid = app.info.uid;
14848                if (mPendingProcessChanges.size() == 0) {
14849                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14850                            "*** Enqueueing dispatch processes changed!");
14851                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14852                }
14853                mPendingProcessChanges.add(item);
14854            }
14855            item.changes |= changes;
14856            item.importance = importance;
14857            item.foregroundActivities = foregroundActivities;
14858            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14859                    + Integer.toHexString(System.identityHashCode(item))
14860                    + " " + app.toShortString() + ": changes=" + item.changes
14861                    + " importance=" + item.importance
14862                    + " foreground=" + item.foregroundActivities
14863                    + " type=" + app.adjType + " source=" + app.adjSource
14864                    + " target=" + app.adjTarget);
14865        }
14866
14867        return app.curRawAdj;
14868    }
14869
14870    /**
14871     * Schedule PSS collection of a process.
14872     */
14873    void requestPssLocked(ProcessRecord proc, int procState) {
14874        if (mPendingPssProcesses.contains(proc)) {
14875            return;
14876        }
14877        if (mPendingPssProcesses.size() == 0) {
14878            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14879        }
14880        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14881        proc.pssProcState = procState;
14882        mPendingPssProcesses.add(proc);
14883    }
14884
14885    /**
14886     * Schedule PSS collection of all processes.
14887     */
14888    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14889        if (!always) {
14890            if (now < (mLastFullPssTime +
14891                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14892                return;
14893            }
14894        }
14895        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14896        mLastFullPssTime = now;
14897        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14898        mPendingPssProcesses.clear();
14899        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14900            ProcessRecord app = mLruProcesses.get(i);
14901            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14902                app.pssProcState = app.setProcState;
14903                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14904                        mSleeping, now);
14905                mPendingPssProcesses.add(app);
14906            }
14907        }
14908        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14909    }
14910
14911    /**
14912     * Ask a given process to GC right now.
14913     */
14914    final void performAppGcLocked(ProcessRecord app) {
14915        try {
14916            app.lastRequestedGc = SystemClock.uptimeMillis();
14917            if (app.thread != null) {
14918                if (app.reportLowMemory) {
14919                    app.reportLowMemory = false;
14920                    app.thread.scheduleLowMemory();
14921                } else {
14922                    app.thread.processInBackground();
14923                }
14924            }
14925        } catch (Exception e) {
14926            // whatever.
14927        }
14928    }
14929
14930    /**
14931     * Returns true if things are idle enough to perform GCs.
14932     */
14933    private final boolean canGcNowLocked() {
14934        boolean processingBroadcasts = false;
14935        for (BroadcastQueue q : mBroadcastQueues) {
14936            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14937                processingBroadcasts = true;
14938            }
14939        }
14940        return !processingBroadcasts
14941                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14942    }
14943
14944    /**
14945     * Perform GCs on all processes that are waiting for it, but only
14946     * if things are idle.
14947     */
14948    final void performAppGcsLocked() {
14949        final int N = mProcessesToGc.size();
14950        if (N <= 0) {
14951            return;
14952        }
14953        if (canGcNowLocked()) {
14954            while (mProcessesToGc.size() > 0) {
14955                ProcessRecord proc = mProcessesToGc.remove(0);
14956                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14957                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14958                            <= SystemClock.uptimeMillis()) {
14959                        // To avoid spamming the system, we will GC processes one
14960                        // at a time, waiting a few seconds between each.
14961                        performAppGcLocked(proc);
14962                        scheduleAppGcsLocked();
14963                        return;
14964                    } else {
14965                        // It hasn't been long enough since we last GCed this
14966                        // process...  put it in the list to wait for its time.
14967                        addProcessToGcListLocked(proc);
14968                        break;
14969                    }
14970                }
14971            }
14972
14973            scheduleAppGcsLocked();
14974        }
14975    }
14976
14977    /**
14978     * If all looks good, perform GCs on all processes waiting for them.
14979     */
14980    final void performAppGcsIfAppropriateLocked() {
14981        if (canGcNowLocked()) {
14982            performAppGcsLocked();
14983            return;
14984        }
14985        // Still not idle, wait some more.
14986        scheduleAppGcsLocked();
14987    }
14988
14989    /**
14990     * Schedule the execution of all pending app GCs.
14991     */
14992    final void scheduleAppGcsLocked() {
14993        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
14994
14995        if (mProcessesToGc.size() > 0) {
14996            // Schedule a GC for the time to the next process.
14997            ProcessRecord proc = mProcessesToGc.get(0);
14998            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14999
15000            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15001            long now = SystemClock.uptimeMillis();
15002            if (when < (now+GC_TIMEOUT)) {
15003                when = now + GC_TIMEOUT;
15004            }
15005            mHandler.sendMessageAtTime(msg, when);
15006        }
15007    }
15008
15009    /**
15010     * Add a process to the array of processes waiting to be GCed.  Keeps the
15011     * list in sorted order by the last GC time.  The process can't already be
15012     * on the list.
15013     */
15014    final void addProcessToGcListLocked(ProcessRecord proc) {
15015        boolean added = false;
15016        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15017            if (mProcessesToGc.get(i).lastRequestedGc <
15018                    proc.lastRequestedGc) {
15019                added = true;
15020                mProcessesToGc.add(i+1, proc);
15021                break;
15022            }
15023        }
15024        if (!added) {
15025            mProcessesToGc.add(0, proc);
15026        }
15027    }
15028
15029    /**
15030     * Set up to ask a process to GC itself.  This will either do it
15031     * immediately, or put it on the list of processes to gc the next
15032     * time things are idle.
15033     */
15034    final void scheduleAppGcLocked(ProcessRecord app) {
15035        long now = SystemClock.uptimeMillis();
15036        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15037            return;
15038        }
15039        if (!mProcessesToGc.contains(app)) {
15040            addProcessToGcListLocked(app);
15041            scheduleAppGcsLocked();
15042        }
15043    }
15044
15045    final void checkExcessivePowerUsageLocked(boolean doKills) {
15046        updateCpuStatsNow();
15047
15048        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15049        boolean doWakeKills = doKills;
15050        boolean doCpuKills = doKills;
15051        if (mLastPowerCheckRealtime == 0) {
15052            doWakeKills = false;
15053        }
15054        if (mLastPowerCheckUptime == 0) {
15055            doCpuKills = false;
15056        }
15057        if (stats.isScreenOn()) {
15058            doWakeKills = false;
15059        }
15060        final long curRealtime = SystemClock.elapsedRealtime();
15061        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15062        final long curUptime = SystemClock.uptimeMillis();
15063        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15064        mLastPowerCheckRealtime = curRealtime;
15065        mLastPowerCheckUptime = curUptime;
15066        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15067            doWakeKills = false;
15068        }
15069        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15070            doCpuKills = false;
15071        }
15072        int i = mLruProcesses.size();
15073        while (i > 0) {
15074            i--;
15075            ProcessRecord app = mLruProcesses.get(i);
15076            if (!app.keeping) {
15077                long wtime;
15078                synchronized (stats) {
15079                    wtime = stats.getProcessWakeTime(app.info.uid,
15080                            app.pid, curRealtime);
15081                }
15082                long wtimeUsed = wtime - app.lastWakeTime;
15083                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15084                if (DEBUG_POWER) {
15085                    StringBuilder sb = new StringBuilder(128);
15086                    sb.append("Wake for ");
15087                    app.toShortString(sb);
15088                    sb.append(": over ");
15089                    TimeUtils.formatDuration(realtimeSince, sb);
15090                    sb.append(" used ");
15091                    TimeUtils.formatDuration(wtimeUsed, sb);
15092                    sb.append(" (");
15093                    sb.append((wtimeUsed*100)/realtimeSince);
15094                    sb.append("%)");
15095                    Slog.i(TAG, sb.toString());
15096                    sb.setLength(0);
15097                    sb.append("CPU for ");
15098                    app.toShortString(sb);
15099                    sb.append(": over ");
15100                    TimeUtils.formatDuration(uptimeSince, sb);
15101                    sb.append(" used ");
15102                    TimeUtils.formatDuration(cputimeUsed, sb);
15103                    sb.append(" (");
15104                    sb.append((cputimeUsed*100)/uptimeSince);
15105                    sb.append("%)");
15106                    Slog.i(TAG, sb.toString());
15107                }
15108                // If a process has held a wake lock for more
15109                // than 50% of the time during this period,
15110                // that sounds bad.  Kill!
15111                if (doWakeKills && realtimeSince > 0
15112                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15113                    synchronized (stats) {
15114                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15115                                realtimeSince, wtimeUsed);
15116                    }
15117                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15118                            + " during " + realtimeSince);
15119                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15120                } else if (doCpuKills && uptimeSince > 0
15121                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15122                    synchronized (stats) {
15123                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15124                                uptimeSince, cputimeUsed);
15125                    }
15126                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15127                            + " during " + uptimeSince);
15128                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15129                } else {
15130                    app.lastWakeTime = wtime;
15131                    app.lastCpuTime = app.curCpuTime;
15132                }
15133            }
15134        }
15135    }
15136
15137    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15138            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15139        boolean success = true;
15140
15141        if (app.curRawAdj != app.setRawAdj) {
15142            if (wasKeeping && !app.keeping) {
15143                // This app is no longer something we want to keep.  Note
15144                // its current wake lock time to later know to kill it if
15145                // it is not behaving well.
15146                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15147                synchronized (stats) {
15148                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15149                            app.pid, SystemClock.elapsedRealtime());
15150                }
15151                app.lastCpuTime = app.curCpuTime;
15152            }
15153
15154            app.setRawAdj = app.curRawAdj;
15155        }
15156
15157        if (app.curAdj != app.setAdj) {
15158            ProcessList.setOomAdj(app.pid, app.curAdj);
15159            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15160                TAG, "Set " + app.pid + " " + app.processName +
15161                " adj " + app.curAdj + ": " + app.adjType);
15162            app.setAdj = app.curAdj;
15163        }
15164
15165        if (app.setSchedGroup != app.curSchedGroup) {
15166            app.setSchedGroup = app.curSchedGroup;
15167            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15168                    "Setting process group of " + app.processName
15169                    + " to " + app.curSchedGroup);
15170            if (app.waitingToKill != null &&
15171                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15172                killUnneededProcessLocked(app, app.waitingToKill);
15173                success = false;
15174            } else {
15175                if (true) {
15176                    long oldId = Binder.clearCallingIdentity();
15177                    try {
15178                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15179                    } catch (Exception e) {
15180                        Slog.w(TAG, "Failed setting process group of " + app.pid
15181                                + " to " + app.curSchedGroup);
15182                        e.printStackTrace();
15183                    } finally {
15184                        Binder.restoreCallingIdentity(oldId);
15185                    }
15186                } else {
15187                    if (app.thread != null) {
15188                        try {
15189                            app.thread.setSchedulingGroup(app.curSchedGroup);
15190                        } catch (RemoteException e) {
15191                        }
15192                    }
15193                }
15194                Process.setSwappiness(app.pid,
15195                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15196            }
15197        }
15198        if (app.repProcState != app.curProcState) {
15199            app.repProcState = app.curProcState;
15200            if (!reportingProcessState && app.thread != null) {
15201                try {
15202                    if (false) {
15203                        //RuntimeException h = new RuntimeException("here");
15204                        Slog.i(TAG, "Sending new process state " + app.repProcState
15205                                + " to " + app /*, h*/);
15206                    }
15207                    app.thread.setProcessState(app.repProcState);
15208                } catch (RemoteException e) {
15209                }
15210            }
15211        }
15212        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15213                app.setProcState)) {
15214            app.lastStateTime = now;
15215            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15216                    mSleeping, now);
15217            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15218                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15219                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15220                    + (app.nextPssTime-now) + ": " + app);
15221        } else {
15222            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15223                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15224                requestPssLocked(app, app.setProcState);
15225                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15226                        mSleeping, now);
15227            } else if (false && DEBUG_PSS) {
15228                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15229            }
15230        }
15231        if (app.setProcState != app.curProcState) {
15232            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15233                    "Proc state change of " + app.processName
15234                    + " to " + app.curProcState);
15235            app.setProcState = app.curProcState;
15236            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15237                app.notCachedSinceIdle = false;
15238            }
15239            if (!doingAll) {
15240                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15241            } else {
15242                app.procStateChanged = true;
15243            }
15244        }
15245        return success;
15246    }
15247
15248    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15249        if (proc.thread != null && proc.baseProcessTracker != null) {
15250            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15251        }
15252    }
15253
15254    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15255            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15256        if (app.thread == null) {
15257            return false;
15258        }
15259
15260        final boolean wasKeeping = app.keeping;
15261
15262        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15263
15264        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15265                reportingProcessState, now);
15266    }
15267
15268    private final ActivityRecord resumedAppLocked() {
15269        return mStackSupervisor.resumedAppLocked();
15270    }
15271
15272    final boolean updateOomAdjLocked(ProcessRecord app) {
15273        return updateOomAdjLocked(app, false);
15274    }
15275
15276    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15277        final ActivityRecord TOP_ACT = resumedAppLocked();
15278        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15279        final boolean wasCached = app.cached;
15280
15281        mAdjSeq++;
15282
15283        // This is the desired cached adjusment we want to tell it to use.
15284        // If our app is currently cached, we know it, and that is it.  Otherwise,
15285        // we don't know it yet, and it needs to now be cached we will then
15286        // need to do a complete oom adj.
15287        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15288                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15289        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15290                SystemClock.uptimeMillis());
15291        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15292            // Changed to/from cached state, so apps after it in the LRU
15293            // list may also be changed.
15294            updateOomAdjLocked();
15295        }
15296        return success;
15297    }
15298
15299    final void updateOomAdjLocked() {
15300        final ActivityRecord TOP_ACT = resumedAppLocked();
15301        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15302        final long now = SystemClock.uptimeMillis();
15303        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15304        final int N = mLruProcesses.size();
15305
15306        if (false) {
15307            RuntimeException e = new RuntimeException();
15308            e.fillInStackTrace();
15309            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15310        }
15311
15312        mAdjSeq++;
15313        mNewNumServiceProcs = 0;
15314        mNewNumAServiceProcs = 0;
15315
15316        final int emptyProcessLimit;
15317        final int cachedProcessLimit;
15318        if (mProcessLimit <= 0) {
15319            emptyProcessLimit = cachedProcessLimit = 0;
15320        } else if (mProcessLimit == 1) {
15321            emptyProcessLimit = 1;
15322            cachedProcessLimit = 0;
15323        } else {
15324            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15325            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15326        }
15327
15328        // Let's determine how many processes we have running vs.
15329        // how many slots we have for background processes; we may want
15330        // to put multiple processes in a slot of there are enough of
15331        // them.
15332        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15333                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15334        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15335        if (numEmptyProcs > cachedProcessLimit) {
15336            // If there are more empty processes than our limit on cached
15337            // processes, then use the cached process limit for the factor.
15338            // This ensures that the really old empty processes get pushed
15339            // down to the bottom, so if we are running low on memory we will
15340            // have a better chance at keeping around more cached processes
15341            // instead of a gazillion empty processes.
15342            numEmptyProcs = cachedProcessLimit;
15343        }
15344        int emptyFactor = numEmptyProcs/numSlots;
15345        if (emptyFactor < 1) emptyFactor = 1;
15346        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15347        if (cachedFactor < 1) cachedFactor = 1;
15348        int stepCached = 0;
15349        int stepEmpty = 0;
15350        int numCached = 0;
15351        int numEmpty = 0;
15352        int numTrimming = 0;
15353
15354        mNumNonCachedProcs = 0;
15355        mNumCachedHiddenProcs = 0;
15356
15357        // First update the OOM adjustment for each of the
15358        // application processes based on their current state.
15359        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15360        int nextCachedAdj = curCachedAdj+1;
15361        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15362        int nextEmptyAdj = curEmptyAdj+2;
15363        for (int i=N-1; i>=0; i--) {
15364            ProcessRecord app = mLruProcesses.get(i);
15365            if (!app.killedByAm && app.thread != null) {
15366                app.procStateChanged = false;
15367                final boolean wasKeeping = app.keeping;
15368                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15369
15370                // If we haven't yet assigned the final cached adj
15371                // to the process, do that now.
15372                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15373                    switch (app.curProcState) {
15374                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15375                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15376                            // This process is a cached process holding activities...
15377                            // assign it the next cached value for that type, and then
15378                            // step that cached level.
15379                            app.curRawAdj = curCachedAdj;
15380                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15381                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15382                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15383                                    + ")");
15384                            if (curCachedAdj != nextCachedAdj) {
15385                                stepCached++;
15386                                if (stepCached >= cachedFactor) {
15387                                    stepCached = 0;
15388                                    curCachedAdj = nextCachedAdj;
15389                                    nextCachedAdj += 2;
15390                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15391                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15392                                    }
15393                                }
15394                            }
15395                            break;
15396                        default:
15397                            // For everything else, assign next empty cached process
15398                            // level and bump that up.  Note that this means that
15399                            // long-running services that have dropped down to the
15400                            // cached level will be treated as empty (since their process
15401                            // state is still as a service), which is what we want.
15402                            app.curRawAdj = curEmptyAdj;
15403                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15404                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15405                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15406                                    + ")");
15407                            if (curEmptyAdj != nextEmptyAdj) {
15408                                stepEmpty++;
15409                                if (stepEmpty >= emptyFactor) {
15410                                    stepEmpty = 0;
15411                                    curEmptyAdj = nextEmptyAdj;
15412                                    nextEmptyAdj += 2;
15413                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15414                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15415                                    }
15416                                }
15417                            }
15418                            break;
15419                    }
15420                }
15421
15422                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15423
15424                // Count the number of process types.
15425                switch (app.curProcState) {
15426                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15427                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15428                        mNumCachedHiddenProcs++;
15429                        numCached++;
15430                        if (numCached > cachedProcessLimit) {
15431                            killUnneededProcessLocked(app, "cached #" + numCached);
15432                        }
15433                        break;
15434                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15435                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15436                                && app.lastActivityTime < oldTime) {
15437                            killUnneededProcessLocked(app, "empty for "
15438                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15439                                    / 1000) + "s");
15440                        } else {
15441                            numEmpty++;
15442                            if (numEmpty > emptyProcessLimit) {
15443                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15444                            }
15445                        }
15446                        break;
15447                    default:
15448                        mNumNonCachedProcs++;
15449                        break;
15450                }
15451
15452                if (app.isolated && app.services.size() <= 0) {
15453                    // If this is an isolated process, and there are no
15454                    // services running in it, then the process is no longer
15455                    // needed.  We agressively kill these because we can by
15456                    // definition not re-use the same process again, and it is
15457                    // good to avoid having whatever code was running in them
15458                    // left sitting around after no longer needed.
15459                    killUnneededProcessLocked(app, "isolated not needed");
15460                }
15461
15462                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15463                        && !app.killedByAm) {
15464                    numTrimming++;
15465                }
15466            }
15467        }
15468
15469        mNumServiceProcs = mNewNumServiceProcs;
15470
15471        // Now determine the memory trimming level of background processes.
15472        // Unfortunately we need to start at the back of the list to do this
15473        // properly.  We only do this if the number of background apps we
15474        // are managing to keep around is less than half the maximum we desire;
15475        // if we are keeping a good number around, we'll let them use whatever
15476        // memory they want.
15477        final int numCachedAndEmpty = numCached + numEmpty;
15478        int memFactor;
15479        if (numCached <= ProcessList.TRIM_CACHED_APPS
15480                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15481            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15482                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15483            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15484                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15485            } else {
15486                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15487            }
15488        } else {
15489            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15490        }
15491        // We always allow the memory level to go up (better).  We only allow it to go
15492        // down if we are in a state where that is allowed, *and* the total number of processes
15493        // has gone down since last time.
15494        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15495                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15496                + " last=" + mLastNumProcesses);
15497        if (memFactor > mLastMemoryLevel) {
15498            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15499                memFactor = mLastMemoryLevel;
15500                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15501            }
15502        }
15503        mLastMemoryLevel = memFactor;
15504        mLastNumProcesses = mLruProcesses.size();
15505        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15506        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15507        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15508            if (mLowRamStartTime == 0) {
15509                mLowRamStartTime = now;
15510            }
15511            int step = 0;
15512            int fgTrimLevel;
15513            switch (memFactor) {
15514                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15515                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15516                    break;
15517                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15518                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15519                    break;
15520                default:
15521                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15522                    break;
15523            }
15524            int factor = numTrimming/3;
15525            int minFactor = 2;
15526            if (mHomeProcess != null) minFactor++;
15527            if (mPreviousProcess != null) minFactor++;
15528            if (factor < minFactor) factor = minFactor;
15529            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15530            for (int i=N-1; i>=0; i--) {
15531                ProcessRecord app = mLruProcesses.get(i);
15532                if (allChanged || app.procStateChanged) {
15533                    setProcessTrackerState(app, trackerMemFactor, now);
15534                    app.procStateChanged = false;
15535                }
15536                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15537                        && !app.killedByAm) {
15538                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15539                        try {
15540                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15541                                    "Trimming memory of " + app.processName
15542                                    + " to " + curLevel);
15543                            app.thread.scheduleTrimMemory(curLevel);
15544                        } catch (RemoteException e) {
15545                        }
15546                        if (false) {
15547                            // For now we won't do this; our memory trimming seems
15548                            // to be good enough at this point that destroying
15549                            // activities causes more harm than good.
15550                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15551                                    && app != mHomeProcess && app != mPreviousProcess) {
15552                                // Need to do this on its own message because the stack may not
15553                                // be in a consistent state at this point.
15554                                // For these apps we will also finish their activities
15555                                // to help them free memory.
15556                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15557                            }
15558                        }
15559                    }
15560                    app.trimMemoryLevel = curLevel;
15561                    step++;
15562                    if (step >= factor) {
15563                        step = 0;
15564                        switch (curLevel) {
15565                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15566                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15567                                break;
15568                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15569                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15570                                break;
15571                        }
15572                    }
15573                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15574                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15575                            && app.thread != null) {
15576                        try {
15577                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15578                                    "Trimming memory of heavy-weight " + app.processName
15579                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15580                            app.thread.scheduleTrimMemory(
15581                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15582                        } catch (RemoteException e) {
15583                        }
15584                    }
15585                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15586                } else {
15587                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15588                            || app.systemNoUi) && app.pendingUiClean) {
15589                        // If this application is now in the background and it
15590                        // had done UI, then give it the special trim level to
15591                        // have it free UI resources.
15592                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15593                        if (app.trimMemoryLevel < level && app.thread != null) {
15594                            try {
15595                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15596                                        "Trimming memory of bg-ui " + app.processName
15597                                        + " to " + level);
15598                                app.thread.scheduleTrimMemory(level);
15599                            } catch (RemoteException e) {
15600                            }
15601                        }
15602                        app.pendingUiClean = false;
15603                    }
15604                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15605                        try {
15606                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15607                                    "Trimming memory of fg " + app.processName
15608                                    + " to " + fgTrimLevel);
15609                            app.thread.scheduleTrimMemory(fgTrimLevel);
15610                        } catch (RemoteException e) {
15611                        }
15612                    }
15613                    app.trimMemoryLevel = fgTrimLevel;
15614                }
15615            }
15616        } else {
15617            if (mLowRamStartTime != 0) {
15618                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15619                mLowRamStartTime = 0;
15620            }
15621            for (int i=N-1; i>=0; i--) {
15622                ProcessRecord app = mLruProcesses.get(i);
15623                if (allChanged || app.procStateChanged) {
15624                    setProcessTrackerState(app, trackerMemFactor, now);
15625                    app.procStateChanged = false;
15626                }
15627                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15628                        || app.systemNoUi) && app.pendingUiClean) {
15629                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15630                            && app.thread != null) {
15631                        try {
15632                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15633                                    "Trimming memory of ui hidden " + app.processName
15634                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15635                            app.thread.scheduleTrimMemory(
15636                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15637                        } catch (RemoteException e) {
15638                        }
15639                    }
15640                    app.pendingUiClean = false;
15641                }
15642                app.trimMemoryLevel = 0;
15643            }
15644        }
15645
15646        if (mAlwaysFinishActivities) {
15647            // Need to do this on its own message because the stack may not
15648            // be in a consistent state at this point.
15649            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15650        }
15651
15652        if (allChanged) {
15653            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15654        }
15655
15656        if (mProcessStats.shouldWriteNowLocked(now)) {
15657            mHandler.post(new Runnable() {
15658                @Override public void run() {
15659                    synchronized (ActivityManagerService.this) {
15660                        mProcessStats.writeStateAsyncLocked();
15661                    }
15662                }
15663            });
15664        }
15665
15666        if (DEBUG_OOM_ADJ) {
15667            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15668        }
15669    }
15670
15671    final void trimApplications() {
15672        synchronized (this) {
15673            int i;
15674
15675            // First remove any unused application processes whose package
15676            // has been removed.
15677            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15678                final ProcessRecord app = mRemovedProcesses.get(i);
15679                if (app.activities.size() == 0
15680                        && app.curReceiver == null && app.services.size() == 0) {
15681                    Slog.i(
15682                        TAG, "Exiting empty application process "
15683                        + app.processName + " ("
15684                        + (app.thread != null ? app.thread.asBinder() : null)
15685                        + ")\n");
15686                    if (app.pid > 0 && app.pid != MY_PID) {
15687                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15688                                app.processName, app.setAdj, "empty");
15689                        app.killedByAm = true;
15690                        Process.killProcessQuiet(app.pid);
15691                    } else {
15692                        try {
15693                            app.thread.scheduleExit();
15694                        } catch (Exception e) {
15695                            // Ignore exceptions.
15696                        }
15697                    }
15698                    cleanUpApplicationRecordLocked(app, false, true, -1);
15699                    mRemovedProcesses.remove(i);
15700
15701                    if (app.persistent) {
15702                        if (app.persistent) {
15703                            addAppLocked(app.info, false);
15704                        }
15705                    }
15706                }
15707            }
15708
15709            // Now update the oom adj for all processes.
15710            updateOomAdjLocked();
15711        }
15712    }
15713
15714    /** This method sends the specified signal to each of the persistent apps */
15715    public void signalPersistentProcesses(int sig) throws RemoteException {
15716        if (sig != Process.SIGNAL_USR1) {
15717            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15718        }
15719
15720        synchronized (this) {
15721            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15722                    != PackageManager.PERMISSION_GRANTED) {
15723                throw new SecurityException("Requires permission "
15724                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15725            }
15726
15727            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15728                ProcessRecord r = mLruProcesses.get(i);
15729                if (r.thread != null && r.persistent) {
15730                    Process.sendSignal(r.pid, sig);
15731                }
15732            }
15733        }
15734    }
15735
15736    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15737        if (proc == null || proc == mProfileProc) {
15738            proc = mProfileProc;
15739            path = mProfileFile;
15740            profileType = mProfileType;
15741            clearProfilerLocked();
15742        }
15743        if (proc == null) {
15744            return;
15745        }
15746        try {
15747            proc.thread.profilerControl(false, path, null, profileType);
15748        } catch (RemoteException e) {
15749            throw new IllegalStateException("Process disappeared");
15750        }
15751    }
15752
15753    private void clearProfilerLocked() {
15754        if (mProfileFd != null) {
15755            try {
15756                mProfileFd.close();
15757            } catch (IOException e) {
15758            }
15759        }
15760        mProfileApp = null;
15761        mProfileProc = null;
15762        mProfileFile = null;
15763        mProfileType = 0;
15764        mAutoStopProfiler = false;
15765    }
15766
15767    public boolean profileControl(String process, int userId, boolean start,
15768            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15769
15770        try {
15771            synchronized (this) {
15772                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15773                // its own permission.
15774                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15775                        != PackageManager.PERMISSION_GRANTED) {
15776                    throw new SecurityException("Requires permission "
15777                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15778                }
15779
15780                if (start && fd == null) {
15781                    throw new IllegalArgumentException("null fd");
15782                }
15783
15784                ProcessRecord proc = null;
15785                if (process != null) {
15786                    proc = findProcessLocked(process, userId, "profileControl");
15787                }
15788
15789                if (start && (proc == null || proc.thread == null)) {
15790                    throw new IllegalArgumentException("Unknown process: " + process);
15791                }
15792
15793                if (start) {
15794                    stopProfilerLocked(null, null, 0);
15795                    setProfileApp(proc.info, proc.processName, path, fd, false);
15796                    mProfileProc = proc;
15797                    mProfileType = profileType;
15798                    try {
15799                        fd = fd.dup();
15800                    } catch (IOException e) {
15801                        fd = null;
15802                    }
15803                    proc.thread.profilerControl(start, path, fd, profileType);
15804                    fd = null;
15805                    mProfileFd = null;
15806                } else {
15807                    stopProfilerLocked(proc, path, profileType);
15808                    if (fd != null) {
15809                        try {
15810                            fd.close();
15811                        } catch (IOException e) {
15812                        }
15813                    }
15814                }
15815
15816                return true;
15817            }
15818        } catch (RemoteException e) {
15819            throw new IllegalStateException("Process disappeared");
15820        } finally {
15821            if (fd != null) {
15822                try {
15823                    fd.close();
15824                } catch (IOException e) {
15825                }
15826            }
15827        }
15828    }
15829
15830    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15831        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15832                userId, true, true, callName, null);
15833        ProcessRecord proc = null;
15834        try {
15835            int pid = Integer.parseInt(process);
15836            synchronized (mPidsSelfLocked) {
15837                proc = mPidsSelfLocked.get(pid);
15838            }
15839        } catch (NumberFormatException e) {
15840        }
15841
15842        if (proc == null) {
15843            ArrayMap<String, SparseArray<ProcessRecord>> all
15844                    = mProcessNames.getMap();
15845            SparseArray<ProcessRecord> procs = all.get(process);
15846            if (procs != null && procs.size() > 0) {
15847                proc = procs.valueAt(0);
15848                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15849                    for (int i=1; i<procs.size(); i++) {
15850                        ProcessRecord thisProc = procs.valueAt(i);
15851                        if (thisProc.userId == userId) {
15852                            proc = thisProc;
15853                            break;
15854                        }
15855                    }
15856                }
15857            }
15858        }
15859
15860        return proc;
15861    }
15862
15863    public boolean dumpHeap(String process, int userId, boolean managed,
15864            String path, ParcelFileDescriptor fd) throws RemoteException {
15865
15866        try {
15867            synchronized (this) {
15868                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15869                // its own permission (same as profileControl).
15870                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15871                        != PackageManager.PERMISSION_GRANTED) {
15872                    throw new SecurityException("Requires permission "
15873                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15874                }
15875
15876                if (fd == null) {
15877                    throw new IllegalArgumentException("null fd");
15878                }
15879
15880                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15881                if (proc == null || proc.thread == null) {
15882                    throw new IllegalArgumentException("Unknown process: " + process);
15883                }
15884
15885                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15886                if (!isDebuggable) {
15887                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15888                        throw new SecurityException("Process not debuggable: " + proc);
15889                    }
15890                }
15891
15892                proc.thread.dumpHeap(managed, path, fd);
15893                fd = null;
15894                return true;
15895            }
15896        } catch (RemoteException e) {
15897            throw new IllegalStateException("Process disappeared");
15898        } finally {
15899            if (fd != null) {
15900                try {
15901                    fd.close();
15902                } catch (IOException e) {
15903                }
15904            }
15905        }
15906    }
15907
15908    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15909    public void monitor() {
15910        synchronized (this) { }
15911    }
15912
15913    void onCoreSettingsChange(Bundle settings) {
15914        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15915            ProcessRecord processRecord = mLruProcesses.get(i);
15916            try {
15917                if (processRecord.thread != null) {
15918                    processRecord.thread.setCoreSettings(settings);
15919                }
15920            } catch (RemoteException re) {
15921                /* ignore */
15922            }
15923        }
15924    }
15925
15926    // Multi-user methods
15927
15928    @Override
15929    public boolean switchUser(final int userId) {
15930        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15931                != PackageManager.PERMISSION_GRANTED) {
15932            String msg = "Permission Denial: switchUser() from pid="
15933                    + Binder.getCallingPid()
15934                    + ", uid=" + Binder.getCallingUid()
15935                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15936            Slog.w(TAG, msg);
15937            throw new SecurityException(msg);
15938        }
15939
15940        final long ident = Binder.clearCallingIdentity();
15941        try {
15942            synchronized (this) {
15943                final int oldUserId = mCurrentUserId;
15944                if (oldUserId == userId) {
15945                    return true;
15946                }
15947
15948                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15949                if (userInfo == null) {
15950                    Slog.w(TAG, "No user info for user #" + userId);
15951                    return false;
15952                }
15953
15954                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15955                        R.anim.screen_user_enter);
15956
15957                boolean needStart = false;
15958
15959                // If the user we are switching to is not currently started, then
15960                // we need to start it now.
15961                if (mStartedUsers.get(userId) == null) {
15962                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
15963                    updateStartedUserArrayLocked();
15964                    needStart = true;
15965                }
15966
15967                mCurrentUserId = userId;
15968                final Integer userIdInt = Integer.valueOf(userId);
15969                mUserLru.remove(userIdInt);
15970                mUserLru.add(userIdInt);
15971
15972                mWindowManager.setCurrentUser(userId);
15973
15974                // Once the internal notion of the active user has switched, we lock the device
15975                // with the option to show the user switcher on the keyguard.
15976                mWindowManager.lockNow(null);
15977
15978                final UserStartedState uss = mStartedUsers.get(userId);
15979
15980                // Make sure user is in the started state.  If it is currently
15981                // stopping, we need to knock that off.
15982                if (uss.mState == UserStartedState.STATE_STOPPING) {
15983                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
15984                    // so we can just fairly silently bring the user back from
15985                    // the almost-dead.
15986                    uss.mState = UserStartedState.STATE_RUNNING;
15987                    updateStartedUserArrayLocked();
15988                    needStart = true;
15989                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
15990                    // This means ACTION_SHUTDOWN has been sent, so we will
15991                    // need to treat this as a new boot of the user.
15992                    uss.mState = UserStartedState.STATE_BOOTING;
15993                    updateStartedUserArrayLocked();
15994                    needStart = true;
15995                }
15996
15997                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
15998                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
15999                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16000                        oldUserId, userId, uss));
16001                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16002                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16003                if (needStart) {
16004                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16005                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16006                            | Intent.FLAG_RECEIVER_FOREGROUND);
16007                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16008                    broadcastIntentLocked(null, null, intent,
16009                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16010                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16011                }
16012
16013                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16014                    if (userId != 0) {
16015                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16016                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16017                        broadcastIntentLocked(null, null, intent, null,
16018                                new IIntentReceiver.Stub() {
16019                                    public void performReceive(Intent intent, int resultCode,
16020                                            String data, Bundle extras, boolean ordered,
16021                                            boolean sticky, int sendingUser) {
16022                                        userInitialized(uss, userId);
16023                                    }
16024                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16025                                true, false, MY_PID, Process.SYSTEM_UID,
16026                                userId);
16027                        uss.initializing = true;
16028                    } else {
16029                        getUserManagerLocked().makeInitialized(userInfo.id);
16030                    }
16031                }
16032
16033                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16034                if (homeInFront) {
16035                    startHomeActivityLocked(userId);
16036                } else {
16037                    mStackSupervisor.resumeTopActivitiesLocked();
16038                }
16039
16040                EventLogTags.writeAmSwitchUser(userId);
16041                getUserManagerLocked().userForeground(userId);
16042                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16043                if (needStart) {
16044                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16045                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16046                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16047                    broadcastIntentLocked(null, null, intent,
16048                            null, new IIntentReceiver.Stub() {
16049                                @Override
16050                                public void performReceive(Intent intent, int resultCode, String data,
16051                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16052                                        throws RemoteException {
16053                                }
16054                            }, 0, null, null,
16055                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16056                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16057                }
16058            }
16059        } finally {
16060            Binder.restoreCallingIdentity(ident);
16061        }
16062
16063        return true;
16064    }
16065
16066    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16067        long ident = Binder.clearCallingIdentity();
16068        try {
16069            Intent intent;
16070            if (oldUserId >= 0) {
16071                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16072                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16073                        | Intent.FLAG_RECEIVER_FOREGROUND);
16074                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16075                broadcastIntentLocked(null, null, intent,
16076                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16077                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16078            }
16079            if (newUserId >= 0) {
16080                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16081                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16082                        | Intent.FLAG_RECEIVER_FOREGROUND);
16083                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16084                broadcastIntentLocked(null, null, intent,
16085                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16086                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16087                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16088                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16089                        | Intent.FLAG_RECEIVER_FOREGROUND);
16090                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16091                broadcastIntentLocked(null, null, intent,
16092                        null, null, 0, null, null,
16093                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16094                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16095            }
16096        } finally {
16097            Binder.restoreCallingIdentity(ident);
16098        }
16099    }
16100
16101    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16102            final int newUserId) {
16103        final int N = mUserSwitchObservers.beginBroadcast();
16104        if (N > 0) {
16105            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16106                int mCount = 0;
16107                @Override
16108                public void sendResult(Bundle data) throws RemoteException {
16109                    synchronized (ActivityManagerService.this) {
16110                        if (mCurUserSwitchCallback == this) {
16111                            mCount++;
16112                            if (mCount == N) {
16113                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16114                            }
16115                        }
16116                    }
16117                }
16118            };
16119            synchronized (this) {
16120                uss.switching = true;
16121                mCurUserSwitchCallback = callback;
16122            }
16123            for (int i=0; i<N; i++) {
16124                try {
16125                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16126                            newUserId, callback);
16127                } catch (RemoteException e) {
16128                }
16129            }
16130        } else {
16131            synchronized (this) {
16132                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16133            }
16134        }
16135        mUserSwitchObservers.finishBroadcast();
16136    }
16137
16138    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16139        synchronized (this) {
16140            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16141            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16142        }
16143    }
16144
16145    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16146        mCurUserSwitchCallback = null;
16147        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16148        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16149                oldUserId, newUserId, uss));
16150    }
16151
16152    void userInitialized(UserStartedState uss, int newUserId) {
16153        completeSwitchAndInitalize(uss, newUserId, true, false);
16154    }
16155
16156    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16157        completeSwitchAndInitalize(uss, newUserId, false, true);
16158    }
16159
16160    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16161            boolean clearInitializing, boolean clearSwitching) {
16162        boolean unfrozen = false;
16163        synchronized (this) {
16164            if (clearInitializing) {
16165                uss.initializing = false;
16166                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16167            }
16168            if (clearSwitching) {
16169                uss.switching = false;
16170            }
16171            if (!uss.switching && !uss.initializing) {
16172                mWindowManager.stopFreezingScreen();
16173                unfrozen = true;
16174            }
16175        }
16176        if (unfrozen) {
16177            final int N = mUserSwitchObservers.beginBroadcast();
16178            for (int i=0; i<N; i++) {
16179                try {
16180                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16181                } catch (RemoteException e) {
16182                }
16183            }
16184            mUserSwitchObservers.finishBroadcast();
16185        }
16186    }
16187
16188    void finishUserSwitch(UserStartedState uss) {
16189        synchronized (this) {
16190            if (uss.mState == UserStartedState.STATE_BOOTING
16191                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16192                uss.mState = UserStartedState.STATE_RUNNING;
16193                final int userId = uss.mHandle.getIdentifier();
16194                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16195                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16196                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16197                broadcastIntentLocked(null, null, intent,
16198                        null, null, 0, null, null,
16199                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16200                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16201            }
16202            int num = mUserLru.size();
16203            int i = 0;
16204            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16205                Integer oldUserId = mUserLru.get(i);
16206                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16207                if (oldUss == null) {
16208                    // Shouldn't happen, but be sane if it does.
16209                    mUserLru.remove(i);
16210                    num--;
16211                    continue;
16212                }
16213                if (oldUss.mState == UserStartedState.STATE_STOPPING
16214                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16215                    // This user is already stopping, doesn't count.
16216                    num--;
16217                    i++;
16218                    continue;
16219                }
16220                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16221                    // Owner and current can't be stopped, but count as running.
16222                    i++;
16223                    continue;
16224                }
16225                // This is a user to be stopped.
16226                stopUserLocked(oldUserId, null);
16227                num--;
16228                i++;
16229            }
16230        }
16231    }
16232
16233    @Override
16234    public int stopUser(final int userId, final IStopUserCallback callback) {
16235        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16236                != PackageManager.PERMISSION_GRANTED) {
16237            String msg = "Permission Denial: switchUser() from pid="
16238                    + Binder.getCallingPid()
16239                    + ", uid=" + Binder.getCallingUid()
16240                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16241            Slog.w(TAG, msg);
16242            throw new SecurityException(msg);
16243        }
16244        if (userId <= 0) {
16245            throw new IllegalArgumentException("Can't stop primary user " + userId);
16246        }
16247        synchronized (this) {
16248            return stopUserLocked(userId, callback);
16249        }
16250    }
16251
16252    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16253        if (mCurrentUserId == userId) {
16254            return ActivityManager.USER_OP_IS_CURRENT;
16255        }
16256
16257        final UserStartedState uss = mStartedUsers.get(userId);
16258        if (uss == null) {
16259            // User is not started, nothing to do...  but we do need to
16260            // callback if requested.
16261            if (callback != null) {
16262                mHandler.post(new Runnable() {
16263                    @Override
16264                    public void run() {
16265                        try {
16266                            callback.userStopped(userId);
16267                        } catch (RemoteException e) {
16268                        }
16269                    }
16270                });
16271            }
16272            return ActivityManager.USER_OP_SUCCESS;
16273        }
16274
16275        if (callback != null) {
16276            uss.mStopCallbacks.add(callback);
16277        }
16278
16279        if (uss.mState != UserStartedState.STATE_STOPPING
16280                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16281            uss.mState = UserStartedState.STATE_STOPPING;
16282            updateStartedUserArrayLocked();
16283
16284            long ident = Binder.clearCallingIdentity();
16285            try {
16286                // We are going to broadcast ACTION_USER_STOPPING and then
16287                // once that is done send a final ACTION_SHUTDOWN and then
16288                // stop the user.
16289                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16290                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16291                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16292                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16293                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16294                // This is the result receiver for the final shutdown broadcast.
16295                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16296                    @Override
16297                    public void performReceive(Intent intent, int resultCode, String data,
16298                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16299                        finishUserStop(uss);
16300                    }
16301                };
16302                // This is the result receiver for the initial stopping broadcast.
16303                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16304                    @Override
16305                    public void performReceive(Intent intent, int resultCode, String data,
16306                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16307                        // On to the next.
16308                        synchronized (ActivityManagerService.this) {
16309                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16310                                // Whoops, we are being started back up.  Abort, abort!
16311                                return;
16312                            }
16313                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16314                        }
16315                        broadcastIntentLocked(null, null, shutdownIntent,
16316                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16317                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16318                    }
16319                };
16320                // Kick things off.
16321                broadcastIntentLocked(null, null, stoppingIntent,
16322                        null, stoppingReceiver, 0, null, null,
16323                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16324                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16325            } finally {
16326                Binder.restoreCallingIdentity(ident);
16327            }
16328        }
16329
16330        return ActivityManager.USER_OP_SUCCESS;
16331    }
16332
16333    void finishUserStop(UserStartedState uss) {
16334        final int userId = uss.mHandle.getIdentifier();
16335        boolean stopped;
16336        ArrayList<IStopUserCallback> callbacks;
16337        synchronized (this) {
16338            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16339            if (mStartedUsers.get(userId) != uss) {
16340                stopped = false;
16341            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16342                stopped = false;
16343            } else {
16344                stopped = true;
16345                // User can no longer run.
16346                mStartedUsers.remove(userId);
16347                mUserLru.remove(Integer.valueOf(userId));
16348                updateStartedUserArrayLocked();
16349
16350                // Clean up all state and processes associated with the user.
16351                // Kill all the processes for the user.
16352                forceStopUserLocked(userId, "finish user");
16353            }
16354        }
16355
16356        for (int i=0; i<callbacks.size(); i++) {
16357            try {
16358                if (stopped) callbacks.get(i).userStopped(userId);
16359                else callbacks.get(i).userStopAborted(userId);
16360            } catch (RemoteException e) {
16361            }
16362        }
16363
16364        mStackSupervisor.removeUserLocked(userId);
16365    }
16366
16367    @Override
16368    public UserInfo getCurrentUser() {
16369        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16370                != PackageManager.PERMISSION_GRANTED) && (
16371                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16372                != PackageManager.PERMISSION_GRANTED)) {
16373            String msg = "Permission Denial: getCurrentUser() from pid="
16374                    + Binder.getCallingPid()
16375                    + ", uid=" + Binder.getCallingUid()
16376                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16377            Slog.w(TAG, msg);
16378            throw new SecurityException(msg);
16379        }
16380        synchronized (this) {
16381            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16382        }
16383    }
16384
16385    int getCurrentUserIdLocked() {
16386        return mCurrentUserId;
16387    }
16388
16389    @Override
16390    public boolean isUserRunning(int userId, boolean orStopped) {
16391        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16392                != PackageManager.PERMISSION_GRANTED) {
16393            String msg = "Permission Denial: isUserRunning() from pid="
16394                    + Binder.getCallingPid()
16395                    + ", uid=" + Binder.getCallingUid()
16396                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16397            Slog.w(TAG, msg);
16398            throw new SecurityException(msg);
16399        }
16400        synchronized (this) {
16401            return isUserRunningLocked(userId, orStopped);
16402        }
16403    }
16404
16405    boolean isUserRunningLocked(int userId, boolean orStopped) {
16406        UserStartedState state = mStartedUsers.get(userId);
16407        if (state == null) {
16408            return false;
16409        }
16410        if (orStopped) {
16411            return true;
16412        }
16413        return state.mState != UserStartedState.STATE_STOPPING
16414                && state.mState != UserStartedState.STATE_SHUTDOWN;
16415    }
16416
16417    @Override
16418    public int[] getRunningUserIds() {
16419        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16420                != PackageManager.PERMISSION_GRANTED) {
16421            String msg = "Permission Denial: isUserRunning() from pid="
16422                    + Binder.getCallingPid()
16423                    + ", uid=" + Binder.getCallingUid()
16424                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16425            Slog.w(TAG, msg);
16426            throw new SecurityException(msg);
16427        }
16428        synchronized (this) {
16429            return mStartedUserArray;
16430        }
16431    }
16432
16433    private void updateStartedUserArrayLocked() {
16434        int num = 0;
16435        for (int i=0; i<mStartedUsers.size();  i++) {
16436            UserStartedState uss = mStartedUsers.valueAt(i);
16437            // This list does not include stopping users.
16438            if (uss.mState != UserStartedState.STATE_STOPPING
16439                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16440                num++;
16441            }
16442        }
16443        mStartedUserArray = new int[num];
16444        num = 0;
16445        for (int i=0; i<mStartedUsers.size();  i++) {
16446            UserStartedState uss = mStartedUsers.valueAt(i);
16447            if (uss.mState != UserStartedState.STATE_STOPPING
16448                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16449                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16450                num++;
16451            }
16452        }
16453    }
16454
16455    @Override
16456    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16457        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16458                != PackageManager.PERMISSION_GRANTED) {
16459            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16460                    + Binder.getCallingPid()
16461                    + ", uid=" + Binder.getCallingUid()
16462                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16463            Slog.w(TAG, msg);
16464            throw new SecurityException(msg);
16465        }
16466
16467        mUserSwitchObservers.register(observer);
16468    }
16469
16470    @Override
16471    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16472        mUserSwitchObservers.unregister(observer);
16473    }
16474
16475    private boolean userExists(int userId) {
16476        if (userId == 0) {
16477            return true;
16478        }
16479        UserManagerService ums = getUserManagerLocked();
16480        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16481    }
16482
16483    int[] getUsersLocked() {
16484        UserManagerService ums = getUserManagerLocked();
16485        return ums != null ? ums.getUserIds() : new int[] { 0 };
16486    }
16487
16488    UserManagerService getUserManagerLocked() {
16489        if (mUserManager == null) {
16490            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16491            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16492        }
16493        return mUserManager;
16494    }
16495
16496    private int applyUserId(int uid, int userId) {
16497        return UserHandle.getUid(userId, uid);
16498    }
16499
16500    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16501        if (info == null) return null;
16502        ApplicationInfo newInfo = new ApplicationInfo(info);
16503        newInfo.uid = applyUserId(info.uid, userId);
16504        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16505                + info.packageName;
16506        return newInfo;
16507    }
16508
16509    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16510        if (aInfo == null
16511                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16512            return aInfo;
16513        }
16514
16515        ActivityInfo info = new ActivityInfo(aInfo);
16516        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16517        return info;
16518    }
16519}
16520