ActivityManagerService.java revision 5f6238e4a7b2b54c4852852bd9bf045f387a5e42
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
28
29import android.app.AppOpsManager;
30import android.app.IActivityContainer;
31import android.app.IActivityContainerCallback;
32import android.appwidget.AppWidgetManager;
33import android.graphics.Rect;
34import android.util.ArrayMap;
35
36import com.android.internal.R;
37import com.android.internal.annotations.GuardedBy;
38import com.android.internal.app.IAppOpsService;
39import com.android.internal.app.ProcessMap;
40import com.android.internal.app.ProcessStats;
41import com.android.internal.os.BackgroundThread;
42import com.android.internal.os.BatteryStatsImpl;
43import com.android.internal.os.ProcessCpuTracker;
44import com.android.internal.os.TransferPipe;
45import com.android.internal.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.LocalServices;
53import com.android.server.ServiceThread;
54import com.android.server.SystemService;
55import com.android.server.Watchdog;
56import com.android.server.am.ActivityStack.ActivityState;
57import com.android.server.firewall.IntentFirewall;
58import com.android.server.pm.UserManagerService;
59import com.android.server.wm.AppTransition;
60import com.android.server.wm.WindowManagerService;
61import com.google.android.collect.Lists;
62import com.google.android.collect.Maps;
63
64import dalvik.system.Zygote;
65import libcore.io.IoUtils;
66
67import org.xmlpull.v1.XmlPullParser;
68import org.xmlpull.v1.XmlPullParserException;
69import org.xmlpull.v1.XmlSerializer;
70
71import android.app.Activity;
72import android.app.ActivityManager;
73import android.app.ActivityManager.RunningTaskInfo;
74import android.app.ActivityManager.StackInfo;
75import android.app.ActivityManagerInternal;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.ApplicationErrorReport;
82import android.app.Dialog;
83import android.app.IActivityController;
84import android.app.IApplicationThread;
85import android.app.IInstrumentationWatcher;
86import android.app.INotificationManager;
87import android.app.IProcessObserver;
88import android.app.IServiceConnection;
89import android.app.IStopUserCallback;
90import android.app.IThumbnailReceiver;
91import android.app.IUiAutomationConnection;
92import android.app.IUserSwitchObserver;
93import android.app.Instrumentation;
94import android.app.Notification;
95import android.app.NotificationManager;
96import android.app.PendingIntent;
97import android.app.backup.IBackupManager;
98import android.content.ActivityNotFoundException;
99import android.content.BroadcastReceiver;
100import android.content.ClipData;
101import android.content.ComponentCallbacks2;
102import android.content.ComponentName;
103import android.content.ContentProvider;
104import android.content.ContentResolver;
105import android.content.Context;
106import android.content.DialogInterface;
107import android.content.IContentProvider;
108import android.content.IIntentReceiver;
109import android.content.IIntentSender;
110import android.content.Intent;
111import android.content.IntentFilter;
112import android.content.IntentSender;
113import android.content.pm.ActivityInfo;
114import android.content.pm.ApplicationInfo;
115import android.content.pm.ConfigurationInfo;
116import android.content.pm.IPackageDataObserver;
117import android.content.pm.IPackageManager;
118import android.content.pm.InstrumentationInfo;
119import android.content.pm.PackageInfo;
120import android.content.pm.PackageManager;
121import android.content.pm.ParceledListSlice;
122import android.content.pm.UserInfo;
123import android.content.pm.PackageManager.NameNotFoundException;
124import android.content.pm.PathPermission;
125import android.content.pm.ProviderInfo;
126import android.content.pm.ResolveInfo;
127import android.content.pm.ServiceInfo;
128import android.content.res.CompatibilityInfo;
129import android.content.res.Configuration;
130import android.graphics.Bitmap;
131import android.net.Proxy;
132import android.net.ProxyProperties;
133import android.net.Uri;
134import android.os.Binder;
135import android.os.Build;
136import android.os.Bundle;
137import android.os.Debug;
138import android.os.DropBoxManager;
139import android.os.Environment;
140import android.os.FactoryTest;
141import android.os.FileObserver;
142import android.os.FileUtils;
143import android.os.Handler;
144import android.os.IBinder;
145import android.os.IPermissionController;
146import android.os.IRemoteCallback;
147import android.os.IUserManager;
148import android.os.Looper;
149import android.os.Message;
150import android.os.Parcel;
151import android.os.ParcelFileDescriptor;
152import android.os.Process;
153import android.os.RemoteCallbackList;
154import android.os.RemoteException;
155import android.os.SELinux;
156import android.os.ServiceManager;
157import android.os.StrictMode;
158import android.os.SystemClock;
159import android.os.SystemProperties;
160import android.os.UpdateLock;
161import android.os.UserHandle;
162import android.provider.Settings;
163import android.text.format.DateUtils;
164import android.text.format.Time;
165import android.util.AtomicFile;
166import android.util.EventLog;
167import android.util.Log;
168import android.util.Pair;
169import android.util.PrintWriterPrinter;
170import android.util.Slog;
171import android.util.SparseArray;
172import android.util.TimeUtils;
173import android.util.Xml;
174import android.view.Gravity;
175import android.view.LayoutInflater;
176import android.view.View;
177import android.view.WindowManager;
178
179import java.io.BufferedInputStream;
180import java.io.BufferedOutputStream;
181import java.io.DataInputStream;
182import java.io.DataOutputStream;
183import java.io.File;
184import java.io.FileDescriptor;
185import java.io.FileInputStream;
186import java.io.FileNotFoundException;
187import java.io.FileOutputStream;
188import java.io.IOException;
189import java.io.InputStreamReader;
190import java.io.PrintWriter;
191import java.io.StringWriter;
192import java.lang.ref.WeakReference;
193import java.util.ArrayList;
194import java.util.Arrays;
195import java.util.Collections;
196import java.util.Comparator;
197import java.util.HashMap;
198import java.util.HashSet;
199import java.util.Iterator;
200import java.util.List;
201import java.util.Locale;
202import java.util.Map;
203import java.util.Set;
204import java.util.concurrent.atomic.AtomicBoolean;
205import java.util.concurrent.atomic.AtomicLong;
206
207public final class ActivityManagerService extends ActivityManagerNative
208        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
209    private static final String USER_DATA_DIR = "/data/user/";
210    static final String TAG = "ActivityManager";
211    static final String TAG_MU = "ActivityManagerServiceMU";
212    static final boolean DEBUG = false;
213    static final boolean localLOGV = DEBUG;
214    static final boolean DEBUG_BACKUP = localLOGV || false;
215    static final boolean DEBUG_BROADCAST = localLOGV || false;
216    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_CLEANUP = localLOGV || false;
219    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
220    static final boolean DEBUG_FOCUS = false;
221    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
222    static final boolean DEBUG_MU = localLOGV || false;
223    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
224    static final boolean DEBUG_LRU = localLOGV || false;
225    static final boolean DEBUG_PAUSE = localLOGV || false;
226    static final boolean DEBUG_POWER = localLOGV || false;
227    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
228    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
229    static final boolean DEBUG_PROCESSES = localLOGV || false;
230    static final boolean DEBUG_PROVIDER = localLOGV || false;
231    static final boolean DEBUG_RESULTS = localLOGV || false;
232    static final boolean DEBUG_SERVICE = localLOGV || false;
233    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
234    static final boolean DEBUG_STACK = localLOGV || false;
235    static final boolean DEBUG_SWITCH = localLOGV || false;
236    static final boolean DEBUG_TASKS = localLOGV || false;
237    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
238    static final boolean DEBUG_TRANSITION = localLOGV || false;
239    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
240    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
241    static final boolean DEBUG_VISBILITY = localLOGV || false;
242    static final boolean DEBUG_PSS = localLOGV || false;
243    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
244    static final boolean VALIDATE_TOKENS = false;
245    static final boolean SHOW_ACTIVITY_START_TIME = true;
246
247    // Control over CPU and battery monitoring.
248    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
249    static final boolean MONITOR_CPU_USAGE = true;
250    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
251    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
252    static final boolean MONITOR_THREAD_CPU_USAGE = false;
253
254    // The flags that are set for all calls we make to the package manager.
255    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
256
257    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
258
259    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
260
261    // Maximum number of recent tasks that we can remember.
262    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
263
264    // Amount of time after a call to stopAppSwitches() during which we will
265    // prevent further untrusted switches from happening.
266    static final long APP_SWITCH_DELAY_TIME = 5*1000;
267
268    // How long we wait for a launched process to attach to the activity manager
269    // before we decide it's never going to come up for real.
270    static final int PROC_START_TIMEOUT = 10*1000;
271
272    // How long we wait for a launched process to attach to the activity manager
273    // before we decide it's never going to come up for real, when the process was
274    // started with a wrapper for instrumentation (such as Valgrind) because it
275    // could take much longer than usual.
276    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
277
278    // How long to wait after going idle before forcing apps to GC.
279    static final int GC_TIMEOUT = 5*1000;
280
281    // The minimum amount of time between successive GC requests for a process.
282    static final int GC_MIN_INTERVAL = 60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process.
285    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
286
287    // The minimum amount of time between successive PSS requests for a process
288    // when the request is due to the memory state being lowered.
289    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
290
291    // The rate at which we check for apps using excessive power -- 15 mins.
292    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
293
294    // The minimum sample duration we will allow before deciding we have
295    // enough data on wake locks to start killing things.
296    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
297
298    // The minimum sample duration we will allow before deciding we have
299    // enough data on CPU usage to start killing things.
300    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
301
302    // How long we allow a receiver to run before giving up on it.
303    static final int BROADCAST_FG_TIMEOUT = 10*1000;
304    static final int BROADCAST_BG_TIMEOUT = 60*1000;
305
306    // How long we wait until we timeout on key dispatching.
307    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
308
309    // How long we wait until we timeout on key dispatching during instrumentation.
310    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
311
312    // Amount of time we wait for observers to handle a user switch before
313    // giving up on them and unfreezing the screen.
314    static final int USER_SWITCH_TIMEOUT = 2*1000;
315
316    // Maximum number of users we allow to be running at a time.
317    static final int MAX_RUNNING_USERS = 3;
318
319    // How long to wait in getAssistContextExtras for the activity and foreground services
320    // to respond with the result.
321    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
322
323    // Maximum number of persisted Uri grants a package is allowed
324    static final int MAX_PERSISTED_URI_GRANTS = 128;
325
326    static final int MY_PID = Process.myPid();
327
328    static final String[] EMPTY_STRING_ARRAY = new String[0];
329
330    // How many bytes to write into the dropbox log before truncating
331    static final int DROPBOX_MAX_SIZE = 256 * 1024;
332
333    /** Run all ActivityStacks through this */
334    ActivityStackSupervisor mStackSupervisor;
335
336    public IntentFirewall mIntentFirewall;
337
338    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
339    // default actuion automatically.  Important for devices without direct input
340    // devices.
341    private boolean mShowDialogs = true;
342
343    /**
344     * Description of a request to start a new activity, which has been held
345     * due to app switches being disabled.
346     */
347    static class PendingActivityLaunch {
348        final ActivityRecord r;
349        final ActivityRecord sourceRecord;
350        final int startFlags;
351        final ActivityStack stack;
352
353        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
354                int _startFlags, ActivityStack _stack) {
355            r = _r;
356            sourceRecord = _sourceRecord;
357            startFlags = _startFlags;
358            stack = _stack;
359        }
360    }
361
362    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
363            = new ArrayList<PendingActivityLaunch>();
364
365    BroadcastQueue mFgBroadcastQueue;
366    BroadcastQueue mBgBroadcastQueue;
367    // Convenient for easy iteration over the queues. Foreground is first
368    // so that dispatch of foreground broadcasts gets precedence.
369    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
370
371    BroadcastQueue broadcastQueueForIntent(Intent intent) {
372        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
373        if (DEBUG_BACKGROUND_BROADCAST) {
374            Slog.i(TAG, "Broadcast intent " + intent + " on "
375                    + (isFg ? "foreground" : "background")
376                    + " queue");
377        }
378        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
379    }
380
381    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
382        for (BroadcastQueue queue : mBroadcastQueues) {
383            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
384            if (r != null) {
385                return r;
386            }
387        }
388        return null;
389    }
390
391    /**
392     * Activity we have told the window manager to have key focus.
393     */
394    ActivityRecord mFocusedActivity = null;
395
396    /**
397     * List of intents that were used to start the most recent tasks.
398     */
399    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
400
401    public class PendingAssistExtras extends Binder implements Runnable {
402        public final ActivityRecord activity;
403        public boolean haveResult = false;
404        public Bundle result = null;
405        public PendingAssistExtras(ActivityRecord _activity) {
406            activity = _activity;
407        }
408        @Override
409        public void run() {
410            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
411            synchronized (this) {
412                haveResult = true;
413                notifyAll();
414            }
415        }
416    }
417
418    final ArrayList<PendingAssistExtras> mPendingAssistExtras
419            = new ArrayList<PendingAssistExtras>();
420
421    /**
422     * Process management.
423     */
424    final ProcessList mProcessList = new ProcessList();
425
426    /**
427     * All of the applications we currently have running organized by name.
428     * The keys are strings of the application package name (as
429     * returned by the package manager), and the keys are ApplicationRecord
430     * objects.
431     */
432    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
433
434    /**
435     * Tracking long-term execution of processes to look for abuse and other
436     * bad app behavior.
437     */
438    final ProcessStatsService mProcessStats;
439
440    /**
441     * The currently running isolated processes.
442     */
443    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
444
445    /**
446     * Counter for assigning isolated process uids, to avoid frequently reusing the
447     * same ones.
448     */
449    int mNextIsolatedProcessUid = 0;
450
451    /**
452     * The currently running heavy-weight process, if any.
453     */
454    ProcessRecord mHeavyWeightProcess = null;
455
456    /**
457     * The last time that various processes have crashed.
458     */
459    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
460
461    /**
462     * Information about a process that is currently marked as bad.
463     */
464    static final class BadProcessInfo {
465        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
466            this.time = time;
467            this.shortMsg = shortMsg;
468            this.longMsg = longMsg;
469            this.stack = stack;
470        }
471
472        final long time;
473        final String shortMsg;
474        final String longMsg;
475        final String stack;
476    }
477
478    /**
479     * Set of applications that we consider to be bad, and will reject
480     * incoming broadcasts from (which the user has no control over).
481     * Processes are added to this set when they have crashed twice within
482     * a minimum amount of time; they are removed from it when they are
483     * later restarted (hopefully due to some user action).  The value is the
484     * time it was added to the list.
485     */
486    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
487
488    /**
489     * All of the processes we currently have running organized by pid.
490     * The keys are the pid running the application.
491     *
492     * <p>NOTE: This object is protected by its own lock, NOT the global
493     * activity manager lock!
494     */
495    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
496
497    /**
498     * All of the processes that have been forced to be foreground.  The key
499     * is the pid of the caller who requested it (we hold a death
500     * link on it).
501     */
502    abstract class ForegroundToken implements IBinder.DeathRecipient {
503        int pid;
504        IBinder token;
505    }
506    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
507
508    /**
509     * List of records for processes that someone had tried to start before the
510     * system was ready.  We don't start them at that point, but ensure they
511     * are started by the time booting is complete.
512     */
513    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
514
515    /**
516     * List of persistent applications that are in the process
517     * of being started.
518     */
519    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
520
521    /**
522     * Processes that are being forcibly torn down.
523     */
524    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of running applications, sorted by recent usage.
528     * The first entry in the list is the least recently used.
529     */
530    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Where in mLruProcesses that the processes hosting activities start.
534     */
535    int mLruProcessActivityStart = 0;
536
537    /**
538     * Where in mLruProcesses that the processes hosting services start.
539     * This is after (lower index) than mLruProcessesActivityStart.
540     */
541    int mLruProcessServiceStart = 0;
542
543    /**
544     * List of processes that should gc as soon as things are idle.
545     */
546    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
547
548    /**
549     * Processes we want to collect PSS data from.
550     */
551    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Last time we requested PSS data of all processes.
555     */
556    long mLastFullPssTime = SystemClock.uptimeMillis();
557
558    /**
559     * This is the process holding what we currently consider to be
560     * the "home" activity.
561     */
562    ProcessRecord mHomeProcess;
563
564    /**
565     * This is the process holding the activity the user last visited that
566     * is in a different process from the one they are currently in.
567     */
568    ProcessRecord mPreviousProcess;
569
570    /**
571     * The time at which the previous process was last visible.
572     */
573    long mPreviousProcessVisibleTime;
574
575    /**
576     * Which uses have been started, so are allowed to run code.
577     */
578    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
579
580    /**
581     * LRU list of history of current users.  Most recently current is at the end.
582     */
583    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
584
585    /**
586     * Constant array of the users that are currently started.
587     */
588    int[] mStartedUserArray = new int[] { 0 };
589
590    /**
591     * Registered observers of the user switching mechanics.
592     */
593    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
594            = new RemoteCallbackList<IUserSwitchObserver>();
595
596    /**
597     * Currently active user switch.
598     */
599    Object mCurUserSwitchCallback;
600
601    /**
602     * Packages that the user has asked to have run in screen size
603     * compatibility mode instead of filling the screen.
604     */
605    final CompatModePackages mCompatModePackages;
606
607    /**
608     * Set of IntentSenderRecord objects that are currently active.
609     */
610    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
611            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
612
613    /**
614     * Fingerprints (hashCode()) of stack traces that we've
615     * already logged DropBox entries for.  Guarded by itself.  If
616     * something (rogue user app) forces this over
617     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
618     */
619    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
620    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
621
622    /**
623     * Strict Mode background batched logging state.
624     *
625     * The string buffer is guarded by itself, and its lock is also
626     * used to determine if another batched write is already
627     * in-flight.
628     */
629    private final StringBuilder mStrictModeBuffer = new StringBuilder();
630
631    /**
632     * Keeps track of all IIntentReceivers that have been registered for
633     * broadcasts.  Hash keys are the receiver IBinder, hash value is
634     * a ReceiverList.
635     */
636    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
637            new HashMap<IBinder, ReceiverList>();
638
639    /**
640     * Resolver for broadcast intents to registered receivers.
641     * Holds BroadcastFilter (subclass of IntentFilter).
642     */
643    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
644            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
645        @Override
646        protected boolean allowFilterResult(
647                BroadcastFilter filter, List<BroadcastFilter> dest) {
648            IBinder target = filter.receiverList.receiver.asBinder();
649            for (int i=dest.size()-1; i>=0; i--) {
650                if (dest.get(i).receiverList.receiver.asBinder() == target) {
651                    return false;
652                }
653            }
654            return true;
655        }
656
657        @Override
658        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
659            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
660                    || userId == filter.owningUserId) {
661                return super.newResult(filter, match, userId);
662            }
663            return null;
664        }
665
666        @Override
667        protected BroadcastFilter[] newArray(int size) {
668            return new BroadcastFilter[size];
669        }
670
671        @Override
672        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
673            return packageName.equals(filter.packageName);
674        }
675    };
676
677    /**
678     * State of all active sticky broadcasts per user.  Keys are the action of the
679     * sticky Intent, values are an ArrayList of all broadcasted intents with
680     * that action (which should usually be one).  The SparseArray is keyed
681     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
682     * for stickies that are sent to all users.
683     */
684    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
685            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
686
687    final ActiveServices mServices;
688
689    /**
690     * Backup/restore process management
691     */
692    String mBackupAppName = null;
693    BackupRecord mBackupTarget = null;
694
695    /**
696     * List of PendingThumbnailsRecord objects of clients who are still
697     * waiting to receive all of the thumbnails for a task.
698     */
699    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
700            new ArrayList<PendingThumbnailsRecord>();
701
702    final ProviderMap mProviderMap;
703
704    /**
705     * List of content providers who have clients waiting for them.  The
706     * application is currently being launched and the provider will be
707     * removed from this list once it is published.
708     */
709    final ArrayList<ContentProviderRecord> mLaunchingProviders
710            = new ArrayList<ContentProviderRecord>();
711
712    /**
713     * File storing persisted {@link #mGrantedUriPermissions}.
714     */
715    private final AtomicFile mGrantFile;
716
717    /** XML constants used in {@link #mGrantFile} */
718    private static final String TAG_URI_GRANTS = "uri-grants";
719    private static final String TAG_URI_GRANT = "uri-grant";
720    private static final String ATTR_USER_HANDLE = "userHandle";
721    private static final String ATTR_SOURCE_PKG = "sourcePkg";
722    private static final String ATTR_TARGET_PKG = "targetPkg";
723    private static final String ATTR_URI = "uri";
724    private static final String ATTR_MODE_FLAGS = "modeFlags";
725    private static final String ATTR_CREATED_TIME = "createdTime";
726
727    /**
728     * Global set of specific {@link Uri} permissions that have been granted.
729     * This optimized lookup structure maps from {@link UriPermission#targetUid}
730     * to {@link UriPermission#uri} to {@link UriPermission}.
731     */
732    @GuardedBy("this")
733    private final SparseArray<ArrayMap<Uri, UriPermission>>
734            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
735
736    CoreSettingsObserver mCoreSettingsObserver;
737
738    /**
739     * Thread-local storage used to carry caller permissions over through
740     * indirect content-provider access.
741     */
742    private class Identity {
743        public int pid;
744        public int uid;
745
746        Identity(int _pid, int _uid) {
747            pid = _pid;
748            uid = _uid;
749        }
750    }
751
752    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
753
754    /**
755     * All information we have collected about the runtime performance of
756     * any user id that can impact battery performance.
757     */
758    final BatteryStatsService mBatteryStatsService;
759
760    /**
761     * Information about component usage
762     */
763    final UsageStatsService mUsageStatsService;
764
765    /**
766     * Information about and control over application operations
767     */
768    final AppOpsService mAppOpsService;
769
770    /**
771     * Current configuration information.  HistoryRecord objects are given
772     * a reference to this object to indicate which configuration they are
773     * currently running in, so this object must be kept immutable.
774     */
775    Configuration mConfiguration = new Configuration();
776
777    /**
778     * Current sequencing integer of the configuration, for skipping old
779     * configurations.
780     */
781    int mConfigurationSeq = 0;
782
783    /**
784     * Hardware-reported OpenGLES version.
785     */
786    final int GL_ES_VERSION;
787
788    /**
789     * List of initialization arguments to pass to all processes when binding applications to them.
790     * For example, references to the commonly used services.
791     */
792    HashMap<String, IBinder> mAppBindArgs;
793
794    /**
795     * Temporary to avoid allocations.  Protected by main lock.
796     */
797    final StringBuilder mStringBuilder = new StringBuilder(256);
798
799    /**
800     * Used to control how we initialize the service.
801     */
802    ComponentName mTopComponent;
803    String mTopAction = Intent.ACTION_MAIN;
804    String mTopData;
805    boolean mProcessesReady = false;
806    boolean mSystemReady = false;
807    boolean mBooting = false;
808    boolean mWaitingUpdate = false;
809    boolean mDidUpdate = false;
810    boolean mOnBattery = false;
811    boolean mLaunchWarningShown = false;
812
813    Context mContext;
814
815    int mFactoryTest;
816
817    boolean mCheckedForSetup;
818
819    /**
820     * The time at which we will allow normal application switches again,
821     * after a call to {@link #stopAppSwitches()}.
822     */
823    long mAppSwitchesAllowedTime;
824
825    /**
826     * This is set to true after the first switch after mAppSwitchesAllowedTime
827     * is set; any switches after that will clear the time.
828     */
829    boolean mDidAppSwitch;
830
831    /**
832     * Last time (in realtime) at which we checked for power usage.
833     */
834    long mLastPowerCheckRealtime;
835
836    /**
837     * Last time (in uptime) at which we checked for power usage.
838     */
839    long mLastPowerCheckUptime;
840
841    /**
842     * Set while we are wanting to sleep, to prevent any
843     * activities from being started/resumed.
844     */
845    boolean mSleeping = false;
846
847    /**
848     * State of external calls telling us if the device is asleep.
849     */
850    boolean mWentToSleep = false;
851
852    /**
853     * State of external call telling us if the lock screen is shown.
854     */
855    boolean mLockScreenShown = false;
856
857    /**
858     * Set if we are shutting down the system, similar to sleeping.
859     */
860    boolean mShuttingDown = false;
861
862    /**
863     * Current sequence id for oom_adj computation traversal.
864     */
865    int mAdjSeq = 0;
866
867    /**
868     * Current sequence id for process LRU updating.
869     */
870    int mLruSeq = 0;
871
872    /**
873     * Keep track of the non-cached/empty process we last found, to help
874     * determine how to distribute cached/empty processes next time.
875     */
876    int mNumNonCachedProcs = 0;
877
878    /**
879     * Keep track of the number of cached hidden procs, to balance oom adj
880     * distribution between those and empty procs.
881     */
882    int mNumCachedHiddenProcs = 0;
883
884    /**
885     * Keep track of the number of service processes we last found, to
886     * determine on the next iteration which should be B services.
887     */
888    int mNumServiceProcs = 0;
889    int mNewNumAServiceProcs = 0;
890    int mNewNumServiceProcs = 0;
891
892    /**
893     * Allow the current computed overall memory level of the system to go down?
894     * This is set to false when we are killing processes for reasons other than
895     * memory management, so that the now smaller process list will not be taken as
896     * an indication that memory is tighter.
897     */
898    boolean mAllowLowerMemLevel = false;
899
900    /**
901     * The last computed memory level, for holding when we are in a state that
902     * processes are going away for other reasons.
903     */
904    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
905
906    /**
907     * The last total number of process we have, to determine if changes actually look
908     * like a shrinking number of process due to lower RAM.
909     */
910    int mLastNumProcesses;
911
912    /**
913     * The uptime of the last time we performed idle maintenance.
914     */
915    long mLastIdleTime = SystemClock.uptimeMillis();
916
917    /**
918     * Total time spent with RAM that has been added in the past since the last idle time.
919     */
920    long mLowRamTimeSinceLastIdle = 0;
921
922    /**
923     * If RAM is currently low, when that horrible situatin started.
924     */
925    long mLowRamStartTime = 0;
926
927    /**
928     * This is set if we had to do a delayed dexopt of an app before launching
929     * it, to increasing the ANR timeouts in that case.
930     */
931    boolean mDidDexOpt;
932
933    String mDebugApp = null;
934    boolean mWaitForDebugger = false;
935    boolean mDebugTransient = false;
936    String mOrigDebugApp = null;
937    boolean mOrigWaitForDebugger = false;
938    boolean mAlwaysFinishActivities = false;
939    IActivityController mController = null;
940    String mProfileApp = null;
941    ProcessRecord mProfileProc = null;
942    String mProfileFile;
943    ParcelFileDescriptor mProfileFd;
944    int mProfileType = 0;
945    boolean mAutoStopProfiler = false;
946    String mOpenGlTraceApp = null;
947
948    static class ProcessChangeItem {
949        static final int CHANGE_ACTIVITIES = 1<<0;
950        static final int CHANGE_IMPORTANCE= 1<<1;
951        int changes;
952        int uid;
953        int pid;
954        int importance;
955        boolean foregroundActivities;
956    }
957
958    final RemoteCallbackList<IProcessObserver> mProcessObservers
959            = new RemoteCallbackList<IProcessObserver>();
960    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
961
962    final ArrayList<ProcessChangeItem> mPendingProcessChanges
963            = new ArrayList<ProcessChangeItem>();
964    final ArrayList<ProcessChangeItem> mAvailProcessChanges
965            = new ArrayList<ProcessChangeItem>();
966
967    /**
968     * Runtime CPU use collection thread.  This object's lock is used to
969     * protect all related state.
970     */
971    final Thread mProcessCpuThread;
972
973    /**
974     * Used to collect process stats when showing not responding dialog.
975     * Protected by mProcessCpuThread.
976     */
977    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
978            MONITOR_THREAD_CPU_USAGE);
979    final AtomicLong mLastCpuTime = new AtomicLong(0);
980    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
981
982    long mLastWriteTime = 0;
983
984    /**
985     * Used to retain an update lock when the foreground activity is in
986     * immersive mode.
987     */
988    final UpdateLock mUpdateLock = new UpdateLock("immersive");
989
990    /**
991     * Set to true after the system has finished booting.
992     */
993    boolean mBooted = false;
994
995    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
996    int mProcessLimitOverride = -1;
997
998    WindowManagerService mWindowManager;
999
1000    final ActivityThread mSystemThread;
1001
1002    int mCurrentUserId = 0;
1003    private UserManagerService mUserManager;
1004
1005    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1006        final ProcessRecord mApp;
1007        final int mPid;
1008        final IApplicationThread mAppThread;
1009
1010        AppDeathRecipient(ProcessRecord app, int pid,
1011                IApplicationThread thread) {
1012            if (localLOGV) Slog.v(
1013                TAG, "New death recipient " + this
1014                + " for thread " + thread.asBinder());
1015            mApp = app;
1016            mPid = pid;
1017            mAppThread = thread;
1018        }
1019
1020        @Override
1021        public void binderDied() {
1022            if (localLOGV) Slog.v(
1023                TAG, "Death received in " + this
1024                + " for thread " + mAppThread.asBinder());
1025            synchronized(ActivityManagerService.this) {
1026                appDiedLocked(mApp, mPid, mAppThread);
1027            }
1028        }
1029    }
1030
1031    static final int SHOW_ERROR_MSG = 1;
1032    static final int SHOW_NOT_RESPONDING_MSG = 2;
1033    static final int SHOW_FACTORY_ERROR_MSG = 3;
1034    static final int UPDATE_CONFIGURATION_MSG = 4;
1035    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1036    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1037    static final int SERVICE_TIMEOUT_MSG = 12;
1038    static final int UPDATE_TIME_ZONE = 13;
1039    static final int SHOW_UID_ERROR_MSG = 14;
1040    static final int IM_FEELING_LUCKY_MSG = 15;
1041    static final int PROC_START_TIMEOUT_MSG = 20;
1042    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1043    static final int KILL_APPLICATION_MSG = 22;
1044    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1045    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1046    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1047    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1048    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1049    static final int CLEAR_DNS_CACHE_MSG = 28;
1050    static final int UPDATE_HTTP_PROXY_MSG = 29;
1051    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1052    static final int DISPATCH_PROCESSES_CHANGED = 31;
1053    static final int DISPATCH_PROCESS_DIED = 32;
1054    static final int REPORT_MEM_USAGE_MSG = 33;
1055    static final int REPORT_USER_SWITCH_MSG = 34;
1056    static final int CONTINUE_USER_SWITCH_MSG = 35;
1057    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1058    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1059    static final int PERSIST_URI_GRANTS_MSG = 38;
1060    static final int REQUEST_ALL_PSS_MSG = 39;
1061
1062    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1063    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1064    static final int FIRST_COMPAT_MODE_MSG = 300;
1065    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1066
1067    AlertDialog mUidAlert;
1068    CompatModeDialog mCompatModeDialog;
1069    long mLastMemUsageReportTime = 0;
1070
1071    /**
1072     * Flag whether the current user is a "monkey", i.e. whether
1073     * the UI is driven by a UI automation tool.
1074     */
1075    private boolean mUserIsMonkey;
1076
1077    /** Flag whether the device has a recents UI */
1078    final boolean mHasRecents;
1079
1080    final ServiceThread mHandlerThread;
1081    final MainHandler mHandler;
1082
1083    final class MainHandler extends Handler {
1084        public MainHandler(Looper looper) {
1085            super(looper, null, true);
1086        }
1087
1088        @Override
1089        public void handleMessage(Message msg) {
1090            switch (msg.what) {
1091            case SHOW_ERROR_MSG: {
1092                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1093                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1094                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1095                synchronized (ActivityManagerService.this) {
1096                    ProcessRecord proc = (ProcessRecord)data.get("app");
1097                    AppErrorResult res = (AppErrorResult) data.get("result");
1098                    if (proc != null && proc.crashDialog != null) {
1099                        Slog.e(TAG, "App already has crash dialog: " + proc);
1100                        if (res != null) {
1101                            res.set(0);
1102                        }
1103                        return;
1104                    }
1105                    if (!showBackground && UserHandle.getAppId(proc.uid)
1106                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1107                            && proc.pid != MY_PID) {
1108                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1109                        if (res != null) {
1110                            res.set(0);
1111                        }
1112                        return;
1113                    }
1114                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1115                        Dialog d = new AppErrorDialog(mContext,
1116                                ActivityManagerService.this, res, proc);
1117                        d.show();
1118                        proc.crashDialog = d;
1119                    } else {
1120                        // The device is asleep, so just pretend that the user
1121                        // saw a crash dialog and hit "force quit".
1122                        if (res != null) {
1123                            res.set(0);
1124                        }
1125                    }
1126                }
1127
1128                ensureBootCompleted();
1129            } break;
1130            case SHOW_NOT_RESPONDING_MSG: {
1131                synchronized (ActivityManagerService.this) {
1132                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1133                    ProcessRecord proc = (ProcessRecord)data.get("app");
1134                    if (proc != null && proc.anrDialog != null) {
1135                        Slog.e(TAG, "App already has anr dialog: " + proc);
1136                        return;
1137                    }
1138
1139                    Intent intent = new Intent("android.intent.action.ANR");
1140                    if (!mProcessesReady) {
1141                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1142                                | Intent.FLAG_RECEIVER_FOREGROUND);
1143                    }
1144                    broadcastIntentLocked(null, null, intent,
1145                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1146                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1147
1148                    if (mShowDialogs) {
1149                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1150                                mContext, proc, (ActivityRecord)data.get("activity"),
1151                                msg.arg1 != 0);
1152                        d.show();
1153                        proc.anrDialog = d;
1154                    } else {
1155                        // Just kill the app if there is no dialog to be shown.
1156                        killAppAtUsersRequest(proc, null);
1157                    }
1158                }
1159
1160                ensureBootCompleted();
1161            } break;
1162            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1163                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1164                synchronized (ActivityManagerService.this) {
1165                    ProcessRecord proc = (ProcessRecord) data.get("app");
1166                    if (proc == null) {
1167                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1168                        break;
1169                    }
1170                    if (proc.crashDialog != null) {
1171                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1172                        return;
1173                    }
1174                    AppErrorResult res = (AppErrorResult) data.get("result");
1175                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1176                        Dialog d = new StrictModeViolationDialog(mContext,
1177                                ActivityManagerService.this, res, proc);
1178                        d.show();
1179                        proc.crashDialog = d;
1180                    } else {
1181                        // The device is asleep, so just pretend that the user
1182                        // saw a crash dialog and hit "force quit".
1183                        res.set(0);
1184                    }
1185                }
1186                ensureBootCompleted();
1187            } break;
1188            case SHOW_FACTORY_ERROR_MSG: {
1189                Dialog d = new FactoryErrorDialog(
1190                    mContext, msg.getData().getCharSequence("msg"));
1191                d.show();
1192                ensureBootCompleted();
1193            } break;
1194            case UPDATE_CONFIGURATION_MSG: {
1195                final ContentResolver resolver = mContext.getContentResolver();
1196                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1197            } break;
1198            case GC_BACKGROUND_PROCESSES_MSG: {
1199                synchronized (ActivityManagerService.this) {
1200                    performAppGcsIfAppropriateLocked();
1201                }
1202            } break;
1203            case WAIT_FOR_DEBUGGER_MSG: {
1204                synchronized (ActivityManagerService.this) {
1205                    ProcessRecord app = (ProcessRecord)msg.obj;
1206                    if (msg.arg1 != 0) {
1207                        if (!app.waitedForDebugger) {
1208                            Dialog d = new AppWaitingForDebuggerDialog(
1209                                    ActivityManagerService.this,
1210                                    mContext, app);
1211                            app.waitDialog = d;
1212                            app.waitedForDebugger = true;
1213                            d.show();
1214                        }
1215                    } else {
1216                        if (app.waitDialog != null) {
1217                            app.waitDialog.dismiss();
1218                            app.waitDialog = null;
1219                        }
1220                    }
1221                }
1222            } break;
1223            case SERVICE_TIMEOUT_MSG: {
1224                if (mDidDexOpt) {
1225                    mDidDexOpt = false;
1226                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1227                    nmsg.obj = msg.obj;
1228                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1229                    return;
1230                }
1231                mServices.serviceTimeout((ProcessRecord)msg.obj);
1232            } break;
1233            case UPDATE_TIME_ZONE: {
1234                synchronized (ActivityManagerService.this) {
1235                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1236                        ProcessRecord r = mLruProcesses.get(i);
1237                        if (r.thread != null) {
1238                            try {
1239                                r.thread.updateTimeZone();
1240                            } catch (RemoteException ex) {
1241                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1242                            }
1243                        }
1244                    }
1245                }
1246            } break;
1247            case CLEAR_DNS_CACHE_MSG: {
1248                synchronized (ActivityManagerService.this) {
1249                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1250                        ProcessRecord r = mLruProcesses.get(i);
1251                        if (r.thread != null) {
1252                            try {
1253                                r.thread.clearDnsCache();
1254                            } catch (RemoteException ex) {
1255                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1256                            }
1257                        }
1258                    }
1259                }
1260            } break;
1261            case UPDATE_HTTP_PROXY_MSG: {
1262                ProxyProperties proxy = (ProxyProperties)msg.obj;
1263                String host = "";
1264                String port = "";
1265                String exclList = "";
1266                String pacFileUrl = null;
1267                if (proxy != null) {
1268                    host = proxy.getHost();
1269                    port = Integer.toString(proxy.getPort());
1270                    exclList = proxy.getExclusionList();
1271                    pacFileUrl = proxy.getPacFileUrl();
1272                }
1273                synchronized (ActivityManagerService.this) {
1274                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1275                        ProcessRecord r = mLruProcesses.get(i);
1276                        if (r.thread != null) {
1277                            try {
1278                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1279                            } catch (RemoteException ex) {
1280                                Slog.w(TAG, "Failed to update http proxy for: " +
1281                                        r.info.processName);
1282                            }
1283                        }
1284                    }
1285                }
1286            } break;
1287            case SHOW_UID_ERROR_MSG: {
1288                String title = "System UIDs Inconsistent";
1289                String text = "UIDs on the system are inconsistent, you need to wipe your"
1290                        + " data partition or your device will be unstable.";
1291                Log.e(TAG, title + ": " + text);
1292                if (mShowDialogs) {
1293                    // XXX This is a temporary dialog, no need to localize.
1294                    AlertDialog d = new BaseErrorDialog(mContext);
1295                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1296                    d.setCancelable(false);
1297                    d.setTitle(title);
1298                    d.setMessage(text);
1299                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1300                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1301                    mUidAlert = d;
1302                    d.show();
1303                }
1304            } break;
1305            case IM_FEELING_LUCKY_MSG: {
1306                if (mUidAlert != null) {
1307                    mUidAlert.dismiss();
1308                    mUidAlert = null;
1309                }
1310            } break;
1311            case PROC_START_TIMEOUT_MSG: {
1312                if (mDidDexOpt) {
1313                    mDidDexOpt = false;
1314                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1315                    nmsg.obj = msg.obj;
1316                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1317                    return;
1318                }
1319                ProcessRecord app = (ProcessRecord)msg.obj;
1320                synchronized (ActivityManagerService.this) {
1321                    processStartTimedOutLocked(app);
1322                }
1323            } break;
1324            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1325                synchronized (ActivityManagerService.this) {
1326                    doPendingActivityLaunchesLocked(true);
1327                }
1328            } break;
1329            case KILL_APPLICATION_MSG: {
1330                synchronized (ActivityManagerService.this) {
1331                    int appid = msg.arg1;
1332                    boolean restart = (msg.arg2 == 1);
1333                    Bundle bundle = (Bundle)msg.obj;
1334                    String pkg = bundle.getString("pkg");
1335                    String reason = bundle.getString("reason");
1336                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1337                            UserHandle.USER_ALL, reason);
1338                }
1339            } break;
1340            case FINALIZE_PENDING_INTENT_MSG: {
1341                ((PendingIntentRecord)msg.obj).completeFinalize();
1342            } break;
1343            case POST_HEAVY_NOTIFICATION_MSG: {
1344                INotificationManager inm = NotificationManager.getService();
1345                if (inm == null) {
1346                    return;
1347                }
1348
1349                ActivityRecord root = (ActivityRecord)msg.obj;
1350                ProcessRecord process = root.app;
1351                if (process == null) {
1352                    return;
1353                }
1354
1355                try {
1356                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1357                    String text = mContext.getString(R.string.heavy_weight_notification,
1358                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1359                    Notification notification = new Notification();
1360                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1361                    notification.when = 0;
1362                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1363                    notification.tickerText = text;
1364                    notification.defaults = 0; // please be quiet
1365                    notification.sound = null;
1366                    notification.vibrate = null;
1367                    notification.setLatestEventInfo(context, text,
1368                            mContext.getText(R.string.heavy_weight_notification_detail),
1369                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1370                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1371                                    new UserHandle(root.userId)));
1372
1373                    try {
1374                        int[] outId = new int[1];
1375                        inm.enqueueNotificationWithTag("android", "android", null,
1376                                R.string.heavy_weight_notification,
1377                                notification, outId, root.userId);
1378                    } catch (RuntimeException e) {
1379                        Slog.w(ActivityManagerService.TAG,
1380                                "Error showing notification for heavy-weight app", e);
1381                    } catch (RemoteException e) {
1382                    }
1383                } catch (NameNotFoundException e) {
1384                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1385                }
1386            } break;
1387            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1388                INotificationManager inm = NotificationManager.getService();
1389                if (inm == null) {
1390                    return;
1391                }
1392                try {
1393                    inm.cancelNotificationWithTag("android", null,
1394                            R.string.heavy_weight_notification,  msg.arg1);
1395                } catch (RuntimeException e) {
1396                    Slog.w(ActivityManagerService.TAG,
1397                            "Error canceling notification for service", e);
1398                } catch (RemoteException e) {
1399                }
1400            } break;
1401            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1402                synchronized (ActivityManagerService.this) {
1403                    checkExcessivePowerUsageLocked(true);
1404                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1405                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1406                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1407                }
1408            } break;
1409            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1410                synchronized (ActivityManagerService.this) {
1411                    ActivityRecord ar = (ActivityRecord)msg.obj;
1412                    if (mCompatModeDialog != null) {
1413                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1414                                ar.info.applicationInfo.packageName)) {
1415                            return;
1416                        }
1417                        mCompatModeDialog.dismiss();
1418                        mCompatModeDialog = null;
1419                    }
1420                    if (ar != null && false) {
1421                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1422                                ar.packageName)) {
1423                            int mode = mCompatModePackages.computeCompatModeLocked(
1424                                    ar.info.applicationInfo);
1425                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1426                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1427                                mCompatModeDialog = new CompatModeDialog(
1428                                        ActivityManagerService.this, mContext,
1429                                        ar.info.applicationInfo);
1430                                mCompatModeDialog.show();
1431                            }
1432                        }
1433                    }
1434                }
1435                break;
1436            }
1437            case DISPATCH_PROCESSES_CHANGED: {
1438                dispatchProcessesChanged();
1439                break;
1440            }
1441            case DISPATCH_PROCESS_DIED: {
1442                final int pid = msg.arg1;
1443                final int uid = msg.arg2;
1444                dispatchProcessDied(pid, uid);
1445                break;
1446            }
1447            case REPORT_MEM_USAGE_MSG: {
1448                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1449                Thread thread = new Thread() {
1450                    @Override public void run() {
1451                        final SparseArray<ProcessMemInfo> infoMap
1452                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1453                        for (int i=0, N=memInfos.size(); i<N; i++) {
1454                            ProcessMemInfo mi = memInfos.get(i);
1455                            infoMap.put(mi.pid, mi);
1456                        }
1457                        updateCpuStatsNow();
1458                        synchronized (mProcessCpuThread) {
1459                            final int N = mProcessCpuTracker.countStats();
1460                            for (int i=0; i<N; i++) {
1461                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1462                                if (st.vsize > 0) {
1463                                    long pss = Debug.getPss(st.pid, null);
1464                                    if (pss > 0) {
1465                                        if (infoMap.indexOfKey(st.pid) < 0) {
1466                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1467                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1468                                            mi.pss = pss;
1469                                            memInfos.add(mi);
1470                                        }
1471                                    }
1472                                }
1473                            }
1474                        }
1475
1476                        long totalPss = 0;
1477                        for (int i=0, N=memInfos.size(); i<N; i++) {
1478                            ProcessMemInfo mi = memInfos.get(i);
1479                            if (mi.pss == 0) {
1480                                mi.pss = Debug.getPss(mi.pid, null);
1481                            }
1482                            totalPss += mi.pss;
1483                        }
1484                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1485                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1486                                if (lhs.oomAdj != rhs.oomAdj) {
1487                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1488                                }
1489                                if (lhs.pss != rhs.pss) {
1490                                    return lhs.pss < rhs.pss ? 1 : -1;
1491                                }
1492                                return 0;
1493                            }
1494                        });
1495
1496                        StringBuilder tag = new StringBuilder(128);
1497                        StringBuilder stack = new StringBuilder(128);
1498                        tag.append("Low on memory -- ");
1499                        appendMemBucket(tag, totalPss, "total", false);
1500                        appendMemBucket(stack, totalPss, "total", true);
1501
1502                        StringBuilder logBuilder = new StringBuilder(1024);
1503                        logBuilder.append("Low on memory:\n");
1504
1505                        boolean firstLine = true;
1506                        int lastOomAdj = Integer.MIN_VALUE;
1507                        for (int i=0, N=memInfos.size(); i<N; i++) {
1508                            ProcessMemInfo mi = memInfos.get(i);
1509
1510                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1511                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1512                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1513                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1514                                if (lastOomAdj != mi.oomAdj) {
1515                                    lastOomAdj = mi.oomAdj;
1516                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1517                                        tag.append(" / ");
1518                                    }
1519                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1520                                        if (firstLine) {
1521                                            stack.append(":");
1522                                            firstLine = false;
1523                                        }
1524                                        stack.append("\n\t at ");
1525                                    } else {
1526                                        stack.append("$");
1527                                    }
1528                                } else {
1529                                    tag.append(" ");
1530                                    stack.append("$");
1531                                }
1532                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1533                                    appendMemBucket(tag, mi.pss, mi.name, false);
1534                                }
1535                                appendMemBucket(stack, mi.pss, mi.name, true);
1536                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1537                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1538                                    stack.append("(");
1539                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1540                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1541                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1542                                            stack.append(":");
1543                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1544                                        }
1545                                    }
1546                                    stack.append(")");
1547                                }
1548                            }
1549
1550                            logBuilder.append("  ");
1551                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1552                            logBuilder.append(' ');
1553                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1554                            logBuilder.append(' ');
1555                            ProcessList.appendRamKb(logBuilder, mi.pss);
1556                            logBuilder.append(" kB: ");
1557                            logBuilder.append(mi.name);
1558                            logBuilder.append(" (");
1559                            logBuilder.append(mi.pid);
1560                            logBuilder.append(") ");
1561                            logBuilder.append(mi.adjType);
1562                            logBuilder.append('\n');
1563                            if (mi.adjReason != null) {
1564                                logBuilder.append("                      ");
1565                                logBuilder.append(mi.adjReason);
1566                                logBuilder.append('\n');
1567                            }
1568                        }
1569
1570                        logBuilder.append("           ");
1571                        ProcessList.appendRamKb(logBuilder, totalPss);
1572                        logBuilder.append(" kB: TOTAL\n");
1573
1574                        long[] infos = new long[Debug.MEMINFO_COUNT];
1575                        Debug.getMemInfo(infos);
1576                        logBuilder.append("  MemInfo: ");
1577                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1578                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1579                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1580                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1581                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1582                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1583                            logBuilder.append("  ZRAM: ");
1584                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1585                            logBuilder.append(" kB RAM, ");
1586                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1587                            logBuilder.append(" kB swap total, ");
1588                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1589                            logBuilder.append(" kB swap free\n");
1590                        }
1591                        Slog.i(TAG, logBuilder.toString());
1592
1593                        StringBuilder dropBuilder = new StringBuilder(1024);
1594                        /*
1595                        StringWriter oomSw = new StringWriter();
1596                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1597                        StringWriter catSw = new StringWriter();
1598                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1599                        String[] emptyArgs = new String[] { };
1600                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1601                        oomPw.flush();
1602                        String oomString = oomSw.toString();
1603                        */
1604                        dropBuilder.append(stack);
1605                        dropBuilder.append('\n');
1606                        dropBuilder.append('\n');
1607                        dropBuilder.append(logBuilder);
1608                        dropBuilder.append('\n');
1609                        /*
1610                        dropBuilder.append(oomString);
1611                        dropBuilder.append('\n');
1612                        */
1613                        StringWriter catSw = new StringWriter();
1614                        synchronized (ActivityManagerService.this) {
1615                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1616                            String[] emptyArgs = new String[] { };
1617                            catPw.println();
1618                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1619                            catPw.println();
1620                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1621                                    false, false, null);
1622                            catPw.println();
1623                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1624                            catPw.flush();
1625                        }
1626                        dropBuilder.append(catSw.toString());
1627                        addErrorToDropBox("lowmem", null, "system_server", null,
1628                                null, tag.toString(), dropBuilder.toString(), null, null);
1629                        //Slog.i(TAG, "Sent to dropbox:");
1630                        //Slog.i(TAG, dropBuilder.toString());
1631                        synchronized (ActivityManagerService.this) {
1632                            long now = SystemClock.uptimeMillis();
1633                            if (mLastMemUsageReportTime < now) {
1634                                mLastMemUsageReportTime = now;
1635                            }
1636                        }
1637                    }
1638                };
1639                thread.start();
1640                break;
1641            }
1642            case REPORT_USER_SWITCH_MSG: {
1643                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1644                break;
1645            }
1646            case CONTINUE_USER_SWITCH_MSG: {
1647                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1648                break;
1649            }
1650            case USER_SWITCH_TIMEOUT_MSG: {
1651                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1652                break;
1653            }
1654            case IMMERSIVE_MODE_LOCK_MSG: {
1655                final boolean nextState = (msg.arg1 != 0);
1656                if (mUpdateLock.isHeld() != nextState) {
1657                    if (DEBUG_IMMERSIVE) {
1658                        final ActivityRecord r = (ActivityRecord) msg.obj;
1659                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1660                    }
1661                    if (nextState) {
1662                        mUpdateLock.acquire();
1663                    } else {
1664                        mUpdateLock.release();
1665                    }
1666                }
1667                break;
1668            }
1669            case PERSIST_URI_GRANTS_MSG: {
1670                writeGrantedUriPermissions();
1671                break;
1672            }
1673            case REQUEST_ALL_PSS_MSG: {
1674                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1675                break;
1676            }
1677            }
1678        }
1679    };
1680
1681    static final int COLLECT_PSS_BG_MSG = 1;
1682
1683    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1684        @Override
1685        public void handleMessage(Message msg) {
1686            switch (msg.what) {
1687            case COLLECT_PSS_BG_MSG: {
1688                int i=0, num=0;
1689                long start = SystemClock.uptimeMillis();
1690                long[] tmp = new long[1];
1691                do {
1692                    ProcessRecord proc;
1693                    int procState;
1694                    int pid;
1695                    synchronized (ActivityManagerService.this) {
1696                        if (i >= mPendingPssProcesses.size()) {
1697                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1698                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1699                            mPendingPssProcesses.clear();
1700                            return;
1701                        }
1702                        proc = mPendingPssProcesses.get(i);
1703                        procState = proc.pssProcState;
1704                        if (proc.thread != null && procState == proc.setProcState) {
1705                            pid = proc.pid;
1706                        } else {
1707                            proc = null;
1708                            pid = 0;
1709                        }
1710                        i++;
1711                    }
1712                    if (proc != null) {
1713                        long pss = Debug.getPss(pid, tmp);
1714                        synchronized (ActivityManagerService.this) {
1715                            if (proc.thread != null && proc.setProcState == procState
1716                                    && proc.pid == pid) {
1717                                num++;
1718                                proc.lastPssTime = SystemClock.uptimeMillis();
1719                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1720                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1721                                        + ": " + pss + " lastPss=" + proc.lastPss
1722                                        + " state=" + ProcessList.makeProcStateString(procState));
1723                                if (proc.initialIdlePss == 0) {
1724                                    proc.initialIdlePss = pss;
1725                                }
1726                                proc.lastPss = pss;
1727                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1728                                    proc.lastCachedPss = pss;
1729                                }
1730                            }
1731                        }
1732                    }
1733                } while (true);
1734            }
1735            }
1736        }
1737    };
1738
1739    public void setSystemProcess() {
1740        try {
1741            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1742            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1743            ServiceManager.addService("meminfo", new MemBinder(this));
1744            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1745            ServiceManager.addService("dbinfo", new DbBinder(this));
1746            if (MONITOR_CPU_USAGE) {
1747                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1748            }
1749            ServiceManager.addService("permission", new PermissionController(this));
1750
1751            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1752                    "android", STOCK_PM_FLAGS);
1753            mSystemThread.installSystemApplicationInfo(info);
1754
1755            synchronized (this) {
1756                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1757                app.persistent = true;
1758                app.pid = MY_PID;
1759                app.maxAdj = ProcessList.SYSTEM_ADJ;
1760                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1761                mProcessNames.put(app.processName, app.uid, app);
1762                synchronized (mPidsSelfLocked) {
1763                    mPidsSelfLocked.put(app.pid, app);
1764                }
1765                updateLruProcessLocked(app, false, null);
1766                updateOomAdjLocked();
1767            }
1768        } catch (PackageManager.NameNotFoundException e) {
1769            throw new RuntimeException(
1770                    "Unable to find android system package", e);
1771        }
1772    }
1773
1774    public void setWindowManager(WindowManagerService wm) {
1775        mWindowManager = wm;
1776        mStackSupervisor.setWindowManager(wm);
1777    }
1778
1779    public void startObservingNativeCrashes() {
1780        final NativeCrashListener ncl = new NativeCrashListener(this);
1781        ncl.start();
1782    }
1783
1784    public IAppOpsService getAppOpsService() {
1785        return mAppOpsService;
1786    }
1787
1788    static class MemBinder extends Binder {
1789        ActivityManagerService mActivityManagerService;
1790        MemBinder(ActivityManagerService activityManagerService) {
1791            mActivityManagerService = activityManagerService;
1792        }
1793
1794        @Override
1795        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1796            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1797                    != PackageManager.PERMISSION_GRANTED) {
1798                pw.println("Permission Denial: can't dump meminfo from from pid="
1799                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1800                        + " without permission " + android.Manifest.permission.DUMP);
1801                return;
1802            }
1803
1804            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1805        }
1806    }
1807
1808    static class GraphicsBinder extends Binder {
1809        ActivityManagerService mActivityManagerService;
1810        GraphicsBinder(ActivityManagerService activityManagerService) {
1811            mActivityManagerService = activityManagerService;
1812        }
1813
1814        @Override
1815        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1816            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1817                    != PackageManager.PERMISSION_GRANTED) {
1818                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1819                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1820                        + " without permission " + android.Manifest.permission.DUMP);
1821                return;
1822            }
1823
1824            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1825        }
1826    }
1827
1828    static class DbBinder extends Binder {
1829        ActivityManagerService mActivityManagerService;
1830        DbBinder(ActivityManagerService activityManagerService) {
1831            mActivityManagerService = activityManagerService;
1832        }
1833
1834        @Override
1835        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1836            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1837                    != PackageManager.PERMISSION_GRANTED) {
1838                pw.println("Permission Denial: can't dump dbinfo from from pid="
1839                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1840                        + " without permission " + android.Manifest.permission.DUMP);
1841                return;
1842            }
1843
1844            mActivityManagerService.dumpDbInfo(fd, pw, args);
1845        }
1846    }
1847
1848    static class CpuBinder extends Binder {
1849        ActivityManagerService mActivityManagerService;
1850        CpuBinder(ActivityManagerService activityManagerService) {
1851            mActivityManagerService = activityManagerService;
1852        }
1853
1854        @Override
1855        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1856            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1857                    != PackageManager.PERMISSION_GRANTED) {
1858                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1859                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1860                        + " without permission " + android.Manifest.permission.DUMP);
1861                return;
1862            }
1863
1864            synchronized (mActivityManagerService.mProcessCpuThread) {
1865                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1866                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1867                        SystemClock.uptimeMillis()));
1868            }
1869        }
1870    }
1871
1872    public static final class Lifecycle extends SystemService {
1873        private final ActivityManagerService mService;
1874
1875        public Lifecycle(Context context) {
1876            super(context);
1877            mService = new ActivityManagerService(context);
1878        }
1879
1880        @Override
1881        public void onStart() {
1882            mService.start();
1883        }
1884
1885        public ActivityManagerService getService() {
1886            return mService;
1887        }
1888    }
1889
1890    // Note: This method is invoked on the main thread but may need to attach various
1891    // handlers to other threads.  So take care to be explicit about the looper.
1892    public ActivityManagerService(Context systemContext) {
1893        mContext = systemContext;
1894        mFactoryTest = FactoryTest.getMode();
1895        mSystemThread = ActivityThread.currentActivityThread();
1896
1897        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1898
1899        mHandlerThread = new ServiceThread(TAG,
1900                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1901        mHandlerThread.start();
1902        mHandler = new MainHandler(mHandlerThread.getLooper());
1903
1904        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1905                "foreground", BROADCAST_FG_TIMEOUT, false);
1906        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1907                "background", BROADCAST_BG_TIMEOUT, true);
1908        mBroadcastQueues[0] = mFgBroadcastQueue;
1909        mBroadcastQueues[1] = mBgBroadcastQueue;
1910
1911        mServices = new ActiveServices(this);
1912        mProviderMap = new ProviderMap(this);
1913
1914        // TODO: Move creation of battery stats service outside of activity manager service.
1915        File dataDir = Environment.getDataDirectory();
1916        File systemDir = new File(dataDir, "system");
1917        systemDir.mkdirs();
1918        mBatteryStatsService = new BatteryStatsService(new File(
1919                systemDir, "batterystats.bin").toString(), mHandler);
1920        mBatteryStatsService.getActiveStatistics().readLocked();
1921        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1922        mOnBattery = DEBUG_POWER ? true
1923                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1924        mBatteryStatsService.getActiveStatistics().setCallback(this);
1925
1926        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1927
1928        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1929        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1930
1931        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1932
1933        // User 0 is the first and only user that runs at boot.
1934        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1935        mUserLru.add(Integer.valueOf(0));
1936        updateStartedUserArrayLocked();
1937
1938        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1939            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1940
1941        mConfiguration.setToDefaults();
1942        mConfiguration.setLocale(Locale.getDefault());
1943
1944        mConfigurationSeq = mConfiguration.seq = 1;
1945        mProcessCpuTracker.init();
1946
1947        mHasRecents = mContext.getResources().getBoolean(
1948                com.android.internal.R.bool.config_hasRecents);
1949
1950        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1951        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1952        mStackSupervisor = new ActivityStackSupervisor(this);
1953
1954        mProcessCpuThread = new Thread("CpuTracker") {
1955            @Override
1956            public void run() {
1957                while (true) {
1958                    try {
1959                        try {
1960                            synchronized(this) {
1961                                final long now = SystemClock.uptimeMillis();
1962                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1963                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1964                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1965                                //        + ", write delay=" + nextWriteDelay);
1966                                if (nextWriteDelay < nextCpuDelay) {
1967                                    nextCpuDelay = nextWriteDelay;
1968                                }
1969                                if (nextCpuDelay > 0) {
1970                                    mProcessCpuMutexFree.set(true);
1971                                    this.wait(nextCpuDelay);
1972                                }
1973                            }
1974                        } catch (InterruptedException e) {
1975                        }
1976                        updateCpuStatsNow();
1977                    } catch (Exception e) {
1978                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1979                    }
1980                }
1981            }
1982        };
1983
1984        Watchdog.getInstance().addMonitor(this);
1985        Watchdog.getInstance().addThread(mHandler);
1986    }
1987
1988    private void start() {
1989        mProcessCpuThread.start();
1990
1991        mBatteryStatsService.publish(mContext);
1992        mUsageStatsService.publish(mContext);
1993        mAppOpsService.publish(mContext);
1994
1995        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
1996    }
1997
1998    @Override
1999    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2000            throws RemoteException {
2001        if (code == SYSPROPS_TRANSACTION) {
2002            // We need to tell all apps about the system property change.
2003            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2004            synchronized(this) {
2005                final int NP = mProcessNames.getMap().size();
2006                for (int ip=0; ip<NP; ip++) {
2007                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2008                    final int NA = apps.size();
2009                    for (int ia=0; ia<NA; ia++) {
2010                        ProcessRecord app = apps.valueAt(ia);
2011                        if (app.thread != null) {
2012                            procs.add(app.thread.asBinder());
2013                        }
2014                    }
2015                }
2016            }
2017
2018            int N = procs.size();
2019            for (int i=0; i<N; i++) {
2020                Parcel data2 = Parcel.obtain();
2021                try {
2022                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2023                } catch (RemoteException e) {
2024                }
2025                data2.recycle();
2026            }
2027        }
2028        try {
2029            return super.onTransact(code, data, reply, flags);
2030        } catch (RuntimeException e) {
2031            // The activity manager only throws security exceptions, so let's
2032            // log all others.
2033            if (!(e instanceof SecurityException)) {
2034                Slog.wtf(TAG, "Activity Manager Crash", e);
2035            }
2036            throw e;
2037        }
2038    }
2039
2040    void updateCpuStats() {
2041        final long now = SystemClock.uptimeMillis();
2042        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2043            return;
2044        }
2045        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2046            synchronized (mProcessCpuThread) {
2047                mProcessCpuThread.notify();
2048            }
2049        }
2050    }
2051
2052    void updateCpuStatsNow() {
2053        synchronized (mProcessCpuThread) {
2054            mProcessCpuMutexFree.set(false);
2055            final long now = SystemClock.uptimeMillis();
2056            boolean haveNewCpuStats = false;
2057
2058            if (MONITOR_CPU_USAGE &&
2059                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2060                mLastCpuTime.set(now);
2061                haveNewCpuStats = true;
2062                mProcessCpuTracker.update();
2063                //Slog.i(TAG, mProcessCpu.printCurrentState());
2064                //Slog.i(TAG, "Total CPU usage: "
2065                //        + mProcessCpu.getTotalCpuPercent() + "%");
2066
2067                // Slog the cpu usage if the property is set.
2068                if ("true".equals(SystemProperties.get("events.cpu"))) {
2069                    int user = mProcessCpuTracker.getLastUserTime();
2070                    int system = mProcessCpuTracker.getLastSystemTime();
2071                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2072                    int irq = mProcessCpuTracker.getLastIrqTime();
2073                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2074                    int idle = mProcessCpuTracker.getLastIdleTime();
2075
2076                    int total = user + system + iowait + irq + softIrq + idle;
2077                    if (total == 0) total = 1;
2078
2079                    EventLog.writeEvent(EventLogTags.CPU,
2080                            ((user+system+iowait+irq+softIrq) * 100) / total,
2081                            (user * 100) / total,
2082                            (system * 100) / total,
2083                            (iowait * 100) / total,
2084                            (irq * 100) / total,
2085                            (softIrq * 100) / total);
2086                }
2087            }
2088
2089            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2090            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2091            synchronized(bstats) {
2092                synchronized(mPidsSelfLocked) {
2093                    if (haveNewCpuStats) {
2094                        if (mOnBattery) {
2095                            int perc = bstats.startAddingCpuLocked();
2096                            int totalUTime = 0;
2097                            int totalSTime = 0;
2098                            final int N = mProcessCpuTracker.countStats();
2099                            for (int i=0; i<N; i++) {
2100                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2101                                if (!st.working) {
2102                                    continue;
2103                                }
2104                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2105                                int otherUTime = (st.rel_utime*perc)/100;
2106                                int otherSTime = (st.rel_stime*perc)/100;
2107                                totalUTime += otherUTime;
2108                                totalSTime += otherSTime;
2109                                if (pr != null) {
2110                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
2111                                            st.name, st.pid);
2112                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2113                                            st.rel_stime-otherSTime);
2114                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2115                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2116                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
2117                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2118                                    if (ps == null) {
2119                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
2120                                                "(Unknown)");
2121                                    }
2122                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2123                                            st.rel_stime-otherSTime);
2124                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2125                                } else {
2126                                    BatteryStatsImpl.Uid.Proc ps =
2127                                            bstats.getProcessStatsLocked(st.name, st.pid);
2128                                    if (ps != null) {
2129                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2130                                                st.rel_stime-otherSTime);
2131                                        ps.addSpeedStepTimes(cpuSpeedTimes);
2132                                    }
2133                                }
2134                            }
2135                            bstats.finishAddingCpuLocked(perc, totalUTime,
2136                                    totalSTime, cpuSpeedTimes);
2137                        }
2138                    }
2139                }
2140
2141                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2142                    mLastWriteTime = now;
2143                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2144                }
2145            }
2146        }
2147    }
2148
2149    @Override
2150    public void batteryNeedsCpuUpdate() {
2151        updateCpuStatsNow();
2152    }
2153
2154    @Override
2155    public void batteryPowerChanged(boolean onBattery) {
2156        // When plugging in, update the CPU stats first before changing
2157        // the plug state.
2158        updateCpuStatsNow();
2159        synchronized (this) {
2160            synchronized(mPidsSelfLocked) {
2161                mOnBattery = DEBUG_POWER ? true : onBattery;
2162            }
2163        }
2164    }
2165
2166    /**
2167     * Initialize the application bind args. These are passed to each
2168     * process when the bindApplication() IPC is sent to the process. They're
2169     * lazily setup to make sure the services are running when they're asked for.
2170     */
2171    private HashMap<String, IBinder> getCommonServicesLocked() {
2172        if (mAppBindArgs == null) {
2173            mAppBindArgs = new HashMap<String, IBinder>();
2174
2175            // Setup the application init args
2176            mAppBindArgs.put("package", ServiceManager.getService("package"));
2177            mAppBindArgs.put("window", ServiceManager.getService("window"));
2178            mAppBindArgs.put(Context.ALARM_SERVICE,
2179                    ServiceManager.getService(Context.ALARM_SERVICE));
2180        }
2181        return mAppBindArgs;
2182    }
2183
2184    final void setFocusedActivityLocked(ActivityRecord r) {
2185        if (mFocusedActivity != r) {
2186            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2187            mFocusedActivity = r;
2188            mStackSupervisor.setFocusedStack(r);
2189            if (r != null) {
2190                mWindowManager.setFocusedApp(r.appToken, true);
2191            }
2192            applyUpdateLockStateLocked(r);
2193        }
2194    }
2195
2196    @Override
2197    public void setFocusedStack(int stackId) {
2198        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2199        synchronized (ActivityManagerService.this) {
2200            ActivityStack stack = mStackSupervisor.getStack(stackId);
2201            if (stack != null) {
2202                ActivityRecord r = stack.topRunningActivityLocked(null);
2203                if (r != null) {
2204                    setFocusedActivityLocked(r);
2205                }
2206            }
2207        }
2208    }
2209
2210    @Override
2211    public void notifyActivityDrawn(IBinder token) {
2212        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2213        synchronized (this) {
2214            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2215            if (r != null) {
2216                r.task.stack.notifyActivityDrawnLocked(r);
2217            }
2218        }
2219    }
2220
2221    final void applyUpdateLockStateLocked(ActivityRecord r) {
2222        // Modifications to the UpdateLock state are done on our handler, outside
2223        // the activity manager's locks.  The new state is determined based on the
2224        // state *now* of the relevant activity record.  The object is passed to
2225        // the handler solely for logging detail, not to be consulted/modified.
2226        final boolean nextState = r != null && r.immersive;
2227        mHandler.sendMessage(
2228                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2229    }
2230
2231    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2232        Message msg = Message.obtain();
2233        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2234        msg.obj = r.task.askedCompatMode ? null : r;
2235        mHandler.sendMessage(msg);
2236    }
2237
2238    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2239            String what, Object obj, ProcessRecord srcApp) {
2240        app.lastActivityTime = now;
2241
2242        if (app.activities.size() > 0) {
2243            // Don't want to touch dependent processes that are hosting activities.
2244            return index;
2245        }
2246
2247        int lrui = mLruProcesses.lastIndexOf(app);
2248        if (lrui < 0) {
2249            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2250                    + what + " " + obj + " from " + srcApp);
2251            return index;
2252        }
2253
2254        if (lrui >= index) {
2255            // Don't want to cause this to move dependent processes *back* in the
2256            // list as if they were less frequently used.
2257            return index;
2258        }
2259
2260        if (lrui >= mLruProcessActivityStart) {
2261            // Don't want to touch dependent processes that are hosting activities.
2262            return index;
2263        }
2264
2265        mLruProcesses.remove(lrui);
2266        if (index > 0) {
2267            index--;
2268        }
2269        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2270                + " in LRU list: " + app);
2271        mLruProcesses.add(index, app);
2272        return index;
2273    }
2274
2275    final void removeLruProcessLocked(ProcessRecord app) {
2276        int lrui = mLruProcesses.lastIndexOf(app);
2277        if (lrui >= 0) {
2278            if (lrui <= mLruProcessActivityStart) {
2279                mLruProcessActivityStart--;
2280            }
2281            if (lrui <= mLruProcessServiceStart) {
2282                mLruProcessServiceStart--;
2283            }
2284            mLruProcesses.remove(lrui);
2285        }
2286    }
2287
2288    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2289            ProcessRecord client) {
2290        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2291        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2292        if (!activityChange && hasActivity) {
2293            // The process has activties, so we are only going to allow activity-based
2294            // adjustments move it.  It should be kept in the front of the list with other
2295            // processes that have activities, and we don't want those to change their
2296            // order except due to activity operations.
2297            return;
2298        }
2299
2300        mLruSeq++;
2301        final long now = SystemClock.uptimeMillis();
2302        app.lastActivityTime = now;
2303
2304        // First a quick reject: if the app is already at the position we will
2305        // put it, then there is nothing to do.
2306        if (hasActivity) {
2307            final int N = mLruProcesses.size();
2308            if (N > 0 && mLruProcesses.get(N-1) == app) {
2309                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2310                return;
2311            }
2312        } else {
2313            if (mLruProcessServiceStart > 0
2314                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2315                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2316                return;
2317            }
2318        }
2319
2320        int lrui = mLruProcesses.lastIndexOf(app);
2321
2322        if (app.persistent && lrui >= 0) {
2323            // We don't care about the position of persistent processes, as long as
2324            // they are in the list.
2325            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2326            return;
2327        }
2328
2329        /* In progress: compute new position first, so we can avoid doing work
2330           if the process is not actually going to move.  Not yet working.
2331        int addIndex;
2332        int nextIndex;
2333        boolean inActivity = false, inService = false;
2334        if (hasActivity) {
2335            // Process has activities, put it at the very tipsy-top.
2336            addIndex = mLruProcesses.size();
2337            nextIndex = mLruProcessServiceStart;
2338            inActivity = true;
2339        } else if (hasService) {
2340            // Process has services, put it at the top of the service list.
2341            addIndex = mLruProcessActivityStart;
2342            nextIndex = mLruProcessServiceStart;
2343            inActivity = true;
2344            inService = true;
2345        } else  {
2346            // Process not otherwise of interest, it goes to the top of the non-service area.
2347            addIndex = mLruProcessServiceStart;
2348            if (client != null) {
2349                int clientIndex = mLruProcesses.lastIndexOf(client);
2350                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2351                        + app);
2352                if (clientIndex >= 0 && addIndex > clientIndex) {
2353                    addIndex = clientIndex;
2354                }
2355            }
2356            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2357        }
2358
2359        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2360                + mLruProcessActivityStart + "): " + app);
2361        */
2362
2363        if (lrui >= 0) {
2364            if (lrui < mLruProcessActivityStart) {
2365                mLruProcessActivityStart--;
2366            }
2367            if (lrui < mLruProcessServiceStart) {
2368                mLruProcessServiceStart--;
2369            }
2370            /*
2371            if (addIndex > lrui) {
2372                addIndex--;
2373            }
2374            if (nextIndex > lrui) {
2375                nextIndex--;
2376            }
2377            */
2378            mLruProcesses.remove(lrui);
2379        }
2380
2381        /*
2382        mLruProcesses.add(addIndex, app);
2383        if (inActivity) {
2384            mLruProcessActivityStart++;
2385        }
2386        if (inService) {
2387            mLruProcessActivityStart++;
2388        }
2389        */
2390
2391        int nextIndex;
2392        if (hasActivity) {
2393            final int N = mLruProcesses.size();
2394            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2395                // Process doesn't have activities, but has clients with
2396                // activities...  move it up, but one below the top (the top
2397                // should always have a real activity).
2398                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2399                mLruProcesses.add(N-1, app);
2400                // To keep it from spamming the LRU list (by making a bunch of clients),
2401                // we will push down any other entries owned by the app.
2402                final int uid = app.info.uid;
2403                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2404                    ProcessRecord subProc = mLruProcesses.get(i);
2405                    if (subProc.info.uid == uid) {
2406                        // We want to push this one down the list.  If the process after
2407                        // it is for the same uid, however, don't do so, because we don't
2408                        // want them internally to be re-ordered.
2409                        if (mLruProcesses.get(i-1).info.uid != uid) {
2410                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2411                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2412                            ProcessRecord tmp = mLruProcesses.get(i);
2413                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2414                            mLruProcesses.set(i-1, tmp);
2415                            i--;
2416                        }
2417                    } else {
2418                        // A gap, we can stop here.
2419                        break;
2420                    }
2421                }
2422            } else {
2423                // Process has activities, put it at the very tipsy-top.
2424                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2425                mLruProcesses.add(app);
2426            }
2427            nextIndex = mLruProcessServiceStart;
2428        } else if (hasService) {
2429            // Process has services, put it at the top of the service list.
2430            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2431            mLruProcesses.add(mLruProcessActivityStart, app);
2432            nextIndex = mLruProcessServiceStart;
2433            mLruProcessActivityStart++;
2434        } else  {
2435            // Process not otherwise of interest, it goes to the top of the non-service area.
2436            int index = mLruProcessServiceStart;
2437            if (client != null) {
2438                // If there is a client, don't allow the process to be moved up higher
2439                // in the list than that client.
2440                int clientIndex = mLruProcesses.lastIndexOf(client);
2441                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2442                        + " when updating " + app);
2443                if (clientIndex <= lrui) {
2444                    // Don't allow the client index restriction to push it down farther in the
2445                    // list than it already is.
2446                    clientIndex = lrui;
2447                }
2448                if (clientIndex >= 0 && index > clientIndex) {
2449                    index = clientIndex;
2450                }
2451            }
2452            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2453            mLruProcesses.add(index, app);
2454            nextIndex = index-1;
2455            mLruProcessActivityStart++;
2456            mLruProcessServiceStart++;
2457        }
2458
2459        // If the app is currently using a content provider or service,
2460        // bump those processes as well.
2461        for (int j=app.connections.size()-1; j>=0; j--) {
2462            ConnectionRecord cr = app.connections.valueAt(j);
2463            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2464                    && cr.binding.service.app != null
2465                    && cr.binding.service.app.lruSeq != mLruSeq
2466                    && !cr.binding.service.app.persistent) {
2467                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2468                        "service connection", cr, app);
2469            }
2470        }
2471        for (int j=app.conProviders.size()-1; j>=0; j--) {
2472            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2473            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2474                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2475                        "provider reference", cpr, app);
2476            }
2477        }
2478    }
2479
2480    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2481        if (uid == Process.SYSTEM_UID) {
2482            // The system gets to run in any process.  If there are multiple
2483            // processes with the same uid, just pick the first (this
2484            // should never happen).
2485            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2486            if (procs == null) return null;
2487            final int N = procs.size();
2488            for (int i = 0; i < N; i++) {
2489                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2490            }
2491        }
2492        ProcessRecord proc = mProcessNames.get(processName, uid);
2493        if (false && proc != null && !keepIfLarge
2494                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2495                && proc.lastCachedPss >= 4000) {
2496            // Turn this condition on to cause killing to happen regularly, for testing.
2497            if (proc.baseProcessTracker != null) {
2498                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2499            }
2500            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2501                    + "k from cached");
2502        } else if (proc != null && !keepIfLarge
2503                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2504                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2505            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2506            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2507                if (proc.baseProcessTracker != null) {
2508                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2509                }
2510                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2511                        + "k from cached");
2512            }
2513        }
2514        return proc;
2515    }
2516
2517    void ensurePackageDexOpt(String packageName) {
2518        IPackageManager pm = AppGlobals.getPackageManager();
2519        try {
2520            if (pm.performDexOpt(packageName)) {
2521                mDidDexOpt = true;
2522            }
2523        } catch (RemoteException e) {
2524        }
2525    }
2526
2527    boolean isNextTransitionForward() {
2528        int transit = mWindowManager.getPendingAppTransition();
2529        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2530                || transit == AppTransition.TRANSIT_TASK_OPEN
2531                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2532    }
2533
2534    final ProcessRecord startProcessLocked(String processName,
2535            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2536            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2537            boolean isolated, boolean keepIfLarge) {
2538        ProcessRecord app;
2539        if (!isolated) {
2540            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2541        } else {
2542            // If this is an isolated process, it can't re-use an existing process.
2543            app = null;
2544        }
2545        // We don't have to do anything more if:
2546        // (1) There is an existing application record; and
2547        // (2) The caller doesn't think it is dead, OR there is no thread
2548        //     object attached to it so we know it couldn't have crashed; and
2549        // (3) There is a pid assigned to it, so it is either starting or
2550        //     already running.
2551        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2552                + " app=" + app + " knownToBeDead=" + knownToBeDead
2553                + " thread=" + (app != null ? app.thread : null)
2554                + " pid=" + (app != null ? app.pid : -1));
2555        if (app != null && app.pid > 0) {
2556            if (!knownToBeDead || app.thread == null) {
2557                // We already have the app running, or are waiting for it to
2558                // come up (we have a pid but not yet its thread), so keep it.
2559                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2560                // If this is a new package in the process, add the package to the list
2561                app.addPackage(info.packageName, mProcessStats);
2562                return app;
2563            }
2564
2565            // An application record is attached to a previous process,
2566            // clean it up now.
2567            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2568            handleAppDiedLocked(app, true, true);
2569        }
2570
2571        String hostingNameStr = hostingName != null
2572                ? hostingName.flattenToShortString() : null;
2573
2574        if (!isolated) {
2575            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2576                // If we are in the background, then check to see if this process
2577                // is bad.  If so, we will just silently fail.
2578                if (mBadProcesses.get(info.processName, info.uid) != null) {
2579                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2580                            + "/" + info.processName);
2581                    return null;
2582                }
2583            } else {
2584                // When the user is explicitly starting a process, then clear its
2585                // crash count so that we won't make it bad until they see at
2586                // least one crash dialog again, and make the process good again
2587                // if it had been bad.
2588                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2589                        + "/" + info.processName);
2590                mProcessCrashTimes.remove(info.processName, info.uid);
2591                if (mBadProcesses.get(info.processName, info.uid) != null) {
2592                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2593                            UserHandle.getUserId(info.uid), info.uid,
2594                            info.processName);
2595                    mBadProcesses.remove(info.processName, info.uid);
2596                    if (app != null) {
2597                        app.bad = false;
2598                    }
2599                }
2600            }
2601        }
2602
2603        if (app == null) {
2604            app = newProcessRecordLocked(info, processName, isolated);
2605            if (app == null) {
2606                Slog.w(TAG, "Failed making new process record for "
2607                        + processName + "/" + info.uid + " isolated=" + isolated);
2608                return null;
2609            }
2610            mProcessNames.put(processName, app.uid, app);
2611            if (isolated) {
2612                mIsolatedProcesses.put(app.uid, app);
2613            }
2614        } else {
2615            // If this is a new package in the process, add the package to the list
2616            app.addPackage(info.packageName, mProcessStats);
2617        }
2618
2619        // If the system is not ready yet, then hold off on starting this
2620        // process until it is.
2621        if (!mProcessesReady
2622                && !isAllowedWhileBooting(info)
2623                && !allowWhileBooting) {
2624            if (!mProcessesOnHold.contains(app)) {
2625                mProcessesOnHold.add(app);
2626            }
2627            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2628            return app;
2629        }
2630
2631        startProcessLocked(app, hostingType, hostingNameStr);
2632        return (app.pid != 0) ? app : null;
2633    }
2634
2635    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2636        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2637    }
2638
2639    private final void startProcessLocked(ProcessRecord app,
2640            String hostingType, String hostingNameStr) {
2641        if (app.pid > 0 && app.pid != MY_PID) {
2642            synchronized (mPidsSelfLocked) {
2643                mPidsSelfLocked.remove(app.pid);
2644                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2645            }
2646            app.setPid(0);
2647        }
2648
2649        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2650                "startProcessLocked removing on hold: " + app);
2651        mProcessesOnHold.remove(app);
2652
2653        updateCpuStats();
2654
2655        try {
2656            int uid = app.uid;
2657
2658            int[] gids = null;
2659            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2660            if (!app.isolated) {
2661                int[] permGids = null;
2662                try {
2663                    final PackageManager pm = mContext.getPackageManager();
2664                    permGids = pm.getPackageGids(app.info.packageName);
2665
2666                    if (Environment.isExternalStorageEmulated()) {
2667                        if (pm.checkPermission(
2668                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2669                                app.info.packageName) == PERMISSION_GRANTED) {
2670                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2671                        } else {
2672                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2673                        }
2674                    }
2675                } catch (PackageManager.NameNotFoundException e) {
2676                    Slog.w(TAG, "Unable to retrieve gids", e);
2677                }
2678
2679                /*
2680                 * Add shared application GID so applications can share some
2681                 * resources like shared libraries
2682                 */
2683                if (permGids == null) {
2684                    gids = new int[1];
2685                } else {
2686                    gids = new int[permGids.length + 1];
2687                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2688                }
2689                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2690            }
2691            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2692                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2693                        && mTopComponent != null
2694                        && app.processName.equals(mTopComponent.getPackageName())) {
2695                    uid = 0;
2696                }
2697                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2698                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2699                    uid = 0;
2700                }
2701            }
2702            int debugFlags = 0;
2703            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2704                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2705                // Also turn on CheckJNI for debuggable apps. It's quite
2706                // awkward to turn on otherwise.
2707                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2708            }
2709            // Run the app in safe mode if its manifest requests so or the
2710            // system is booted in safe mode.
2711            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2712                Zygote.systemInSafeMode == true) {
2713                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2714            }
2715            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2716                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2717            }
2718            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2719                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2720            }
2721            if ("1".equals(SystemProperties.get("debug.assert"))) {
2722                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2723            }
2724
2725            // Start the process.  It will either succeed and return a result containing
2726            // the PID of the new process, or else throw a RuntimeException.
2727            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2728                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2729                    app.info.targetSdkVersion, app.info.seinfo, null);
2730
2731            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2732            synchronized (bs) {
2733                if (bs.isOnBattery()) {
2734                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2735                }
2736            }
2737
2738            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2739                    UserHandle.getUserId(uid), startResult.pid, uid,
2740                    app.processName, hostingType,
2741                    hostingNameStr != null ? hostingNameStr : "");
2742
2743            if (app.persistent) {
2744                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2745            }
2746
2747            StringBuilder buf = mStringBuilder;
2748            buf.setLength(0);
2749            buf.append("Start proc ");
2750            buf.append(app.processName);
2751            buf.append(" for ");
2752            buf.append(hostingType);
2753            if (hostingNameStr != null) {
2754                buf.append(" ");
2755                buf.append(hostingNameStr);
2756            }
2757            buf.append(": pid=");
2758            buf.append(startResult.pid);
2759            buf.append(" uid=");
2760            buf.append(uid);
2761            buf.append(" gids={");
2762            if (gids != null) {
2763                for (int gi=0; gi<gids.length; gi++) {
2764                    if (gi != 0) buf.append(", ");
2765                    buf.append(gids[gi]);
2766
2767                }
2768            }
2769            buf.append("}");
2770            Slog.i(TAG, buf.toString());
2771            app.setPid(startResult.pid);
2772            app.usingWrapper = startResult.usingWrapper;
2773            app.removed = false;
2774            synchronized (mPidsSelfLocked) {
2775                this.mPidsSelfLocked.put(startResult.pid, app);
2776                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2777                msg.obj = app;
2778                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2779                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2780            }
2781        } catch (RuntimeException e) {
2782            // XXX do better error recovery.
2783            app.setPid(0);
2784            Slog.e(TAG, "Failure starting process " + app.processName, e);
2785        }
2786    }
2787
2788    void updateUsageStats(ActivityRecord component, boolean resumed) {
2789        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2790        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2791        if (resumed) {
2792            mUsageStatsService.noteResumeComponent(component.realActivity);
2793            synchronized (stats) {
2794                stats.noteActivityResumedLocked(component.app.uid);
2795            }
2796        } else {
2797            mUsageStatsService.notePauseComponent(component.realActivity);
2798            synchronized (stats) {
2799                stats.noteActivityPausedLocked(component.app.uid);
2800            }
2801        }
2802    }
2803
2804    Intent getHomeIntent() {
2805        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2806        intent.setComponent(mTopComponent);
2807        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2808            intent.addCategory(Intent.CATEGORY_HOME);
2809        }
2810        return intent;
2811    }
2812
2813    boolean startHomeActivityLocked(int userId) {
2814        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2815                && mTopAction == null) {
2816            // We are running in factory test mode, but unable to find
2817            // the factory test app, so just sit around displaying the
2818            // error message and don't try to start anything.
2819            return false;
2820        }
2821        Intent intent = getHomeIntent();
2822        ActivityInfo aInfo =
2823            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2824        if (aInfo != null) {
2825            intent.setComponent(new ComponentName(
2826                    aInfo.applicationInfo.packageName, aInfo.name));
2827            // Don't do this if the home app is currently being
2828            // instrumented.
2829            aInfo = new ActivityInfo(aInfo);
2830            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2831            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2832                    aInfo.applicationInfo.uid, true);
2833            if (app == null || app.instrumentationClass == null) {
2834                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2835                mStackSupervisor.startHomeActivity(intent, aInfo);
2836            }
2837        }
2838
2839        return true;
2840    }
2841
2842    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2843        ActivityInfo ai = null;
2844        ComponentName comp = intent.getComponent();
2845        try {
2846            if (comp != null) {
2847                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2848            } else {
2849                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2850                        intent,
2851                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2852                            flags, userId);
2853
2854                if (info != null) {
2855                    ai = info.activityInfo;
2856                }
2857            }
2858        } catch (RemoteException e) {
2859            // ignore
2860        }
2861
2862        return ai;
2863    }
2864
2865    /**
2866     * Starts the "new version setup screen" if appropriate.
2867     */
2868    void startSetupActivityLocked() {
2869        // Only do this once per boot.
2870        if (mCheckedForSetup) {
2871            return;
2872        }
2873
2874        // We will show this screen if the current one is a different
2875        // version than the last one shown, and we are not running in
2876        // low-level factory test mode.
2877        final ContentResolver resolver = mContext.getContentResolver();
2878        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2879                Settings.Global.getInt(resolver,
2880                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2881            mCheckedForSetup = true;
2882
2883            // See if we should be showing the platform update setup UI.
2884            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2885            List<ResolveInfo> ris = mContext.getPackageManager()
2886                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2887
2888            // We don't allow third party apps to replace this.
2889            ResolveInfo ri = null;
2890            for (int i=0; ris != null && i<ris.size(); i++) {
2891                if ((ris.get(i).activityInfo.applicationInfo.flags
2892                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2893                    ri = ris.get(i);
2894                    break;
2895                }
2896            }
2897
2898            if (ri != null) {
2899                String vers = ri.activityInfo.metaData != null
2900                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2901                        : null;
2902                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2903                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2904                            Intent.METADATA_SETUP_VERSION);
2905                }
2906                String lastVers = Settings.Secure.getString(
2907                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2908                if (vers != null && !vers.equals(lastVers)) {
2909                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2910                    intent.setComponent(new ComponentName(
2911                            ri.activityInfo.packageName, ri.activityInfo.name));
2912                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2913                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2914                }
2915            }
2916        }
2917    }
2918
2919    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2920        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2921    }
2922
2923    void enforceNotIsolatedCaller(String caller) {
2924        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2925            throw new SecurityException("Isolated process not allowed to call " + caller);
2926        }
2927    }
2928
2929    @Override
2930    public int getFrontActivityScreenCompatMode() {
2931        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2932        synchronized (this) {
2933            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2934        }
2935    }
2936
2937    @Override
2938    public void setFrontActivityScreenCompatMode(int mode) {
2939        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2940                "setFrontActivityScreenCompatMode");
2941        synchronized (this) {
2942            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2943        }
2944    }
2945
2946    @Override
2947    public int getPackageScreenCompatMode(String packageName) {
2948        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2949        synchronized (this) {
2950            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2951        }
2952    }
2953
2954    @Override
2955    public void setPackageScreenCompatMode(String packageName, int mode) {
2956        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2957                "setPackageScreenCompatMode");
2958        synchronized (this) {
2959            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2960        }
2961    }
2962
2963    @Override
2964    public boolean getPackageAskScreenCompat(String packageName) {
2965        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2966        synchronized (this) {
2967            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2968        }
2969    }
2970
2971    @Override
2972    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2973        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2974                "setPackageAskScreenCompat");
2975        synchronized (this) {
2976            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2977        }
2978    }
2979
2980    private void dispatchProcessesChanged() {
2981        int N;
2982        synchronized (this) {
2983            N = mPendingProcessChanges.size();
2984            if (mActiveProcessChanges.length < N) {
2985                mActiveProcessChanges = new ProcessChangeItem[N];
2986            }
2987            mPendingProcessChanges.toArray(mActiveProcessChanges);
2988            mAvailProcessChanges.addAll(mPendingProcessChanges);
2989            mPendingProcessChanges.clear();
2990            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2991        }
2992
2993        int i = mProcessObservers.beginBroadcast();
2994        while (i > 0) {
2995            i--;
2996            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2997            if (observer != null) {
2998                try {
2999                    for (int j=0; j<N; j++) {
3000                        ProcessChangeItem item = mActiveProcessChanges[j];
3001                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3002                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3003                                    + item.pid + " uid=" + item.uid + ": "
3004                                    + item.foregroundActivities);
3005                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3006                                    item.foregroundActivities);
3007                        }
3008                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3009                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3010                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3011                            observer.onImportanceChanged(item.pid, item.uid,
3012                                    item.importance);
3013                        }
3014                    }
3015                } catch (RemoteException e) {
3016                }
3017            }
3018        }
3019        mProcessObservers.finishBroadcast();
3020    }
3021
3022    private void dispatchProcessDied(int pid, int uid) {
3023        int i = mProcessObservers.beginBroadcast();
3024        while (i > 0) {
3025            i--;
3026            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3027            if (observer != null) {
3028                try {
3029                    observer.onProcessDied(pid, uid);
3030                } catch (RemoteException e) {
3031                }
3032            }
3033        }
3034        mProcessObservers.finishBroadcast();
3035    }
3036
3037    final void doPendingActivityLaunchesLocked(boolean doResume) {
3038        final int N = mPendingActivityLaunches.size();
3039        if (N <= 0) {
3040            return;
3041        }
3042        for (int i=0; i<N; i++) {
3043            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3044            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3045                    doResume && i == (N-1), null);
3046        }
3047        mPendingActivityLaunches.clear();
3048    }
3049
3050    @Override
3051    public final int startActivity(IApplicationThread caller, String callingPackage,
3052            Intent intent, String resolvedType, IBinder resultTo,
3053            String resultWho, int requestCode, int startFlags,
3054            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3055        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3056                resultWho, requestCode,
3057                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3058    }
3059
3060    @Override
3061    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3062            Intent intent, String resolvedType, IBinder resultTo,
3063            String resultWho, int requestCode, int startFlags,
3064            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3065        enforceNotIsolatedCaller("startActivity");
3066        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3067                false, true, "startActivity", null);
3068        // TODO: Switch to user app stacks here.
3069        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3070                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3071                null, null, options, userId, null);
3072    }
3073
3074    @Override
3075    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3076            Intent intent, String resolvedType, IBinder resultTo,
3077            String resultWho, int requestCode, int startFlags, String profileFile,
3078            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3079        enforceNotIsolatedCaller("startActivityAndWait");
3080        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3081                false, true, "startActivityAndWait", null);
3082        WaitResult res = new WaitResult();
3083        // TODO: Switch to user app stacks here.
3084        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3085                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3086                res, null, options, UserHandle.getCallingUserId(), null);
3087        return res;
3088    }
3089
3090    @Override
3091    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3092            Intent intent, String resolvedType, IBinder resultTo,
3093            String resultWho, int requestCode, int startFlags, Configuration config,
3094            Bundle options, int userId) {
3095        enforceNotIsolatedCaller("startActivityWithConfig");
3096        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3097                false, true, "startActivityWithConfig", null);
3098        // TODO: Switch to user app stacks here.
3099        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3100                resolvedType, resultTo, resultWho, requestCode, startFlags,
3101                null, null, null, config, options, userId, null);
3102        return ret;
3103    }
3104
3105    @Override
3106    public int startActivityIntentSender(IApplicationThread caller,
3107            IntentSender intent, Intent fillInIntent, String resolvedType,
3108            IBinder resultTo, String resultWho, int requestCode,
3109            int flagsMask, int flagsValues, Bundle options) {
3110        enforceNotIsolatedCaller("startActivityIntentSender");
3111        // Refuse possible leaked file descriptors
3112        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3113            throw new IllegalArgumentException("File descriptors passed in Intent");
3114        }
3115
3116        IIntentSender sender = intent.getTarget();
3117        if (!(sender instanceof PendingIntentRecord)) {
3118            throw new IllegalArgumentException("Bad PendingIntent object");
3119        }
3120
3121        PendingIntentRecord pir = (PendingIntentRecord)sender;
3122
3123        synchronized (this) {
3124            // If this is coming from the currently resumed activity, it is
3125            // effectively saying that app switches are allowed at this point.
3126            final ActivityStack stack = getFocusedStack();
3127            if (stack.mResumedActivity != null &&
3128                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3129                mAppSwitchesAllowedTime = 0;
3130            }
3131        }
3132        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3133                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3134        return ret;
3135    }
3136
3137    @Override
3138    public boolean startNextMatchingActivity(IBinder callingActivity,
3139            Intent intent, Bundle options) {
3140        // Refuse possible leaked file descriptors
3141        if (intent != null && intent.hasFileDescriptors() == true) {
3142            throw new IllegalArgumentException("File descriptors passed in Intent");
3143        }
3144
3145        synchronized (this) {
3146            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3147            if (r == null) {
3148                ActivityOptions.abort(options);
3149                return false;
3150            }
3151            if (r.app == null || r.app.thread == null) {
3152                // The caller is not running...  d'oh!
3153                ActivityOptions.abort(options);
3154                return false;
3155            }
3156            intent = new Intent(intent);
3157            // The caller is not allowed to change the data.
3158            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3159            // And we are resetting to find the next component...
3160            intent.setComponent(null);
3161
3162            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3163
3164            ActivityInfo aInfo = null;
3165            try {
3166                List<ResolveInfo> resolves =
3167                    AppGlobals.getPackageManager().queryIntentActivities(
3168                            intent, r.resolvedType,
3169                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3170                            UserHandle.getCallingUserId());
3171
3172                // Look for the original activity in the list...
3173                final int N = resolves != null ? resolves.size() : 0;
3174                for (int i=0; i<N; i++) {
3175                    ResolveInfo rInfo = resolves.get(i);
3176                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3177                            && rInfo.activityInfo.name.equals(r.info.name)) {
3178                        // We found the current one...  the next matching is
3179                        // after it.
3180                        i++;
3181                        if (i<N) {
3182                            aInfo = resolves.get(i).activityInfo;
3183                        }
3184                        if (debug) {
3185                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3186                                    + "/" + r.info.name);
3187                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3188                                    + "/" + aInfo.name);
3189                        }
3190                        break;
3191                    }
3192                }
3193            } catch (RemoteException e) {
3194            }
3195
3196            if (aInfo == null) {
3197                // Nobody who is next!
3198                ActivityOptions.abort(options);
3199                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3200                return false;
3201            }
3202
3203            intent.setComponent(new ComponentName(
3204                    aInfo.applicationInfo.packageName, aInfo.name));
3205            intent.setFlags(intent.getFlags()&~(
3206                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3207                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3208                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3209                    Intent.FLAG_ACTIVITY_NEW_TASK));
3210
3211            // Okay now we need to start the new activity, replacing the
3212            // currently running activity.  This is a little tricky because
3213            // we want to start the new one as if the current one is finished,
3214            // but not finish the current one first so that there is no flicker.
3215            // And thus...
3216            final boolean wasFinishing = r.finishing;
3217            r.finishing = true;
3218
3219            // Propagate reply information over to the new activity.
3220            final ActivityRecord resultTo = r.resultTo;
3221            final String resultWho = r.resultWho;
3222            final int requestCode = r.requestCode;
3223            r.resultTo = null;
3224            if (resultTo != null) {
3225                resultTo.removeResultsLocked(r, resultWho, requestCode);
3226            }
3227
3228            final long origId = Binder.clearCallingIdentity();
3229            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3230                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3231                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3232                    options, false, null, null);
3233            Binder.restoreCallingIdentity(origId);
3234
3235            r.finishing = wasFinishing;
3236            if (res != ActivityManager.START_SUCCESS) {
3237                return false;
3238            }
3239            return true;
3240        }
3241    }
3242
3243    final int startActivityInPackage(int uid, String callingPackage,
3244            Intent intent, String resolvedType, IBinder resultTo,
3245            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3246                    IActivityContainer container) {
3247
3248        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3249                false, true, "startActivityInPackage", null);
3250
3251        // TODO: Switch to user app stacks here.
3252        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3253                resultTo, resultWho, requestCode, startFlags,
3254                null, null, null, null, options, userId, container);
3255        return ret;
3256    }
3257
3258    @Override
3259    public final int startActivities(IApplicationThread caller, String callingPackage,
3260            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3261            int userId) {
3262        enforceNotIsolatedCaller("startActivities");
3263        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3264                false, true, "startActivity", null);
3265        // TODO: Switch to user app stacks here.
3266        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3267                resolvedTypes, resultTo, options, userId);
3268        return ret;
3269    }
3270
3271    final int startActivitiesInPackage(int uid, String callingPackage,
3272            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3273            Bundle options, int userId) {
3274
3275        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3276                false, true, "startActivityInPackage", null);
3277        // TODO: Switch to user app stacks here.
3278        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3279                resultTo, options, userId);
3280        return ret;
3281    }
3282
3283    final void addRecentTaskLocked(TaskRecord task) {
3284        int N = mRecentTasks.size();
3285        // Quick case: check if the top-most recent task is the same.
3286        if (N > 0 && mRecentTasks.get(0) == task) {
3287            return;
3288        }
3289        // Remove any existing entries that are the same kind of task.
3290        for (int i=0; i<N; i++) {
3291            TaskRecord tr = mRecentTasks.get(i);
3292            if (task.userId == tr.userId
3293                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3294                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3295                tr.disposeThumbnail();
3296                mRecentTasks.remove(i);
3297                i--;
3298                N--;
3299                if (task.intent == null) {
3300                    // If the new recent task we are adding is not fully
3301                    // specified, then replace it with the existing recent task.
3302                    task = tr;
3303                }
3304            }
3305        }
3306        if (N >= MAX_RECENT_TASKS) {
3307            mRecentTasks.remove(N-1).disposeThumbnail();
3308        }
3309        mRecentTasks.add(0, task);
3310    }
3311
3312    @Override
3313    public void reportActivityFullyDrawn(IBinder token) {
3314        synchronized (this) {
3315            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3316            if (r == null) {
3317                return;
3318            }
3319            r.reportFullyDrawnLocked();
3320        }
3321    }
3322
3323    @Override
3324    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3325        synchronized (this) {
3326            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3327            if (r == null) {
3328                return;
3329            }
3330            final long origId = Binder.clearCallingIdentity();
3331            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3332            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3333                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3334            if (config != null) {
3335                r.frozenBeforeDestroy = true;
3336                if (!updateConfigurationLocked(config, r, false, false)) {
3337                    mStackSupervisor.resumeTopActivitiesLocked();
3338                }
3339            }
3340            Binder.restoreCallingIdentity(origId);
3341        }
3342    }
3343
3344    @Override
3345    public int getRequestedOrientation(IBinder token) {
3346        synchronized (this) {
3347            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3348            if (r == null) {
3349                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3350            }
3351            return mWindowManager.getAppOrientation(r.appToken);
3352        }
3353    }
3354
3355    /**
3356     * This is the internal entry point for handling Activity.finish().
3357     *
3358     * @param token The Binder token referencing the Activity we want to finish.
3359     * @param resultCode Result code, if any, from this Activity.
3360     * @param resultData Result data (Intent), if any, from this Activity.
3361     *
3362     * @return Returns true if the activity successfully finished, or false if it is still running.
3363     */
3364    @Override
3365    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3366        // Refuse possible leaked file descriptors
3367        if (resultData != null && resultData.hasFileDescriptors() == true) {
3368            throw new IllegalArgumentException("File descriptors passed in Intent");
3369        }
3370
3371        synchronized(this) {
3372            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3373            if (r == null) {
3374                return true;
3375            }
3376            if (mController != null) {
3377                // Find the first activity that is not finishing.
3378                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3379                if (next != null) {
3380                    // ask watcher if this is allowed
3381                    boolean resumeOK = true;
3382                    try {
3383                        resumeOK = mController.activityResuming(next.packageName);
3384                    } catch (RemoteException e) {
3385                        mController = null;
3386                        Watchdog.getInstance().setActivityController(null);
3387                    }
3388
3389                    if (!resumeOK) {
3390                        return false;
3391                    }
3392                }
3393            }
3394            final long origId = Binder.clearCallingIdentity();
3395            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3396                    resultData, "app-request", true);
3397            Binder.restoreCallingIdentity(origId);
3398            return res;
3399        }
3400    }
3401
3402    @Override
3403    public final void finishHeavyWeightApp() {
3404        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3405                != PackageManager.PERMISSION_GRANTED) {
3406            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3407                    + Binder.getCallingPid()
3408                    + ", uid=" + Binder.getCallingUid()
3409                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3410            Slog.w(TAG, msg);
3411            throw new SecurityException(msg);
3412        }
3413
3414        synchronized(this) {
3415            if (mHeavyWeightProcess == null) {
3416                return;
3417            }
3418
3419            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3420                    mHeavyWeightProcess.activities);
3421            for (int i=0; i<activities.size(); i++) {
3422                ActivityRecord r = activities.get(i);
3423                if (!r.finishing) {
3424                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3425                            null, "finish-heavy", true);
3426                }
3427            }
3428
3429            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3430                    mHeavyWeightProcess.userId, 0));
3431            mHeavyWeightProcess = null;
3432        }
3433    }
3434
3435    @Override
3436    public void crashApplication(int uid, int initialPid, String packageName,
3437            String message) {
3438        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3439                != PackageManager.PERMISSION_GRANTED) {
3440            String msg = "Permission Denial: crashApplication() from pid="
3441                    + Binder.getCallingPid()
3442                    + ", uid=" + Binder.getCallingUid()
3443                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3444            Slog.w(TAG, msg);
3445            throw new SecurityException(msg);
3446        }
3447
3448        synchronized(this) {
3449            ProcessRecord proc = null;
3450
3451            // Figure out which process to kill.  We don't trust that initialPid
3452            // still has any relation to current pids, so must scan through the
3453            // list.
3454            synchronized (mPidsSelfLocked) {
3455                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3456                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3457                    if (p.uid != uid) {
3458                        continue;
3459                    }
3460                    if (p.pid == initialPid) {
3461                        proc = p;
3462                        break;
3463                    }
3464                    if (p.pkgList.containsKey(packageName)) {
3465                        proc = p;
3466                    }
3467                }
3468            }
3469
3470            if (proc == null) {
3471                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3472                        + " initialPid=" + initialPid
3473                        + " packageName=" + packageName);
3474                return;
3475            }
3476
3477            if (proc.thread != null) {
3478                if (proc.pid == Process.myPid()) {
3479                    Log.w(TAG, "crashApplication: trying to crash self!");
3480                    return;
3481                }
3482                long ident = Binder.clearCallingIdentity();
3483                try {
3484                    proc.thread.scheduleCrash(message);
3485                } catch (RemoteException e) {
3486                }
3487                Binder.restoreCallingIdentity(ident);
3488            }
3489        }
3490    }
3491
3492    @Override
3493    public final void finishSubActivity(IBinder token, String resultWho,
3494            int requestCode) {
3495        synchronized(this) {
3496            final long origId = Binder.clearCallingIdentity();
3497            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3498            if (r != null) {
3499                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3500            }
3501            Binder.restoreCallingIdentity(origId);
3502        }
3503    }
3504
3505    @Override
3506    public boolean finishActivityAffinity(IBinder token) {
3507        synchronized(this) {
3508            final long origId = Binder.clearCallingIdentity();
3509            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3510            boolean res = false;
3511            if (r != null) {
3512                res = r.task.stack.finishActivityAffinityLocked(r);
3513            }
3514            Binder.restoreCallingIdentity(origId);
3515            return res;
3516        }
3517    }
3518
3519    @Override
3520    public boolean willActivityBeVisible(IBinder token) {
3521        synchronized(this) {
3522            ActivityStack stack = ActivityRecord.getStackLocked(token);
3523            if (stack != null) {
3524                return stack.willActivityBeVisibleLocked(token);
3525            }
3526            return false;
3527        }
3528    }
3529
3530    @Override
3531    public void overridePendingTransition(IBinder token, String packageName,
3532            int enterAnim, int exitAnim) {
3533        synchronized(this) {
3534            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3535            if (self == null) {
3536                return;
3537            }
3538
3539            final long origId = Binder.clearCallingIdentity();
3540
3541            if (self.state == ActivityState.RESUMED
3542                    || self.state == ActivityState.PAUSING) {
3543                mWindowManager.overridePendingAppTransition(packageName,
3544                        enterAnim, exitAnim, null);
3545            }
3546
3547            Binder.restoreCallingIdentity(origId);
3548        }
3549    }
3550
3551    /**
3552     * Main function for removing an existing process from the activity manager
3553     * as a result of that process going away.  Clears out all connections
3554     * to the process.
3555     */
3556    private final void handleAppDiedLocked(ProcessRecord app,
3557            boolean restarting, boolean allowRestart) {
3558        int pid = app.pid;
3559        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3560        if (!restarting) {
3561            removeLruProcessLocked(app);
3562            if (pid > 0) {
3563                ProcessList.remove(pid);
3564            }
3565        }
3566
3567        if (mProfileProc == app) {
3568            clearProfilerLocked();
3569        }
3570
3571        // Remove this application's activities from active lists.
3572        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3573
3574        app.activities.clear();
3575
3576        if (app.instrumentationClass != null) {
3577            Slog.w(TAG, "Crash of app " + app.processName
3578                  + " running instrumentation " + app.instrumentationClass);
3579            Bundle info = new Bundle();
3580            info.putString("shortMsg", "Process crashed.");
3581            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3582        }
3583
3584        if (!restarting) {
3585            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3586                // If there was nothing to resume, and we are not already
3587                // restarting this process, but there is a visible activity that
3588                // is hosted by the process...  then make sure all visible
3589                // activities are running, taking care of restarting this
3590                // process.
3591                if (hasVisibleActivities) {
3592                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3593                }
3594            }
3595        }
3596    }
3597
3598    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3599        IBinder threadBinder = thread.asBinder();
3600        // Find the application record.
3601        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3602            ProcessRecord rec = mLruProcesses.get(i);
3603            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3604                return i;
3605            }
3606        }
3607        return -1;
3608    }
3609
3610    final ProcessRecord getRecordForAppLocked(
3611            IApplicationThread thread) {
3612        if (thread == null) {
3613            return null;
3614        }
3615
3616        int appIndex = getLRURecordIndexForAppLocked(thread);
3617        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3618    }
3619
3620    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3621        // If there are no longer any background processes running,
3622        // and the app that died was not running instrumentation,
3623        // then tell everyone we are now low on memory.
3624        boolean haveBg = false;
3625        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3626            ProcessRecord rec = mLruProcesses.get(i);
3627            if (rec.thread != null
3628                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3629                haveBg = true;
3630                break;
3631            }
3632        }
3633
3634        if (!haveBg) {
3635            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3636            if (doReport) {
3637                long now = SystemClock.uptimeMillis();
3638                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3639                    doReport = false;
3640                } else {
3641                    mLastMemUsageReportTime = now;
3642                }
3643            }
3644            final ArrayList<ProcessMemInfo> memInfos
3645                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3646            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3647            long now = SystemClock.uptimeMillis();
3648            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3649                ProcessRecord rec = mLruProcesses.get(i);
3650                if (rec == dyingProc || rec.thread == null) {
3651                    continue;
3652                }
3653                if (doReport) {
3654                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3655                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3656                }
3657                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3658                    // The low memory report is overriding any current
3659                    // state for a GC request.  Make sure to do
3660                    // heavy/important/visible/foreground processes first.
3661                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3662                        rec.lastRequestedGc = 0;
3663                    } else {
3664                        rec.lastRequestedGc = rec.lastLowMemory;
3665                    }
3666                    rec.reportLowMemory = true;
3667                    rec.lastLowMemory = now;
3668                    mProcessesToGc.remove(rec);
3669                    addProcessToGcListLocked(rec);
3670                }
3671            }
3672            if (doReport) {
3673                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3674                mHandler.sendMessage(msg);
3675            }
3676            scheduleAppGcsLocked();
3677        }
3678    }
3679
3680    final void appDiedLocked(ProcessRecord app, int pid,
3681            IApplicationThread thread) {
3682
3683        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3684        synchronized (stats) {
3685            stats.noteProcessDiedLocked(app.info.uid, pid);
3686        }
3687
3688        // Clean up already done if the process has been re-started.
3689        if (app.pid == pid && app.thread != null &&
3690                app.thread.asBinder() == thread.asBinder()) {
3691            boolean doLowMem = app.instrumentationClass == null;
3692            boolean doOomAdj = doLowMem;
3693            if (!app.killedByAm) {
3694                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3695                        + ") has died.");
3696                mAllowLowerMemLevel = true;
3697            } else {
3698                // Note that we always want to do oom adj to update our state with the
3699                // new number of procs.
3700                mAllowLowerMemLevel = false;
3701                doLowMem = false;
3702            }
3703            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3704            if (DEBUG_CLEANUP) Slog.v(
3705                TAG, "Dying app: " + app + ", pid: " + pid
3706                + ", thread: " + thread.asBinder());
3707            handleAppDiedLocked(app, false, true);
3708
3709            if (doOomAdj) {
3710                updateOomAdjLocked();
3711            }
3712            if (doLowMem) {
3713                doLowMemReportIfNeededLocked(app);
3714            }
3715        } else if (app.pid != pid) {
3716            // A new process has already been started.
3717            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3718                    + ") has died and restarted (pid " + app.pid + ").");
3719            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3720        } else if (DEBUG_PROCESSES) {
3721            Slog.d(TAG, "Received spurious death notification for thread "
3722                    + thread.asBinder());
3723        }
3724    }
3725
3726    /**
3727     * If a stack trace dump file is configured, dump process stack traces.
3728     * @param clearTraces causes the dump file to be erased prior to the new
3729     *    traces being written, if true; when false, the new traces will be
3730     *    appended to any existing file content.
3731     * @param firstPids of dalvik VM processes to dump stack traces for first
3732     * @param lastPids of dalvik VM processes to dump stack traces for last
3733     * @param nativeProcs optional list of native process names to dump stack crawls
3734     * @return file containing stack traces, or null if no dump file is configured
3735     */
3736    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3737            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3738        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3739        if (tracesPath == null || tracesPath.length() == 0) {
3740            return null;
3741        }
3742
3743        File tracesFile = new File(tracesPath);
3744        try {
3745            File tracesDir = tracesFile.getParentFile();
3746            if (!tracesDir.exists()) {
3747                tracesFile.mkdirs();
3748                if (!SELinux.restorecon(tracesDir)) {
3749                    return null;
3750                }
3751            }
3752            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3753
3754            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3755            tracesFile.createNewFile();
3756            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3757        } catch (IOException e) {
3758            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3759            return null;
3760        }
3761
3762        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3763        return tracesFile;
3764    }
3765
3766    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3767            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3768        // Use a FileObserver to detect when traces finish writing.
3769        // The order of traces is considered important to maintain for legibility.
3770        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3771            @Override
3772            public synchronized void onEvent(int event, String path) { notify(); }
3773        };
3774
3775        try {
3776            observer.startWatching();
3777
3778            // First collect all of the stacks of the most important pids.
3779            if (firstPids != null) {
3780                try {
3781                    int num = firstPids.size();
3782                    for (int i = 0; i < num; i++) {
3783                        synchronized (observer) {
3784                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3785                            observer.wait(200);  // Wait for write-close, give up after 200msec
3786                        }
3787                    }
3788                } catch (InterruptedException e) {
3789                    Log.wtf(TAG, e);
3790                }
3791            }
3792
3793            // Next collect the stacks of the native pids
3794            if (nativeProcs != null) {
3795                int[] pids = Process.getPidsForCommands(nativeProcs);
3796                if (pids != null) {
3797                    for (int pid : pids) {
3798                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3799                    }
3800                }
3801            }
3802
3803            // Lastly, measure CPU usage.
3804            if (processCpuTracker != null) {
3805                processCpuTracker.init();
3806                System.gc();
3807                processCpuTracker.update();
3808                try {
3809                    synchronized (processCpuTracker) {
3810                        processCpuTracker.wait(500); // measure over 1/2 second.
3811                    }
3812                } catch (InterruptedException e) {
3813                }
3814                processCpuTracker.update();
3815
3816                // We'll take the stack crawls of just the top apps using CPU.
3817                final int N = processCpuTracker.countWorkingStats();
3818                int numProcs = 0;
3819                for (int i=0; i<N && numProcs<5; i++) {
3820                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3821                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3822                        numProcs++;
3823                        try {
3824                            synchronized (observer) {
3825                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3826                                observer.wait(200);  // Wait for write-close, give up after 200msec
3827                            }
3828                        } catch (InterruptedException e) {
3829                            Log.wtf(TAG, e);
3830                        }
3831
3832                    }
3833                }
3834            }
3835        } finally {
3836            observer.stopWatching();
3837        }
3838    }
3839
3840    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3841        if (true || IS_USER_BUILD) {
3842            return;
3843        }
3844        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3845        if (tracesPath == null || tracesPath.length() == 0) {
3846            return;
3847        }
3848
3849        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3850        StrictMode.allowThreadDiskWrites();
3851        try {
3852            final File tracesFile = new File(tracesPath);
3853            final File tracesDir = tracesFile.getParentFile();
3854            final File tracesTmp = new File(tracesDir, "__tmp__");
3855            try {
3856                if (!tracesDir.exists()) {
3857                    tracesFile.mkdirs();
3858                    if (!SELinux.restorecon(tracesDir.getPath())) {
3859                        return;
3860                    }
3861                }
3862                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3863
3864                if (tracesFile.exists()) {
3865                    tracesTmp.delete();
3866                    tracesFile.renameTo(tracesTmp);
3867                }
3868                StringBuilder sb = new StringBuilder();
3869                Time tobj = new Time();
3870                tobj.set(System.currentTimeMillis());
3871                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3872                sb.append(": ");
3873                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3874                sb.append(" since ");
3875                sb.append(msg);
3876                FileOutputStream fos = new FileOutputStream(tracesFile);
3877                fos.write(sb.toString().getBytes());
3878                if (app == null) {
3879                    fos.write("\n*** No application process!".getBytes());
3880                }
3881                fos.close();
3882                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3883            } catch (IOException e) {
3884                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3885                return;
3886            }
3887
3888            if (app != null) {
3889                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3890                firstPids.add(app.pid);
3891                dumpStackTraces(tracesPath, firstPids, null, null, null);
3892            }
3893
3894            File lastTracesFile = null;
3895            File curTracesFile = null;
3896            for (int i=9; i>=0; i--) {
3897                String name = String.format(Locale.US, "slow%02d.txt", i);
3898                curTracesFile = new File(tracesDir, name);
3899                if (curTracesFile.exists()) {
3900                    if (lastTracesFile != null) {
3901                        curTracesFile.renameTo(lastTracesFile);
3902                    } else {
3903                        curTracesFile.delete();
3904                    }
3905                }
3906                lastTracesFile = curTracesFile;
3907            }
3908            tracesFile.renameTo(curTracesFile);
3909            if (tracesTmp.exists()) {
3910                tracesTmp.renameTo(tracesFile);
3911            }
3912        } finally {
3913            StrictMode.setThreadPolicy(oldPolicy);
3914        }
3915    }
3916
3917    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3918            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3919        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3920        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3921
3922        if (mController != null) {
3923            try {
3924                // 0 == continue, -1 = kill process immediately
3925                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3926                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3927            } catch (RemoteException e) {
3928                mController = null;
3929                Watchdog.getInstance().setActivityController(null);
3930            }
3931        }
3932
3933        long anrTime = SystemClock.uptimeMillis();
3934        if (MONITOR_CPU_USAGE) {
3935            updateCpuStatsNow();
3936        }
3937
3938        synchronized (this) {
3939            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3940            if (mShuttingDown) {
3941                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3942                return;
3943            } else if (app.notResponding) {
3944                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3945                return;
3946            } else if (app.crashing) {
3947                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3948                return;
3949            }
3950
3951            // In case we come through here for the same app before completing
3952            // this one, mark as anring now so we will bail out.
3953            app.notResponding = true;
3954
3955            // Log the ANR to the event log.
3956            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3957                    app.processName, app.info.flags, annotation);
3958
3959            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3960            firstPids.add(app.pid);
3961
3962            int parentPid = app.pid;
3963            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3964            if (parentPid != app.pid) firstPids.add(parentPid);
3965
3966            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3967
3968            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3969                ProcessRecord r = mLruProcesses.get(i);
3970                if (r != null && r.thread != null) {
3971                    int pid = r.pid;
3972                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3973                        if (r.persistent) {
3974                            firstPids.add(pid);
3975                        } else {
3976                            lastPids.put(pid, Boolean.TRUE);
3977                        }
3978                    }
3979                }
3980            }
3981        }
3982
3983        // Log the ANR to the main log.
3984        StringBuilder info = new StringBuilder();
3985        info.setLength(0);
3986        info.append("ANR in ").append(app.processName);
3987        if (activity != null && activity.shortComponentName != null) {
3988            info.append(" (").append(activity.shortComponentName).append(")");
3989        }
3990        info.append("\n");
3991        info.append("PID: ").append(app.pid).append("\n");
3992        if (annotation != null) {
3993            info.append("Reason: ").append(annotation).append("\n");
3994        }
3995        if (parent != null && parent != activity) {
3996            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3997        }
3998
3999        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4000
4001        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4002                NATIVE_STACKS_OF_INTEREST);
4003
4004        String cpuInfo = null;
4005        if (MONITOR_CPU_USAGE) {
4006            updateCpuStatsNow();
4007            synchronized (mProcessCpuThread) {
4008                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4009            }
4010            info.append(processCpuTracker.printCurrentLoad());
4011            info.append(cpuInfo);
4012        }
4013
4014        info.append(processCpuTracker.printCurrentState(anrTime));
4015
4016        Slog.e(TAG, info.toString());
4017        if (tracesFile == null) {
4018            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4019            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4020        }
4021
4022        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4023                cpuInfo, tracesFile, null);
4024
4025        if (mController != null) {
4026            try {
4027                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4028                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4029                if (res != 0) {
4030                    if (res < 0 && app.pid != MY_PID) {
4031                        Process.killProcess(app.pid);
4032                    } else {
4033                        synchronized (this) {
4034                            mServices.scheduleServiceTimeoutLocked(app);
4035                        }
4036                    }
4037                    return;
4038                }
4039            } catch (RemoteException e) {
4040                mController = null;
4041                Watchdog.getInstance().setActivityController(null);
4042            }
4043        }
4044
4045        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4046        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4047                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4048
4049        synchronized (this) {
4050            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4051                killUnneededProcessLocked(app, "background ANR");
4052                return;
4053            }
4054
4055            // Set the app's notResponding state, and look up the errorReportReceiver
4056            makeAppNotRespondingLocked(app,
4057                    activity != null ? activity.shortComponentName : null,
4058                    annotation != null ? "ANR " + annotation : "ANR",
4059                    info.toString());
4060
4061            // Bring up the infamous App Not Responding dialog
4062            Message msg = Message.obtain();
4063            HashMap<String, Object> map = new HashMap<String, Object>();
4064            msg.what = SHOW_NOT_RESPONDING_MSG;
4065            msg.obj = map;
4066            msg.arg1 = aboveSystem ? 1 : 0;
4067            map.put("app", app);
4068            if (activity != null) {
4069                map.put("activity", activity);
4070            }
4071
4072            mHandler.sendMessage(msg);
4073        }
4074    }
4075
4076    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4077        if (!mLaunchWarningShown) {
4078            mLaunchWarningShown = true;
4079            mHandler.post(new Runnable() {
4080                @Override
4081                public void run() {
4082                    synchronized (ActivityManagerService.this) {
4083                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4084                        d.show();
4085                        mHandler.postDelayed(new Runnable() {
4086                            @Override
4087                            public void run() {
4088                                synchronized (ActivityManagerService.this) {
4089                                    d.dismiss();
4090                                    mLaunchWarningShown = false;
4091                                }
4092                            }
4093                        }, 4000);
4094                    }
4095                }
4096            });
4097        }
4098    }
4099
4100    @Override
4101    public boolean clearApplicationUserData(final String packageName,
4102            final IPackageDataObserver observer, int userId) {
4103        enforceNotIsolatedCaller("clearApplicationUserData");
4104        int uid = Binder.getCallingUid();
4105        int pid = Binder.getCallingPid();
4106        userId = handleIncomingUser(pid, uid,
4107                userId, false, true, "clearApplicationUserData", null);
4108        long callingId = Binder.clearCallingIdentity();
4109        try {
4110            IPackageManager pm = AppGlobals.getPackageManager();
4111            int pkgUid = -1;
4112            synchronized(this) {
4113                try {
4114                    pkgUid = pm.getPackageUid(packageName, userId);
4115                } catch (RemoteException e) {
4116                }
4117                if (pkgUid == -1) {
4118                    Slog.w(TAG, "Invalid packageName: " + packageName);
4119                    if (observer != null) {
4120                        try {
4121                            observer.onRemoveCompleted(packageName, false);
4122                        } catch (RemoteException e) {
4123                            Slog.i(TAG, "Observer no longer exists.");
4124                        }
4125                    }
4126                    return false;
4127                }
4128                if (uid == pkgUid || checkComponentPermission(
4129                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4130                        pid, uid, -1, true)
4131                        == PackageManager.PERMISSION_GRANTED) {
4132                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4133                } else {
4134                    throw new SecurityException("PID " + pid + " does not have permission "
4135                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4136                                    + " of package " + packageName);
4137                }
4138            }
4139
4140            try {
4141                // Clear application user data
4142                pm.clearApplicationUserData(packageName, observer, userId);
4143
4144                // Remove all permissions granted from/to this package
4145                removeUriPermissionsForPackageLocked(packageName, userId, true);
4146
4147                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4148                        Uri.fromParts("package", packageName, null));
4149                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4150                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4151                        null, null, 0, null, null, null, false, false, userId);
4152            } catch (RemoteException e) {
4153            }
4154        } finally {
4155            Binder.restoreCallingIdentity(callingId);
4156        }
4157        return true;
4158    }
4159
4160    @Override
4161    public void killBackgroundProcesses(final String packageName, int userId) {
4162        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4163                != PackageManager.PERMISSION_GRANTED &&
4164                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4165                        != PackageManager.PERMISSION_GRANTED) {
4166            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4167                    + Binder.getCallingPid()
4168                    + ", uid=" + Binder.getCallingUid()
4169                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4170            Slog.w(TAG, msg);
4171            throw new SecurityException(msg);
4172        }
4173
4174        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4175                userId, true, true, "killBackgroundProcesses", null);
4176        long callingId = Binder.clearCallingIdentity();
4177        try {
4178            IPackageManager pm = AppGlobals.getPackageManager();
4179            synchronized(this) {
4180                int appId = -1;
4181                try {
4182                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4183                } catch (RemoteException e) {
4184                }
4185                if (appId == -1) {
4186                    Slog.w(TAG, "Invalid packageName: " + packageName);
4187                    return;
4188                }
4189                killPackageProcessesLocked(packageName, appId, userId,
4190                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4191            }
4192        } finally {
4193            Binder.restoreCallingIdentity(callingId);
4194        }
4195    }
4196
4197    @Override
4198    public void killAllBackgroundProcesses() {
4199        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4200                != PackageManager.PERMISSION_GRANTED) {
4201            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4202                    + Binder.getCallingPid()
4203                    + ", uid=" + Binder.getCallingUid()
4204                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4205            Slog.w(TAG, msg);
4206            throw new SecurityException(msg);
4207        }
4208
4209        long callingId = Binder.clearCallingIdentity();
4210        try {
4211            synchronized(this) {
4212                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4213                final int NP = mProcessNames.getMap().size();
4214                for (int ip=0; ip<NP; ip++) {
4215                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4216                    final int NA = apps.size();
4217                    for (int ia=0; ia<NA; ia++) {
4218                        ProcessRecord app = apps.valueAt(ia);
4219                        if (app.persistent) {
4220                            // we don't kill persistent processes
4221                            continue;
4222                        }
4223                        if (app.removed) {
4224                            procs.add(app);
4225                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4226                            app.removed = true;
4227                            procs.add(app);
4228                        }
4229                    }
4230                }
4231
4232                int N = procs.size();
4233                for (int i=0; i<N; i++) {
4234                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4235                }
4236                mAllowLowerMemLevel = true;
4237                updateOomAdjLocked();
4238                doLowMemReportIfNeededLocked(null);
4239            }
4240        } finally {
4241            Binder.restoreCallingIdentity(callingId);
4242        }
4243    }
4244
4245    @Override
4246    public void forceStopPackage(final String packageName, int userId) {
4247        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4248                != PackageManager.PERMISSION_GRANTED) {
4249            String msg = "Permission Denial: forceStopPackage() from pid="
4250                    + Binder.getCallingPid()
4251                    + ", uid=" + Binder.getCallingUid()
4252                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4253            Slog.w(TAG, msg);
4254            throw new SecurityException(msg);
4255        }
4256        final int callingPid = Binder.getCallingPid();
4257        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4258                userId, true, true, "forceStopPackage", null);
4259        long callingId = Binder.clearCallingIdentity();
4260        try {
4261            IPackageManager pm = AppGlobals.getPackageManager();
4262            synchronized(this) {
4263                int[] users = userId == UserHandle.USER_ALL
4264                        ? getUsersLocked() : new int[] { userId };
4265                for (int user : users) {
4266                    int pkgUid = -1;
4267                    try {
4268                        pkgUid = pm.getPackageUid(packageName, user);
4269                    } catch (RemoteException e) {
4270                    }
4271                    if (pkgUid == -1) {
4272                        Slog.w(TAG, "Invalid packageName: " + packageName);
4273                        continue;
4274                    }
4275                    try {
4276                        pm.setPackageStoppedState(packageName, true, user);
4277                    } catch (RemoteException e) {
4278                    } catch (IllegalArgumentException e) {
4279                        Slog.w(TAG, "Failed trying to unstop package "
4280                                + packageName + ": " + e);
4281                    }
4282                    if (isUserRunningLocked(user, false)) {
4283                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4284                    }
4285                }
4286            }
4287        } finally {
4288            Binder.restoreCallingIdentity(callingId);
4289        }
4290    }
4291
4292    /*
4293     * The pkg name and app id have to be specified.
4294     */
4295    @Override
4296    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4297        if (pkg == null) {
4298            return;
4299        }
4300        // Make sure the uid is valid.
4301        if (appid < 0) {
4302            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4303            return;
4304        }
4305        int callerUid = Binder.getCallingUid();
4306        // Only the system server can kill an application
4307        if (callerUid == Process.SYSTEM_UID) {
4308            // Post an aysnc message to kill the application
4309            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4310            msg.arg1 = appid;
4311            msg.arg2 = 0;
4312            Bundle bundle = new Bundle();
4313            bundle.putString("pkg", pkg);
4314            bundle.putString("reason", reason);
4315            msg.obj = bundle;
4316            mHandler.sendMessage(msg);
4317        } else {
4318            throw new SecurityException(callerUid + " cannot kill pkg: " +
4319                    pkg);
4320        }
4321    }
4322
4323    @Override
4324    public void closeSystemDialogs(String reason) {
4325        enforceNotIsolatedCaller("closeSystemDialogs");
4326
4327        final int pid = Binder.getCallingPid();
4328        final int uid = Binder.getCallingUid();
4329        final long origId = Binder.clearCallingIdentity();
4330        try {
4331            synchronized (this) {
4332                // Only allow this from foreground processes, so that background
4333                // applications can't abuse it to prevent system UI from being shown.
4334                if (uid >= Process.FIRST_APPLICATION_UID) {
4335                    ProcessRecord proc;
4336                    synchronized (mPidsSelfLocked) {
4337                        proc = mPidsSelfLocked.get(pid);
4338                    }
4339                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4340                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4341                                + " from background process " + proc);
4342                        return;
4343                    }
4344                }
4345                closeSystemDialogsLocked(reason);
4346            }
4347        } finally {
4348            Binder.restoreCallingIdentity(origId);
4349        }
4350    }
4351
4352    void closeSystemDialogsLocked(String reason) {
4353        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4354        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4355                | Intent.FLAG_RECEIVER_FOREGROUND);
4356        if (reason != null) {
4357            intent.putExtra("reason", reason);
4358        }
4359        mWindowManager.closeSystemDialogs(reason);
4360
4361        mStackSupervisor.closeSystemDialogsLocked();
4362
4363        broadcastIntentLocked(null, null, intent, null,
4364                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4365                Process.SYSTEM_UID, UserHandle.USER_ALL);
4366    }
4367
4368    @Override
4369    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4370        enforceNotIsolatedCaller("getProcessMemoryInfo");
4371        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4372        for (int i=pids.length-1; i>=0; i--) {
4373            ProcessRecord proc;
4374            int oomAdj;
4375            synchronized (this) {
4376                synchronized (mPidsSelfLocked) {
4377                    proc = mPidsSelfLocked.get(pids[i]);
4378                    oomAdj = proc != null ? proc.setAdj : 0;
4379                }
4380            }
4381            infos[i] = new Debug.MemoryInfo();
4382            Debug.getMemoryInfo(pids[i], infos[i]);
4383            if (proc != null) {
4384                synchronized (this) {
4385                    if (proc.thread != null && proc.setAdj == oomAdj) {
4386                        // Record this for posterity if the process has been stable.
4387                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4388                                infos[i].getTotalUss(), false, proc.pkgList);
4389                    }
4390                }
4391            }
4392        }
4393        return infos;
4394    }
4395
4396    @Override
4397    public long[] getProcessPss(int[] pids) {
4398        enforceNotIsolatedCaller("getProcessPss");
4399        long[] pss = new long[pids.length];
4400        for (int i=pids.length-1; i>=0; i--) {
4401            ProcessRecord proc;
4402            int oomAdj;
4403            synchronized (this) {
4404                synchronized (mPidsSelfLocked) {
4405                    proc = mPidsSelfLocked.get(pids[i]);
4406                    oomAdj = proc != null ? proc.setAdj : 0;
4407                }
4408            }
4409            long[] tmpUss = new long[1];
4410            pss[i] = Debug.getPss(pids[i], tmpUss);
4411            if (proc != null) {
4412                synchronized (this) {
4413                    if (proc.thread != null && proc.setAdj == oomAdj) {
4414                        // Record this for posterity if the process has been stable.
4415                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4416                    }
4417                }
4418            }
4419        }
4420        return pss;
4421    }
4422
4423    @Override
4424    public void killApplicationProcess(String processName, int uid) {
4425        if (processName == null) {
4426            return;
4427        }
4428
4429        int callerUid = Binder.getCallingUid();
4430        // Only the system server can kill an application
4431        if (callerUid == Process.SYSTEM_UID) {
4432            synchronized (this) {
4433                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4434                if (app != null && app.thread != null) {
4435                    try {
4436                        app.thread.scheduleSuicide();
4437                    } catch (RemoteException e) {
4438                        // If the other end already died, then our work here is done.
4439                    }
4440                } else {
4441                    Slog.w(TAG, "Process/uid not found attempting kill of "
4442                            + processName + " / " + uid);
4443                }
4444            }
4445        } else {
4446            throw new SecurityException(callerUid + " cannot kill app process: " +
4447                    processName);
4448        }
4449    }
4450
4451    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4452        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4453                false, true, false, UserHandle.getUserId(uid), reason);
4454        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4455                Uri.fromParts("package", packageName, null));
4456        if (!mProcessesReady) {
4457            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4458                    | Intent.FLAG_RECEIVER_FOREGROUND);
4459        }
4460        intent.putExtra(Intent.EXTRA_UID, uid);
4461        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4462        broadcastIntentLocked(null, null, intent,
4463                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4464                false, false,
4465                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4466    }
4467
4468    private void forceStopUserLocked(int userId, String reason) {
4469        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
4470        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4471        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4472                | Intent.FLAG_RECEIVER_FOREGROUND);
4473        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4474        broadcastIntentLocked(null, null, intent,
4475                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4476                false, false,
4477                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4478    }
4479
4480    private final boolean killPackageProcessesLocked(String packageName, int appId,
4481            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4482            boolean doit, boolean evenPersistent, String reason) {
4483        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4484
4485        // Remove all processes this package may have touched: all with the
4486        // same UID (except for the system or root user), and all whose name
4487        // matches the package name.
4488        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4489        final int NP = mProcessNames.getMap().size();
4490        for (int ip=0; ip<NP; ip++) {
4491            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4492            final int NA = apps.size();
4493            for (int ia=0; ia<NA; ia++) {
4494                ProcessRecord app = apps.valueAt(ia);
4495                if (app.persistent && !evenPersistent) {
4496                    // we don't kill persistent processes
4497                    continue;
4498                }
4499                if (app.removed) {
4500                    if (doit) {
4501                        procs.add(app);
4502                    }
4503                    continue;
4504                }
4505
4506                // Skip process if it doesn't meet our oom adj requirement.
4507                if (app.setAdj < minOomAdj) {
4508                    continue;
4509                }
4510
4511                // If no package is specified, we call all processes under the
4512                // give user id.
4513                if (packageName == null) {
4514                    if (app.userId != userId) {
4515                        continue;
4516                    }
4517                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4518                        continue;
4519                    }
4520                // Package has been specified, we want to hit all processes
4521                // that match it.  We need to qualify this by the processes
4522                // that are running under the specified app and user ID.
4523                } else {
4524                    if (UserHandle.getAppId(app.uid) != appId) {
4525                        continue;
4526                    }
4527                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4528                        continue;
4529                    }
4530                    if (!app.pkgList.containsKey(packageName)) {
4531                        continue;
4532                    }
4533                }
4534
4535                // Process has passed all conditions, kill it!
4536                if (!doit) {
4537                    return true;
4538                }
4539                app.removed = true;
4540                procs.add(app);
4541            }
4542        }
4543
4544        int N = procs.size();
4545        for (int i=0; i<N; i++) {
4546            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4547        }
4548        updateOomAdjLocked();
4549        return N > 0;
4550    }
4551
4552    private final boolean forceStopPackageLocked(String name, int appId,
4553            boolean callerWillRestart, boolean purgeCache, boolean doit,
4554            boolean evenPersistent, int userId, String reason) {
4555        int i;
4556        int N;
4557
4558        if (userId == UserHandle.USER_ALL && name == null) {
4559            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4560        }
4561
4562        if (appId < 0 && name != null) {
4563            try {
4564                appId = UserHandle.getAppId(
4565                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4566            } catch (RemoteException e) {
4567            }
4568        }
4569
4570        if (doit) {
4571            if (name != null) {
4572                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4573                        + " user=" + userId + ": " + reason);
4574            } else {
4575                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4576            }
4577
4578            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4579            for (int ip=pmap.size()-1; ip>=0; ip--) {
4580                SparseArray<Long> ba = pmap.valueAt(ip);
4581                for (i=ba.size()-1; i>=0; i--) {
4582                    boolean remove = false;
4583                    final int entUid = ba.keyAt(i);
4584                    if (name != null) {
4585                        if (userId == UserHandle.USER_ALL) {
4586                            if (UserHandle.getAppId(entUid) == appId) {
4587                                remove = true;
4588                            }
4589                        } else {
4590                            if (entUid == UserHandle.getUid(userId, appId)) {
4591                                remove = true;
4592                            }
4593                        }
4594                    } else if (UserHandle.getUserId(entUid) == userId) {
4595                        remove = true;
4596                    }
4597                    if (remove) {
4598                        ba.removeAt(i);
4599                    }
4600                }
4601                if (ba.size() == 0) {
4602                    pmap.removeAt(ip);
4603                }
4604            }
4605        }
4606
4607        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4608                -100, callerWillRestart, true, doit, evenPersistent,
4609                name == null ? ("stop user " + userId) : ("stop " + name));
4610
4611        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4612            if (!doit) {
4613                return true;
4614            }
4615            didSomething = true;
4616        }
4617
4618        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4619            if (!doit) {
4620                return true;
4621            }
4622            didSomething = true;
4623        }
4624
4625        if (name == null) {
4626            // Remove all sticky broadcasts from this user.
4627            mStickyBroadcasts.remove(userId);
4628        }
4629
4630        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4631        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4632                userId, providers)) {
4633            if (!doit) {
4634                return true;
4635            }
4636            didSomething = true;
4637        }
4638        N = providers.size();
4639        for (i=0; i<N; i++) {
4640            removeDyingProviderLocked(null, providers.get(i), true);
4641        }
4642
4643        // Remove transient permissions granted from/to this package/user
4644        removeUriPermissionsForPackageLocked(name, userId, false);
4645
4646        if (name == null) {
4647            // Remove pending intents.  For now we only do this when force
4648            // stopping users, because we have some problems when doing this
4649            // for packages -- app widgets are not currently cleaned up for
4650            // such packages, so they can be left with bad pending intents.
4651            if (mIntentSenderRecords.size() > 0) {
4652                Iterator<WeakReference<PendingIntentRecord>> it
4653                        = mIntentSenderRecords.values().iterator();
4654                while (it.hasNext()) {
4655                    WeakReference<PendingIntentRecord> wpir = it.next();
4656                    if (wpir == null) {
4657                        it.remove();
4658                        continue;
4659                    }
4660                    PendingIntentRecord pir = wpir.get();
4661                    if (pir == null) {
4662                        it.remove();
4663                        continue;
4664                    }
4665                    if (name == null) {
4666                        // Stopping user, remove all objects for the user.
4667                        if (pir.key.userId != userId) {
4668                            // Not the same user, skip it.
4669                            continue;
4670                        }
4671                    } else {
4672                        if (UserHandle.getAppId(pir.uid) != appId) {
4673                            // Different app id, skip it.
4674                            continue;
4675                        }
4676                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4677                            // Different user, skip it.
4678                            continue;
4679                        }
4680                        if (!pir.key.packageName.equals(name)) {
4681                            // Different package, skip it.
4682                            continue;
4683                        }
4684                    }
4685                    if (!doit) {
4686                        return true;
4687                    }
4688                    didSomething = true;
4689                    it.remove();
4690                    pir.canceled = true;
4691                    if (pir.key.activity != null) {
4692                        pir.key.activity.pendingResults.remove(pir.ref);
4693                    }
4694                }
4695            }
4696        }
4697
4698        if (doit) {
4699            if (purgeCache && name != null) {
4700                AttributeCache ac = AttributeCache.instance();
4701                if (ac != null) {
4702                    ac.removePackage(name);
4703                }
4704            }
4705            if (mBooted) {
4706                mStackSupervisor.resumeTopActivitiesLocked();
4707                mStackSupervisor.scheduleIdleLocked();
4708            }
4709        }
4710
4711        return didSomething;
4712    }
4713
4714    private final boolean removeProcessLocked(ProcessRecord app,
4715            boolean callerWillRestart, boolean allowRestart, String reason) {
4716        final String name = app.processName;
4717        final int uid = app.uid;
4718        if (DEBUG_PROCESSES) Slog.d(
4719            TAG, "Force removing proc " + app.toShortString() + " (" + name
4720            + "/" + uid + ")");
4721
4722        mProcessNames.remove(name, uid);
4723        mIsolatedProcesses.remove(app.uid);
4724        if (mHeavyWeightProcess == app) {
4725            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4726                    mHeavyWeightProcess.userId, 0));
4727            mHeavyWeightProcess = null;
4728        }
4729        boolean needRestart = false;
4730        if (app.pid > 0 && app.pid != MY_PID) {
4731            int pid = app.pid;
4732            synchronized (mPidsSelfLocked) {
4733                mPidsSelfLocked.remove(pid);
4734                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4735            }
4736            killUnneededProcessLocked(app, reason);
4737            handleAppDiedLocked(app, true, allowRestart);
4738            removeLruProcessLocked(app);
4739
4740            if (app.persistent && !app.isolated) {
4741                if (!callerWillRestart) {
4742                    addAppLocked(app.info, false);
4743                } else {
4744                    needRestart = true;
4745                }
4746            }
4747        } else {
4748            mRemovedProcesses.add(app);
4749        }
4750
4751        return needRestart;
4752    }
4753
4754    private final void processStartTimedOutLocked(ProcessRecord app) {
4755        final int pid = app.pid;
4756        boolean gone = false;
4757        synchronized (mPidsSelfLocked) {
4758            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4759            if (knownApp != null && knownApp.thread == null) {
4760                mPidsSelfLocked.remove(pid);
4761                gone = true;
4762            }
4763        }
4764
4765        if (gone) {
4766            Slog.w(TAG, "Process " + app + " failed to attach");
4767            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4768                    pid, app.uid, app.processName);
4769            mProcessNames.remove(app.processName, app.uid);
4770            mIsolatedProcesses.remove(app.uid);
4771            if (mHeavyWeightProcess == app) {
4772                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4773                        mHeavyWeightProcess.userId, 0));
4774                mHeavyWeightProcess = null;
4775            }
4776            // Take care of any launching providers waiting for this process.
4777            checkAppInLaunchingProvidersLocked(app, true);
4778            // Take care of any services that are waiting for the process.
4779            mServices.processStartTimedOutLocked(app);
4780            killUnneededProcessLocked(app, "start timeout");
4781            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4782                Slog.w(TAG, "Unattached app died before backup, skipping");
4783                try {
4784                    IBackupManager bm = IBackupManager.Stub.asInterface(
4785                            ServiceManager.getService(Context.BACKUP_SERVICE));
4786                    bm.agentDisconnected(app.info.packageName);
4787                } catch (RemoteException e) {
4788                    // Can't happen; the backup manager is local
4789                }
4790            }
4791            if (isPendingBroadcastProcessLocked(pid)) {
4792                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4793                skipPendingBroadcastLocked(pid);
4794            }
4795        } else {
4796            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4797        }
4798    }
4799
4800    private final boolean attachApplicationLocked(IApplicationThread thread,
4801            int pid) {
4802
4803        // Find the application record that is being attached...  either via
4804        // the pid if we are running in multiple processes, or just pull the
4805        // next app record if we are emulating process with anonymous threads.
4806        ProcessRecord app;
4807        if (pid != MY_PID && pid >= 0) {
4808            synchronized (mPidsSelfLocked) {
4809                app = mPidsSelfLocked.get(pid);
4810            }
4811        } else {
4812            app = null;
4813        }
4814
4815        if (app == null) {
4816            Slog.w(TAG, "No pending application record for pid " + pid
4817                    + " (IApplicationThread " + thread + "); dropping process");
4818            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4819            if (pid > 0 && pid != MY_PID) {
4820                Process.killProcessQuiet(pid);
4821            } else {
4822                try {
4823                    thread.scheduleExit();
4824                } catch (Exception e) {
4825                    // Ignore exceptions.
4826                }
4827            }
4828            return false;
4829        }
4830
4831        // If this application record is still attached to a previous
4832        // process, clean it up now.
4833        if (app.thread != null) {
4834            handleAppDiedLocked(app, true, true);
4835        }
4836
4837        // Tell the process all about itself.
4838
4839        if (localLOGV) Slog.v(
4840                TAG, "Binding process pid " + pid + " to record " + app);
4841
4842        final String processName = app.processName;
4843        try {
4844            AppDeathRecipient adr = new AppDeathRecipient(
4845                    app, pid, thread);
4846            thread.asBinder().linkToDeath(adr, 0);
4847            app.deathRecipient = adr;
4848        } catch (RemoteException e) {
4849            app.resetPackageList(mProcessStats);
4850            startProcessLocked(app, "link fail", processName);
4851            return false;
4852        }
4853
4854        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4855
4856        app.makeActive(thread, mProcessStats);
4857        app.curAdj = app.setAdj = -100;
4858        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4859        app.forcingToForeground = null;
4860        app.foregroundServices = false;
4861        app.hasShownUi = false;
4862        app.debugging = false;
4863        app.cached = false;
4864
4865        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4866
4867        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4868        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4869
4870        if (!normalMode) {
4871            Slog.i(TAG, "Launching preboot mode app: " + app);
4872        }
4873
4874        if (localLOGV) Slog.v(
4875            TAG, "New app record " + app
4876            + " thread=" + thread.asBinder() + " pid=" + pid);
4877        try {
4878            int testMode = IApplicationThread.DEBUG_OFF;
4879            if (mDebugApp != null && mDebugApp.equals(processName)) {
4880                testMode = mWaitForDebugger
4881                    ? IApplicationThread.DEBUG_WAIT
4882                    : IApplicationThread.DEBUG_ON;
4883                app.debugging = true;
4884                if (mDebugTransient) {
4885                    mDebugApp = mOrigDebugApp;
4886                    mWaitForDebugger = mOrigWaitForDebugger;
4887                }
4888            }
4889            String profileFile = app.instrumentationProfileFile;
4890            ParcelFileDescriptor profileFd = null;
4891            boolean profileAutoStop = false;
4892            if (mProfileApp != null && mProfileApp.equals(processName)) {
4893                mProfileProc = app;
4894                profileFile = mProfileFile;
4895                profileFd = mProfileFd;
4896                profileAutoStop = mAutoStopProfiler;
4897            }
4898            boolean enableOpenGlTrace = false;
4899            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4900                enableOpenGlTrace = true;
4901                mOpenGlTraceApp = null;
4902            }
4903
4904            // If the app is being launched for restore or full backup, set it up specially
4905            boolean isRestrictedBackupMode = false;
4906            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4907                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4908                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4909                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4910            }
4911
4912            ensurePackageDexOpt(app.instrumentationInfo != null
4913                    ? app.instrumentationInfo.packageName
4914                    : app.info.packageName);
4915            if (app.instrumentationClass != null) {
4916                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4917            }
4918            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4919                    + processName + " with config " + mConfiguration);
4920            ApplicationInfo appInfo = app.instrumentationInfo != null
4921                    ? app.instrumentationInfo : app.info;
4922            app.compat = compatibilityInfoForPackageLocked(appInfo);
4923            if (profileFd != null) {
4924                profileFd = profileFd.dup();
4925            }
4926            thread.bindApplication(processName, appInfo, providers,
4927                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4928                    app.instrumentationArguments, app.instrumentationWatcher,
4929                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4930                    isRestrictedBackupMode || !normalMode, app.persistent,
4931                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4932                    mCoreSettingsObserver.getCoreSettingsLocked());
4933            updateLruProcessLocked(app, false, null);
4934            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4935        } catch (Exception e) {
4936            // todo: Yikes!  What should we do?  For now we will try to
4937            // start another process, but that could easily get us in
4938            // an infinite loop of restarting processes...
4939            Slog.w(TAG, "Exception thrown during bind!", e);
4940
4941            app.resetPackageList(mProcessStats);
4942            app.unlinkDeathRecipient();
4943            startProcessLocked(app, "bind fail", processName);
4944            return false;
4945        }
4946
4947        // Remove this record from the list of starting applications.
4948        mPersistentStartingProcesses.remove(app);
4949        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4950                "Attach application locked removing on hold: " + app);
4951        mProcessesOnHold.remove(app);
4952
4953        boolean badApp = false;
4954        boolean didSomething = false;
4955
4956        // See if the top visible activity is waiting to run in this process...
4957        if (normalMode) {
4958            try {
4959                if (mStackSupervisor.attachApplicationLocked(app)) {
4960                    didSomething = true;
4961                }
4962            } catch (Exception e) {
4963                badApp = true;
4964            }
4965        }
4966
4967        // Find any services that should be running in this process...
4968        if (!badApp) {
4969            try {
4970                didSomething |= mServices.attachApplicationLocked(app, processName);
4971            } catch (Exception e) {
4972                badApp = true;
4973            }
4974        }
4975
4976        // Check if a next-broadcast receiver is in this process...
4977        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4978            try {
4979                didSomething |= sendPendingBroadcastsLocked(app);
4980            } catch (Exception e) {
4981                // If the app died trying to launch the receiver we declare it 'bad'
4982                badApp = true;
4983            }
4984        }
4985
4986        // Check whether the next backup agent is in this process...
4987        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4988            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4989            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4990            try {
4991                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4992                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4993                        mBackupTarget.backupMode);
4994            } catch (Exception e) {
4995                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4996                e.printStackTrace();
4997            }
4998        }
4999
5000        if (badApp) {
5001            // todo: Also need to kill application to deal with all
5002            // kinds of exceptions.
5003            handleAppDiedLocked(app, false, true);
5004            return false;
5005        }
5006
5007        if (!didSomething) {
5008            updateOomAdjLocked();
5009        }
5010
5011        return true;
5012    }
5013
5014    @Override
5015    public final void attachApplication(IApplicationThread thread) {
5016        synchronized (this) {
5017            int callingPid = Binder.getCallingPid();
5018            final long origId = Binder.clearCallingIdentity();
5019            attachApplicationLocked(thread, callingPid);
5020            Binder.restoreCallingIdentity(origId);
5021        }
5022    }
5023
5024    @Override
5025    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5026        final long origId = Binder.clearCallingIdentity();
5027        synchronized (this) {
5028            ActivityStack stack = ActivityRecord.getStackLocked(token);
5029            if (stack != null) {
5030                ActivityRecord r =
5031                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5032                if (stopProfiling) {
5033                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5034                        try {
5035                            mProfileFd.close();
5036                        } catch (IOException e) {
5037                        }
5038                        clearProfilerLocked();
5039                    }
5040                }
5041            }
5042        }
5043        Binder.restoreCallingIdentity(origId);
5044    }
5045
5046    void enableScreenAfterBoot() {
5047        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5048                SystemClock.uptimeMillis());
5049        mWindowManager.enableScreenAfterBoot();
5050
5051        synchronized (this) {
5052            updateEventDispatchingLocked();
5053        }
5054    }
5055
5056    @Override
5057    public void showBootMessage(final CharSequence msg, final boolean always) {
5058        enforceNotIsolatedCaller("showBootMessage");
5059        mWindowManager.showBootMessage(msg, always);
5060    }
5061
5062    @Override
5063    public void dismissKeyguardOnNextActivity() {
5064        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5065        final long token = Binder.clearCallingIdentity();
5066        try {
5067            synchronized (this) {
5068                if (DEBUG_LOCKSCREEN) logLockScreen("");
5069                if (mLockScreenShown) {
5070                    mLockScreenShown = false;
5071                    comeOutOfSleepIfNeededLocked();
5072                }
5073                mStackSupervisor.setDismissKeyguard(true);
5074            }
5075        } finally {
5076            Binder.restoreCallingIdentity(token);
5077        }
5078    }
5079
5080    final void finishBooting() {
5081        IntentFilter pkgFilter = new IntentFilter();
5082        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5083        pkgFilter.addDataScheme("package");
5084        mContext.registerReceiver(new BroadcastReceiver() {
5085            @Override
5086            public void onReceive(Context context, Intent intent) {
5087                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5088                if (pkgs != null) {
5089                    for (String pkg : pkgs) {
5090                        synchronized (ActivityManagerService.this) {
5091                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
5092                                    "finished booting")) {
5093                                setResultCode(Activity.RESULT_OK);
5094                                return;
5095                            }
5096                        }
5097                    }
5098                }
5099            }
5100        }, pkgFilter);
5101
5102        synchronized (this) {
5103            // Ensure that any processes we had put on hold are now started
5104            // up.
5105            final int NP = mProcessesOnHold.size();
5106            if (NP > 0) {
5107                ArrayList<ProcessRecord> procs =
5108                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5109                for (int ip=0; ip<NP; ip++) {
5110                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5111                            + procs.get(ip));
5112                    startProcessLocked(procs.get(ip), "on-hold", null);
5113                }
5114            }
5115
5116            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5117                // Start looking for apps that are abusing wake locks.
5118                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5119                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5120                // Tell anyone interested that we are done booting!
5121                SystemProperties.set("sys.boot_completed", "1");
5122                SystemProperties.set("dev.bootcomplete", "1");
5123                for (int i=0; i<mStartedUsers.size(); i++) {
5124                    UserStartedState uss = mStartedUsers.valueAt(i);
5125                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5126                        uss.mState = UserStartedState.STATE_RUNNING;
5127                        final int userId = mStartedUsers.keyAt(i);
5128                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5129                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5130                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5131                        broadcastIntentLocked(null, null, intent, null,
5132                                new IIntentReceiver.Stub() {
5133                                    @Override
5134                                    public void performReceive(Intent intent, int resultCode,
5135                                            String data, Bundle extras, boolean ordered,
5136                                            boolean sticky, int sendingUser) {
5137                                        synchronized (ActivityManagerService.this) {
5138                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5139                                                    true, false);
5140                                        }
5141                                    }
5142                                },
5143                                0, null, null,
5144                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5145                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5146                                userId);
5147                    }
5148                }
5149            }
5150        }
5151    }
5152
5153    final void ensureBootCompleted() {
5154        boolean booting;
5155        boolean enableScreen;
5156        synchronized (this) {
5157            booting = mBooting;
5158            mBooting = false;
5159            enableScreen = !mBooted;
5160            mBooted = true;
5161        }
5162
5163        if (booting) {
5164            finishBooting();
5165        }
5166
5167        if (enableScreen) {
5168            enableScreenAfterBoot();
5169        }
5170    }
5171
5172    @Override
5173    public final void activityResumed(IBinder token) {
5174        final long origId = Binder.clearCallingIdentity();
5175        synchronized(this) {
5176            ActivityStack stack = ActivityRecord.getStackLocked(token);
5177            if (stack != null) {
5178                ActivityRecord.activityResumedLocked(token);
5179            }
5180        }
5181        Binder.restoreCallingIdentity(origId);
5182    }
5183
5184    @Override
5185    public final void activityPaused(IBinder token) {
5186        final long origId = Binder.clearCallingIdentity();
5187        synchronized(this) {
5188            ActivityStack stack = ActivityRecord.getStackLocked(token);
5189            if (stack != null) {
5190                stack.activityPausedLocked(token, false);
5191            }
5192        }
5193        Binder.restoreCallingIdentity(origId);
5194    }
5195
5196    @Override
5197    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5198            CharSequence description) {
5199        if (localLOGV) Slog.v(
5200            TAG, "Activity stopped: token=" + token);
5201
5202        // Refuse possible leaked file descriptors
5203        if (icicle != null && icicle.hasFileDescriptors()) {
5204            throw new IllegalArgumentException("File descriptors passed in Bundle");
5205        }
5206
5207        ActivityRecord r = null;
5208
5209        final long origId = Binder.clearCallingIdentity();
5210
5211        synchronized (this) {
5212            r = ActivityRecord.isInStackLocked(token);
5213            if (r != null) {
5214                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5215            }
5216        }
5217
5218        if (r != null) {
5219            sendPendingThumbnail(r, null, null, null, false);
5220        }
5221
5222        trimApplications();
5223
5224        Binder.restoreCallingIdentity(origId);
5225    }
5226
5227    @Override
5228    public final void activityDestroyed(IBinder token) {
5229        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5230        synchronized (this) {
5231            ActivityStack stack = ActivityRecord.getStackLocked(token);
5232            if (stack != null) {
5233                stack.activityDestroyedLocked(token);
5234            }
5235        }
5236    }
5237
5238    @Override
5239    public String getCallingPackage(IBinder token) {
5240        synchronized (this) {
5241            ActivityRecord r = getCallingRecordLocked(token);
5242            return r != null ? r.info.packageName : null;
5243        }
5244    }
5245
5246    @Override
5247    public ComponentName getCallingActivity(IBinder token) {
5248        synchronized (this) {
5249            ActivityRecord r = getCallingRecordLocked(token);
5250            return r != null ? r.intent.getComponent() : null;
5251        }
5252    }
5253
5254    private ActivityRecord getCallingRecordLocked(IBinder token) {
5255        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5256        if (r == null) {
5257            return null;
5258        }
5259        return r.resultTo;
5260    }
5261
5262    @Override
5263    public ComponentName getActivityClassForToken(IBinder token) {
5264        synchronized(this) {
5265            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5266            if (r == null) {
5267                return null;
5268            }
5269            return r.intent.getComponent();
5270        }
5271    }
5272
5273    @Override
5274    public String getPackageForToken(IBinder token) {
5275        synchronized(this) {
5276            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5277            if (r == null) {
5278                return null;
5279            }
5280            return r.packageName;
5281        }
5282    }
5283
5284    @Override
5285    public IIntentSender getIntentSender(int type,
5286            String packageName, IBinder token, String resultWho,
5287            int requestCode, Intent[] intents, String[] resolvedTypes,
5288            int flags, Bundle options, int userId) {
5289        enforceNotIsolatedCaller("getIntentSender");
5290        // Refuse possible leaked file descriptors
5291        if (intents != null) {
5292            if (intents.length < 1) {
5293                throw new IllegalArgumentException("Intents array length must be >= 1");
5294            }
5295            for (int i=0; i<intents.length; i++) {
5296                Intent intent = intents[i];
5297                if (intent != null) {
5298                    if (intent.hasFileDescriptors()) {
5299                        throw new IllegalArgumentException("File descriptors passed in Intent");
5300                    }
5301                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5302                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5303                        throw new IllegalArgumentException(
5304                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5305                    }
5306                    intents[i] = new Intent(intent);
5307                }
5308            }
5309            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5310                throw new IllegalArgumentException(
5311                        "Intent array length does not match resolvedTypes length");
5312            }
5313        }
5314        if (options != null) {
5315            if (options.hasFileDescriptors()) {
5316                throw new IllegalArgumentException("File descriptors passed in options");
5317            }
5318        }
5319
5320        synchronized(this) {
5321            int callingUid = Binder.getCallingUid();
5322            int origUserId = userId;
5323            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5324                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5325                    "getIntentSender", null);
5326            if (origUserId == UserHandle.USER_CURRENT) {
5327                // We don't want to evaluate this until the pending intent is
5328                // actually executed.  However, we do want to always do the
5329                // security checking for it above.
5330                userId = UserHandle.USER_CURRENT;
5331            }
5332            try {
5333                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5334                    int uid = AppGlobals.getPackageManager()
5335                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5336                    if (!UserHandle.isSameApp(callingUid, uid)) {
5337                        String msg = "Permission Denial: getIntentSender() from pid="
5338                            + Binder.getCallingPid()
5339                            + ", uid=" + Binder.getCallingUid()
5340                            + ", (need uid=" + uid + ")"
5341                            + " is not allowed to send as package " + packageName;
5342                        Slog.w(TAG, msg);
5343                        throw new SecurityException(msg);
5344                    }
5345                }
5346
5347                return getIntentSenderLocked(type, packageName, callingUid, userId,
5348                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5349
5350            } catch (RemoteException e) {
5351                throw new SecurityException(e);
5352            }
5353        }
5354    }
5355
5356    IIntentSender getIntentSenderLocked(int type, String packageName,
5357            int callingUid, int userId, IBinder token, String resultWho,
5358            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5359            Bundle options) {
5360        if (DEBUG_MU)
5361            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5362        ActivityRecord activity = null;
5363        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5364            activity = ActivityRecord.isInStackLocked(token);
5365            if (activity == null) {
5366                return null;
5367            }
5368            if (activity.finishing) {
5369                return null;
5370            }
5371        }
5372
5373        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5374        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5375        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5376        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5377                |PendingIntent.FLAG_UPDATE_CURRENT);
5378
5379        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5380                type, packageName, activity, resultWho,
5381                requestCode, intents, resolvedTypes, flags, options, userId);
5382        WeakReference<PendingIntentRecord> ref;
5383        ref = mIntentSenderRecords.get(key);
5384        PendingIntentRecord rec = ref != null ? ref.get() : null;
5385        if (rec != null) {
5386            if (!cancelCurrent) {
5387                if (updateCurrent) {
5388                    if (rec.key.requestIntent != null) {
5389                        rec.key.requestIntent.replaceExtras(intents != null ?
5390                                intents[intents.length - 1] : null);
5391                    }
5392                    if (intents != null) {
5393                        intents[intents.length-1] = rec.key.requestIntent;
5394                        rec.key.allIntents = intents;
5395                        rec.key.allResolvedTypes = resolvedTypes;
5396                    } else {
5397                        rec.key.allIntents = null;
5398                        rec.key.allResolvedTypes = null;
5399                    }
5400                }
5401                return rec;
5402            }
5403            rec.canceled = true;
5404            mIntentSenderRecords.remove(key);
5405        }
5406        if (noCreate) {
5407            return rec;
5408        }
5409        rec = new PendingIntentRecord(this, key, callingUid);
5410        mIntentSenderRecords.put(key, rec.ref);
5411        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5412            if (activity.pendingResults == null) {
5413                activity.pendingResults
5414                        = new HashSet<WeakReference<PendingIntentRecord>>();
5415            }
5416            activity.pendingResults.add(rec.ref);
5417        }
5418        return rec;
5419    }
5420
5421    @Override
5422    public void cancelIntentSender(IIntentSender sender) {
5423        if (!(sender instanceof PendingIntentRecord)) {
5424            return;
5425        }
5426        synchronized(this) {
5427            PendingIntentRecord rec = (PendingIntentRecord)sender;
5428            try {
5429                int uid = AppGlobals.getPackageManager()
5430                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5431                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5432                    String msg = "Permission Denial: cancelIntentSender() from pid="
5433                        + Binder.getCallingPid()
5434                        + ", uid=" + Binder.getCallingUid()
5435                        + " is not allowed to cancel packges "
5436                        + rec.key.packageName;
5437                    Slog.w(TAG, msg);
5438                    throw new SecurityException(msg);
5439                }
5440            } catch (RemoteException e) {
5441                throw new SecurityException(e);
5442            }
5443            cancelIntentSenderLocked(rec, true);
5444        }
5445    }
5446
5447    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5448        rec.canceled = true;
5449        mIntentSenderRecords.remove(rec.key);
5450        if (cleanActivity && rec.key.activity != null) {
5451            rec.key.activity.pendingResults.remove(rec.ref);
5452        }
5453    }
5454
5455    @Override
5456    public String getPackageForIntentSender(IIntentSender pendingResult) {
5457        if (!(pendingResult instanceof PendingIntentRecord)) {
5458            return null;
5459        }
5460        try {
5461            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5462            return res.key.packageName;
5463        } catch (ClassCastException e) {
5464        }
5465        return null;
5466    }
5467
5468    @Override
5469    public int getUidForIntentSender(IIntentSender sender) {
5470        if (sender instanceof PendingIntentRecord) {
5471            try {
5472                PendingIntentRecord res = (PendingIntentRecord)sender;
5473                return res.uid;
5474            } catch (ClassCastException e) {
5475            }
5476        }
5477        return -1;
5478    }
5479
5480    @Override
5481    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5482        if (!(pendingResult instanceof PendingIntentRecord)) {
5483            return false;
5484        }
5485        try {
5486            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5487            if (res.key.allIntents == null) {
5488                return false;
5489            }
5490            for (int i=0; i<res.key.allIntents.length; i++) {
5491                Intent intent = res.key.allIntents[i];
5492                if (intent.getPackage() != null && intent.getComponent() != null) {
5493                    return false;
5494                }
5495            }
5496            return true;
5497        } catch (ClassCastException e) {
5498        }
5499        return false;
5500    }
5501
5502    @Override
5503    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5504        if (!(pendingResult instanceof PendingIntentRecord)) {
5505            return false;
5506        }
5507        try {
5508            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5509            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5510                return true;
5511            }
5512            return false;
5513        } catch (ClassCastException e) {
5514        }
5515        return false;
5516    }
5517
5518    @Override
5519    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5520        if (!(pendingResult instanceof PendingIntentRecord)) {
5521            return null;
5522        }
5523        try {
5524            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5525            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5526        } catch (ClassCastException e) {
5527        }
5528        return null;
5529    }
5530
5531    @Override
5532    public void setProcessLimit(int max) {
5533        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5534                "setProcessLimit()");
5535        synchronized (this) {
5536            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5537            mProcessLimitOverride = max;
5538        }
5539        trimApplications();
5540    }
5541
5542    @Override
5543    public int getProcessLimit() {
5544        synchronized (this) {
5545            return mProcessLimitOverride;
5546        }
5547    }
5548
5549    void foregroundTokenDied(ForegroundToken token) {
5550        synchronized (ActivityManagerService.this) {
5551            synchronized (mPidsSelfLocked) {
5552                ForegroundToken cur
5553                    = mForegroundProcesses.get(token.pid);
5554                if (cur != token) {
5555                    return;
5556                }
5557                mForegroundProcesses.remove(token.pid);
5558                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5559                if (pr == null) {
5560                    return;
5561                }
5562                pr.forcingToForeground = null;
5563                pr.foregroundServices = false;
5564            }
5565            updateOomAdjLocked();
5566        }
5567    }
5568
5569    @Override
5570    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5571        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5572                "setProcessForeground()");
5573        synchronized(this) {
5574            boolean changed = false;
5575
5576            synchronized (mPidsSelfLocked) {
5577                ProcessRecord pr = mPidsSelfLocked.get(pid);
5578                if (pr == null && isForeground) {
5579                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5580                    return;
5581                }
5582                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5583                if (oldToken != null) {
5584                    oldToken.token.unlinkToDeath(oldToken, 0);
5585                    mForegroundProcesses.remove(pid);
5586                    if (pr != null) {
5587                        pr.forcingToForeground = null;
5588                    }
5589                    changed = true;
5590                }
5591                if (isForeground && token != null) {
5592                    ForegroundToken newToken = new ForegroundToken() {
5593                        @Override
5594                        public void binderDied() {
5595                            foregroundTokenDied(this);
5596                        }
5597                    };
5598                    newToken.pid = pid;
5599                    newToken.token = token;
5600                    try {
5601                        token.linkToDeath(newToken, 0);
5602                        mForegroundProcesses.put(pid, newToken);
5603                        pr.forcingToForeground = token;
5604                        changed = true;
5605                    } catch (RemoteException e) {
5606                        // If the process died while doing this, we will later
5607                        // do the cleanup with the process death link.
5608                    }
5609                }
5610            }
5611
5612            if (changed) {
5613                updateOomAdjLocked();
5614            }
5615        }
5616    }
5617
5618    // =========================================================
5619    // PERMISSIONS
5620    // =========================================================
5621
5622    static class PermissionController extends IPermissionController.Stub {
5623        ActivityManagerService mActivityManagerService;
5624        PermissionController(ActivityManagerService activityManagerService) {
5625            mActivityManagerService = activityManagerService;
5626        }
5627
5628        @Override
5629        public boolean checkPermission(String permission, int pid, int uid) {
5630            return mActivityManagerService.checkPermission(permission, pid,
5631                    uid) == PackageManager.PERMISSION_GRANTED;
5632        }
5633    }
5634
5635    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5636        @Override
5637        public int checkComponentPermission(String permission, int pid, int uid,
5638                int owningUid, boolean exported) {
5639            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5640                    owningUid, exported);
5641        }
5642
5643        @Override
5644        public Object getAMSLock() {
5645            return ActivityManagerService.this;
5646        }
5647    }
5648
5649    /**
5650     * This can be called with or without the global lock held.
5651     */
5652    int checkComponentPermission(String permission, int pid, int uid,
5653            int owningUid, boolean exported) {
5654        // We might be performing an operation on behalf of an indirect binder
5655        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5656        // client identity accordingly before proceeding.
5657        Identity tlsIdentity = sCallerIdentity.get();
5658        if (tlsIdentity != null) {
5659            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5660                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5661            uid = tlsIdentity.uid;
5662            pid = tlsIdentity.pid;
5663        }
5664
5665        if (pid == MY_PID) {
5666            return PackageManager.PERMISSION_GRANTED;
5667        }
5668
5669        return ActivityManager.checkComponentPermission(permission, uid,
5670                owningUid, exported);
5671    }
5672
5673    /**
5674     * As the only public entry point for permissions checking, this method
5675     * can enforce the semantic that requesting a check on a null global
5676     * permission is automatically denied.  (Internally a null permission
5677     * string is used when calling {@link #checkComponentPermission} in cases
5678     * when only uid-based security is needed.)
5679     *
5680     * This can be called with or without the global lock held.
5681     */
5682    @Override
5683    public int checkPermission(String permission, int pid, int uid) {
5684        if (permission == null) {
5685            return PackageManager.PERMISSION_DENIED;
5686        }
5687        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5688    }
5689
5690    /**
5691     * Binder IPC calls go through the public entry point.
5692     * This can be called with or without the global lock held.
5693     */
5694    int checkCallingPermission(String permission) {
5695        return checkPermission(permission,
5696                Binder.getCallingPid(),
5697                UserHandle.getAppId(Binder.getCallingUid()));
5698    }
5699
5700    /**
5701     * This can be called with or without the global lock held.
5702     */
5703    void enforceCallingPermission(String permission, String func) {
5704        if (checkCallingPermission(permission)
5705                == PackageManager.PERMISSION_GRANTED) {
5706            return;
5707        }
5708
5709        String msg = "Permission Denial: " + func + " from pid="
5710                + Binder.getCallingPid()
5711                + ", uid=" + Binder.getCallingUid()
5712                + " requires " + permission;
5713        Slog.w(TAG, msg);
5714        throw new SecurityException(msg);
5715    }
5716
5717    /**
5718     * Determine if UID is holding permissions required to access {@link Uri} in
5719     * the given {@link ProviderInfo}. Final permission checking is always done
5720     * in {@link ContentProvider}.
5721     */
5722    private final boolean checkHoldingPermissionsLocked(
5723            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5724        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5725                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5726
5727        if (pi.applicationInfo.uid == uid) {
5728            return true;
5729        } else if (!pi.exported) {
5730            return false;
5731        }
5732
5733        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5734        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5735        try {
5736            // check if target holds top-level <provider> permissions
5737            if (!readMet && pi.readPermission != null
5738                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5739                readMet = true;
5740            }
5741            if (!writeMet && pi.writePermission != null
5742                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5743                writeMet = true;
5744            }
5745
5746            // track if unprotected read/write is allowed; any denied
5747            // <path-permission> below removes this ability
5748            boolean allowDefaultRead = pi.readPermission == null;
5749            boolean allowDefaultWrite = pi.writePermission == null;
5750
5751            // check if target holds any <path-permission> that match uri
5752            final PathPermission[] pps = pi.pathPermissions;
5753            if (pps != null) {
5754                final String path = uri.getPath();
5755                int i = pps.length;
5756                while (i > 0 && (!readMet || !writeMet)) {
5757                    i--;
5758                    PathPermission pp = pps[i];
5759                    if (pp.match(path)) {
5760                        if (!readMet) {
5761                            final String pprperm = pp.getReadPermission();
5762                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5763                                    + pprperm + " for " + pp.getPath()
5764                                    + ": match=" + pp.match(path)
5765                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5766                            if (pprperm != null) {
5767                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5768                                    readMet = true;
5769                                } else {
5770                                    allowDefaultRead = false;
5771                                }
5772                            }
5773                        }
5774                        if (!writeMet) {
5775                            final String ppwperm = pp.getWritePermission();
5776                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5777                                    + ppwperm + " for " + pp.getPath()
5778                                    + ": match=" + pp.match(path)
5779                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5780                            if (ppwperm != null) {
5781                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5782                                    writeMet = true;
5783                                } else {
5784                                    allowDefaultWrite = false;
5785                                }
5786                            }
5787                        }
5788                    }
5789                }
5790            }
5791
5792            // grant unprotected <provider> read/write, if not blocked by
5793            // <path-permission> above
5794            if (allowDefaultRead) readMet = true;
5795            if (allowDefaultWrite) writeMet = true;
5796
5797        } catch (RemoteException e) {
5798            return false;
5799        }
5800
5801        return readMet && writeMet;
5802    }
5803
5804    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5805        ProviderInfo pi = null;
5806        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5807        if (cpr != null) {
5808            pi = cpr.info;
5809        } else {
5810            try {
5811                pi = AppGlobals.getPackageManager().resolveContentProvider(
5812                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5813            } catch (RemoteException ex) {
5814            }
5815        }
5816        return pi;
5817    }
5818
5819    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5820        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5821        if (targetUris != null) {
5822            return targetUris.get(uri);
5823        } else {
5824            return null;
5825        }
5826    }
5827
5828    private UriPermission findOrCreateUriPermissionLocked(
5829            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5830        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5831        if (targetUris == null) {
5832            targetUris = Maps.newArrayMap();
5833            mGrantedUriPermissions.put(targetUid, targetUris);
5834        }
5835
5836        UriPermission perm = targetUris.get(uri);
5837        if (perm == null) {
5838            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5839            targetUris.put(uri, perm);
5840        }
5841
5842        return perm;
5843    }
5844
5845    private final boolean checkUriPermissionLocked(
5846            Uri uri, int uid, int modeFlags, int minStrength) {
5847        // Root gets to do everything.
5848        if (uid == 0) {
5849            return true;
5850        }
5851        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5852        if (perms == null) return false;
5853        UriPermission perm = perms.get(uri);
5854        if (perm == null) return false;
5855        return perm.getStrength(modeFlags) >= minStrength;
5856    }
5857
5858    @Override
5859    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5860        enforceNotIsolatedCaller("checkUriPermission");
5861
5862        // Another redirected-binder-call permissions check as in
5863        // {@link checkComponentPermission}.
5864        Identity tlsIdentity = sCallerIdentity.get();
5865        if (tlsIdentity != null) {
5866            uid = tlsIdentity.uid;
5867            pid = tlsIdentity.pid;
5868        }
5869
5870        // Our own process gets to do everything.
5871        if (pid == MY_PID) {
5872            return PackageManager.PERMISSION_GRANTED;
5873        }
5874        synchronized(this) {
5875            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5876                    ? PackageManager.PERMISSION_GRANTED
5877                    : PackageManager.PERMISSION_DENIED;
5878        }
5879    }
5880
5881    /**
5882     * Check if the targetPkg can be granted permission to access uri by
5883     * the callingUid using the given modeFlags.  Throws a security exception
5884     * if callingUid is not allowed to do this.  Returns the uid of the target
5885     * if the URI permission grant should be performed; returns -1 if it is not
5886     * needed (for example targetPkg already has permission to access the URI).
5887     * If you already know the uid of the target, you can supply it in
5888     * lastTargetUid else set that to -1.
5889     */
5890    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5891            Uri uri, int modeFlags, int lastTargetUid) {
5892        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5893        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5894                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5895        if (modeFlags == 0) {
5896            return -1;
5897        }
5898
5899        if (targetPkg != null) {
5900            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5901                    "Checking grant " + targetPkg + " permission to " + uri);
5902        }
5903
5904        final IPackageManager pm = AppGlobals.getPackageManager();
5905
5906        // If this is not a content: uri, we can't do anything with it.
5907        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5908            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5909                    "Can't grant URI permission for non-content URI: " + uri);
5910            return -1;
5911        }
5912
5913        final String authority = uri.getAuthority();
5914        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5915        if (pi == null) {
5916            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5917            return -1;
5918        }
5919
5920        int targetUid = lastTargetUid;
5921        if (targetUid < 0 && targetPkg != null) {
5922            try {
5923                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5924                if (targetUid < 0) {
5925                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5926                            "Can't grant URI permission no uid for: " + targetPkg);
5927                    return -1;
5928                }
5929            } catch (RemoteException ex) {
5930                return -1;
5931            }
5932        }
5933
5934        if (targetUid >= 0) {
5935            // First...  does the target actually need this permission?
5936            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5937                // No need to grant the target this permission.
5938                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5939                        "Target " + targetPkg + " already has full permission to " + uri);
5940                return -1;
5941            }
5942        } else {
5943            // First...  there is no target package, so can anyone access it?
5944            boolean allowed = pi.exported;
5945            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5946                if (pi.readPermission != null) {
5947                    allowed = false;
5948                }
5949            }
5950            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5951                if (pi.writePermission != null) {
5952                    allowed = false;
5953                }
5954            }
5955            if (allowed) {
5956                return -1;
5957            }
5958        }
5959
5960        // Second...  is the provider allowing granting of URI permissions?
5961        if (!pi.grantUriPermissions) {
5962            throw new SecurityException("Provider " + pi.packageName
5963                    + "/" + pi.name
5964                    + " does not allow granting of Uri permissions (uri "
5965                    + uri + ")");
5966        }
5967        if (pi.uriPermissionPatterns != null) {
5968            final int N = pi.uriPermissionPatterns.length;
5969            boolean allowed = false;
5970            for (int i=0; i<N; i++) {
5971                if (pi.uriPermissionPatterns[i] != null
5972                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5973                    allowed = true;
5974                    break;
5975                }
5976            }
5977            if (!allowed) {
5978                throw new SecurityException("Provider " + pi.packageName
5979                        + "/" + pi.name
5980                        + " does not allow granting of permission to path of Uri "
5981                        + uri);
5982            }
5983        }
5984
5985        // Third...  does the caller itself have permission to access
5986        // this uri?
5987        if (callingUid != Process.myUid()) {
5988            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5989                // Require they hold a strong enough Uri permission
5990                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
5991                        : UriPermission.STRENGTH_OWNED;
5992                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
5993                    throw new SecurityException("Uid " + callingUid
5994                            + " does not have permission to uri " + uri);
5995                }
5996            }
5997        }
5998
5999        return targetUid;
6000    }
6001
6002    @Override
6003    public int checkGrantUriPermission(int callingUid, String targetPkg,
6004            Uri uri, int modeFlags) {
6005        enforceNotIsolatedCaller("checkGrantUriPermission");
6006        synchronized(this) {
6007            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6008        }
6009    }
6010
6011    void grantUriPermissionUncheckedLocked(
6012            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6013        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6014        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6015                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6016        if (modeFlags == 0) {
6017            return;
6018        }
6019
6020        // So here we are: the caller has the assumed permission
6021        // to the uri, and the target doesn't.  Let's now give this to
6022        // the target.
6023
6024        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6025                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6026
6027        final String authority = uri.getAuthority();
6028        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6029        if (pi == null) {
6030            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6031            return;
6032        }
6033
6034        final UriPermission perm = findOrCreateUriPermissionLocked(
6035                pi.packageName, targetPkg, targetUid, uri);
6036        perm.grantModes(modeFlags, persistable, owner);
6037    }
6038
6039    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6040            int modeFlags, UriPermissionOwner owner) {
6041        if (targetPkg == null) {
6042            throw new NullPointerException("targetPkg");
6043        }
6044
6045        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6046        if (targetUid < 0) {
6047            return;
6048        }
6049
6050        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6051    }
6052
6053    static class NeededUriGrants extends ArrayList<Uri> {
6054        final String targetPkg;
6055        final int targetUid;
6056        final int flags;
6057
6058        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6059            this.targetPkg = targetPkg;
6060            this.targetUid = targetUid;
6061            this.flags = flags;
6062        }
6063    }
6064
6065    /**
6066     * Like checkGrantUriPermissionLocked, but takes an Intent.
6067     */
6068    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6069            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6070        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6071                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6072                + " clip=" + (intent != null ? intent.getClipData() : null)
6073                + " from " + intent + "; flags=0x"
6074                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6075
6076        if (targetPkg == null) {
6077            throw new NullPointerException("targetPkg");
6078        }
6079
6080        if (intent == null) {
6081            return null;
6082        }
6083        Uri data = intent.getData();
6084        ClipData clip = intent.getClipData();
6085        if (data == null && clip == null) {
6086            return null;
6087        }
6088
6089        if (data != null) {
6090            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6091                mode, needed != null ? needed.targetUid : -1);
6092            if (targetUid > 0) {
6093                if (needed == null) {
6094                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6095                }
6096                needed.add(data);
6097            }
6098        }
6099        if (clip != null) {
6100            for (int i=0; i<clip.getItemCount(); i++) {
6101                Uri uri = clip.getItemAt(i).getUri();
6102                if (uri != null) {
6103                    int targetUid = -1;
6104                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6105                            mode, needed != null ? needed.targetUid : -1);
6106                    if (targetUid > 0) {
6107                        if (needed == null) {
6108                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6109                        }
6110                        needed.add(uri);
6111                    }
6112                } else {
6113                    Intent clipIntent = clip.getItemAt(i).getIntent();
6114                    if (clipIntent != null) {
6115                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6116                                callingUid, targetPkg, clipIntent, mode, needed);
6117                        if (newNeeded != null) {
6118                            needed = newNeeded;
6119                        }
6120                    }
6121                }
6122            }
6123        }
6124
6125        return needed;
6126    }
6127
6128    /**
6129     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6130     */
6131    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6132            UriPermissionOwner owner) {
6133        if (needed != null) {
6134            for (int i=0; i<needed.size(); i++) {
6135                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6136                        needed.get(i), needed.flags, owner);
6137            }
6138        }
6139    }
6140
6141    void grantUriPermissionFromIntentLocked(int callingUid,
6142            String targetPkg, Intent intent, UriPermissionOwner owner) {
6143        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6144                intent, intent != null ? intent.getFlags() : 0, null);
6145        if (needed == null) {
6146            return;
6147        }
6148
6149        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6150    }
6151
6152    @Override
6153    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6154            Uri uri, int modeFlags) {
6155        enforceNotIsolatedCaller("grantUriPermission");
6156        synchronized(this) {
6157            final ProcessRecord r = getRecordForAppLocked(caller);
6158            if (r == null) {
6159                throw new SecurityException("Unable to find app for caller "
6160                        + caller
6161                        + " when granting permission to uri " + uri);
6162            }
6163            if (targetPkg == null) {
6164                throw new IllegalArgumentException("null target");
6165            }
6166            if (uri == null) {
6167                throw new IllegalArgumentException("null uri");
6168            }
6169
6170            // Persistable only supported through Intents
6171            Preconditions.checkFlagsArgument(modeFlags,
6172                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6173
6174            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6175                    null);
6176        }
6177    }
6178
6179    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6180        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6181                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6182            ArrayMap<Uri, UriPermission> perms
6183                    = mGrantedUriPermissions.get(perm.targetUid);
6184            if (perms != null) {
6185                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6186                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6187                perms.remove(perm.uri);
6188                if (perms.size() == 0) {
6189                    mGrantedUriPermissions.remove(perm.targetUid);
6190                }
6191            }
6192        }
6193    }
6194
6195    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6196        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6197
6198        final IPackageManager pm = AppGlobals.getPackageManager();
6199        final String authority = uri.getAuthority();
6200        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6201        if (pi == null) {
6202            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6203            return;
6204        }
6205
6206        // Does the caller have this permission on the URI?
6207        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6208            // Right now, if you are not the original owner of the permission,
6209            // you are not allowed to revoke it.
6210            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6211                throw new SecurityException("Uid " + callingUid
6212                        + " does not have permission to uri " + uri);
6213            //}
6214        }
6215
6216        boolean persistChanged = false;
6217
6218        // Go through all of the permissions and remove any that match.
6219        final List<String> SEGMENTS = uri.getPathSegments();
6220        if (SEGMENTS != null) {
6221            final int NS = SEGMENTS.size();
6222            int N = mGrantedUriPermissions.size();
6223            for (int i=0; i<N; i++) {
6224                ArrayMap<Uri, UriPermission> perms
6225                        = mGrantedUriPermissions.valueAt(i);
6226                Iterator<UriPermission> it = perms.values().iterator();
6227            toploop:
6228                while (it.hasNext()) {
6229                    UriPermission perm = it.next();
6230                    Uri targetUri = perm.uri;
6231                    if (!authority.equals(targetUri.getAuthority())) {
6232                        continue;
6233                    }
6234                    List<String> targetSegments = targetUri.getPathSegments();
6235                    if (targetSegments == null) {
6236                        continue;
6237                    }
6238                    if (targetSegments.size() < NS) {
6239                        continue;
6240                    }
6241                    for (int j=0; j<NS; j++) {
6242                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6243                            continue toploop;
6244                        }
6245                    }
6246                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6247                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6248                    persistChanged |= perm.clearModes(modeFlags, true);
6249                    if (perm.modeFlags == 0) {
6250                        it.remove();
6251                    }
6252                }
6253                if (perms.size() == 0) {
6254                    mGrantedUriPermissions.remove(
6255                            mGrantedUriPermissions.keyAt(i));
6256                    N--;
6257                    i--;
6258                }
6259            }
6260        }
6261
6262        if (persistChanged) {
6263            schedulePersistUriGrants();
6264        }
6265    }
6266
6267    @Override
6268    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6269            int modeFlags) {
6270        enforceNotIsolatedCaller("revokeUriPermission");
6271        synchronized(this) {
6272            final ProcessRecord r = getRecordForAppLocked(caller);
6273            if (r == null) {
6274                throw new SecurityException("Unable to find app for caller "
6275                        + caller
6276                        + " when revoking permission to uri " + uri);
6277            }
6278            if (uri == null) {
6279                Slog.w(TAG, "revokeUriPermission: null uri");
6280                return;
6281            }
6282
6283            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6284                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6285            if (modeFlags == 0) {
6286                return;
6287            }
6288
6289            final IPackageManager pm = AppGlobals.getPackageManager();
6290            final String authority = uri.getAuthority();
6291            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6292            if (pi == null) {
6293                Slog.w(TAG, "No content provider found for permission revoke: "
6294                        + uri.toSafeString());
6295                return;
6296            }
6297
6298            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6299        }
6300    }
6301
6302    /**
6303     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6304     * given package.
6305     *
6306     * @param packageName Package name to match, or {@code null} to apply to all
6307     *            packages.
6308     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6309     *            to all users.
6310     * @param persistable If persistable grants should be removed.
6311     */
6312    private void removeUriPermissionsForPackageLocked(
6313            String packageName, int userHandle, boolean persistable) {
6314        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6315            throw new IllegalArgumentException("Must narrow by either package or user");
6316        }
6317
6318        boolean persistChanged = false;
6319
6320        final int size = mGrantedUriPermissions.size();
6321        for (int i = 0; i < size; i++) {
6322            // Only inspect grants matching user
6323            if (userHandle == UserHandle.USER_ALL
6324                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6325                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6326                        .values().iterator();
6327                while (it.hasNext()) {
6328                    final UriPermission perm = it.next();
6329
6330                    // Only inspect grants matching package
6331                    if (packageName == null || perm.sourcePkg.equals(packageName)
6332                            || perm.targetPkg.equals(packageName)) {
6333                        persistChanged |= perm.clearModes(~0, persistable);
6334
6335                        // Only remove when no modes remain; any persisted grants
6336                        // will keep this alive.
6337                        if (perm.modeFlags == 0) {
6338                            it.remove();
6339                        }
6340                    }
6341                }
6342            }
6343        }
6344
6345        if (persistChanged) {
6346            schedulePersistUriGrants();
6347        }
6348    }
6349
6350    @Override
6351    public IBinder newUriPermissionOwner(String name) {
6352        enforceNotIsolatedCaller("newUriPermissionOwner");
6353        synchronized(this) {
6354            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6355            return owner.getExternalTokenLocked();
6356        }
6357    }
6358
6359    @Override
6360    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6361            Uri uri, int modeFlags) {
6362        synchronized(this) {
6363            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6364            if (owner == null) {
6365                throw new IllegalArgumentException("Unknown owner: " + token);
6366            }
6367            if (fromUid != Binder.getCallingUid()) {
6368                if (Binder.getCallingUid() != Process.myUid()) {
6369                    // Only system code can grant URI permissions on behalf
6370                    // of other users.
6371                    throw new SecurityException("nice try");
6372                }
6373            }
6374            if (targetPkg == null) {
6375                throw new IllegalArgumentException("null target");
6376            }
6377            if (uri == null) {
6378                throw new IllegalArgumentException("null uri");
6379            }
6380
6381            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6382        }
6383    }
6384
6385    @Override
6386    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6387        synchronized(this) {
6388            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6389            if (owner == null) {
6390                throw new IllegalArgumentException("Unknown owner: " + token);
6391            }
6392
6393            if (uri == null) {
6394                owner.removeUriPermissionsLocked(mode);
6395            } else {
6396                owner.removeUriPermissionLocked(uri, mode);
6397            }
6398        }
6399    }
6400
6401    private void schedulePersistUriGrants() {
6402        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6403            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6404                    10 * DateUtils.SECOND_IN_MILLIS);
6405        }
6406    }
6407
6408    private void writeGrantedUriPermissions() {
6409        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6410
6411        // Snapshot permissions so we can persist without lock
6412        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6413        synchronized (this) {
6414            final int size = mGrantedUriPermissions.size();
6415            for (int i = 0 ; i < size; i++) {
6416                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6417                    if (perm.persistedModeFlags != 0) {
6418                        persist.add(perm.snapshot());
6419                    }
6420                }
6421            }
6422        }
6423
6424        FileOutputStream fos = null;
6425        try {
6426            fos = mGrantFile.startWrite();
6427
6428            XmlSerializer out = new FastXmlSerializer();
6429            out.setOutput(fos, "utf-8");
6430            out.startDocument(null, true);
6431            out.startTag(null, TAG_URI_GRANTS);
6432            for (UriPermission.Snapshot perm : persist) {
6433                out.startTag(null, TAG_URI_GRANT);
6434                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6435                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6436                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6437                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6438                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6439                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6440                out.endTag(null, TAG_URI_GRANT);
6441            }
6442            out.endTag(null, TAG_URI_GRANTS);
6443            out.endDocument();
6444
6445            mGrantFile.finishWrite(fos);
6446        } catch (IOException e) {
6447            if (fos != null) {
6448                mGrantFile.failWrite(fos);
6449            }
6450        }
6451    }
6452
6453    private void readGrantedUriPermissionsLocked() {
6454        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6455
6456        final long now = System.currentTimeMillis();
6457
6458        FileInputStream fis = null;
6459        try {
6460            fis = mGrantFile.openRead();
6461            final XmlPullParser in = Xml.newPullParser();
6462            in.setInput(fis, null);
6463
6464            int type;
6465            while ((type = in.next()) != END_DOCUMENT) {
6466                final String tag = in.getName();
6467                if (type == START_TAG) {
6468                    if (TAG_URI_GRANT.equals(tag)) {
6469                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6470                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6471                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6472                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6473                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6474                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6475
6476                        // Sanity check that provider still belongs to source package
6477                        final ProviderInfo pi = getProviderInfoLocked(
6478                                uri.getAuthority(), userHandle);
6479                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6480                            int targetUid = -1;
6481                            try {
6482                                targetUid = AppGlobals.getPackageManager()
6483                                        .getPackageUid(targetPkg, userHandle);
6484                            } catch (RemoteException e) {
6485                            }
6486                            if (targetUid != -1) {
6487                                final UriPermission perm = findOrCreateUriPermissionLocked(
6488                                        sourcePkg, targetPkg, targetUid, uri);
6489                                perm.initPersistedModes(modeFlags, createdTime);
6490                            }
6491                        } else {
6492                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6493                                    + " but instead found " + pi);
6494                        }
6495                    }
6496                }
6497            }
6498        } catch (FileNotFoundException e) {
6499            // Missing grants is okay
6500        } catch (IOException e) {
6501            Log.wtf(TAG, "Failed reading Uri grants", e);
6502        } catch (XmlPullParserException e) {
6503            Log.wtf(TAG, "Failed reading Uri grants", e);
6504        } finally {
6505            IoUtils.closeQuietly(fis);
6506        }
6507    }
6508
6509    @Override
6510    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6511        enforceNotIsolatedCaller("takePersistableUriPermission");
6512
6513        Preconditions.checkFlagsArgument(modeFlags,
6514                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6515
6516        synchronized (this) {
6517            final int callingUid = Binder.getCallingUid();
6518            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6519            if (perm == null) {
6520                throw new SecurityException("No permission grant found for UID " + callingUid
6521                        + " and Uri " + uri.toSafeString());
6522            }
6523
6524            boolean persistChanged = perm.takePersistableModes(modeFlags);
6525            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6526
6527            if (persistChanged) {
6528                schedulePersistUriGrants();
6529            }
6530        }
6531    }
6532
6533    @Override
6534    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6535        enforceNotIsolatedCaller("releasePersistableUriPermission");
6536
6537        Preconditions.checkFlagsArgument(modeFlags,
6538                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6539
6540        synchronized (this) {
6541            final int callingUid = Binder.getCallingUid();
6542
6543            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6544            if (perm == null) {
6545                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6546                        + uri.toSafeString());
6547                return;
6548            }
6549
6550            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6551            removeUriPermissionIfNeededLocked(perm);
6552            if (persistChanged) {
6553                schedulePersistUriGrants();
6554            }
6555        }
6556    }
6557
6558    /**
6559     * Prune any older {@link UriPermission} for the given UID until outstanding
6560     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6561     *
6562     * @return if any mutations occured that require persisting.
6563     */
6564    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6565        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6566        if (perms == null) return false;
6567        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6568
6569        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6570        for (UriPermission perm : perms.values()) {
6571            if (perm.persistedModeFlags != 0) {
6572                persisted.add(perm);
6573            }
6574        }
6575
6576        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6577        if (trimCount <= 0) return false;
6578
6579        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6580        for (int i = 0; i < trimCount; i++) {
6581            final UriPermission perm = persisted.get(i);
6582
6583            if (DEBUG_URI_PERMISSION) {
6584                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6585            }
6586
6587            perm.releasePersistableModes(~0);
6588            removeUriPermissionIfNeededLocked(perm);
6589        }
6590
6591        return true;
6592    }
6593
6594    @Override
6595    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6596            String packageName, boolean incoming) {
6597        enforceNotIsolatedCaller("getPersistedUriPermissions");
6598        Preconditions.checkNotNull(packageName, "packageName");
6599
6600        final int callingUid = Binder.getCallingUid();
6601        final IPackageManager pm = AppGlobals.getPackageManager();
6602        try {
6603            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6604            if (packageUid != callingUid) {
6605                throw new SecurityException(
6606                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6607            }
6608        } catch (RemoteException e) {
6609            throw new SecurityException("Failed to verify package name ownership");
6610        }
6611
6612        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6613        synchronized (this) {
6614            if (incoming) {
6615                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6616                if (perms == null) {
6617                    Slog.w(TAG, "No permission grants found for " + packageName);
6618                } else {
6619                    final int size = perms.size();
6620                    for (int i = 0; i < size; i++) {
6621                        final UriPermission perm = perms.valueAt(i);
6622                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6623                            result.add(perm.buildPersistedPublicApiObject());
6624                        }
6625                    }
6626                }
6627            } else {
6628                final int size = mGrantedUriPermissions.size();
6629                for (int i = 0; i < size; i++) {
6630                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6631                    final int permsSize = perms.size();
6632                    for (int j = 0; j < permsSize; j++) {
6633                        final UriPermission perm = perms.valueAt(j);
6634                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6635                            result.add(perm.buildPersistedPublicApiObject());
6636                        }
6637                    }
6638                }
6639            }
6640        }
6641        return new ParceledListSlice<android.content.UriPermission>(result);
6642    }
6643
6644    @Override
6645    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6646        synchronized (this) {
6647            ProcessRecord app =
6648                who != null ? getRecordForAppLocked(who) : null;
6649            if (app == null) return;
6650
6651            Message msg = Message.obtain();
6652            msg.what = WAIT_FOR_DEBUGGER_MSG;
6653            msg.obj = app;
6654            msg.arg1 = waiting ? 1 : 0;
6655            mHandler.sendMessage(msg);
6656        }
6657    }
6658
6659    @Override
6660    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6661        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6662        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6663        outInfo.availMem = Process.getFreeMemory();
6664        outInfo.totalMem = Process.getTotalMemory();
6665        outInfo.threshold = homeAppMem;
6666        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6667        outInfo.hiddenAppThreshold = cachedAppMem;
6668        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6669                ProcessList.SERVICE_ADJ);
6670        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6671                ProcessList.VISIBLE_APP_ADJ);
6672        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6673                ProcessList.FOREGROUND_APP_ADJ);
6674    }
6675
6676    // =========================================================
6677    // TASK MANAGEMENT
6678    // =========================================================
6679
6680    @Override
6681    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6682                         IThumbnailReceiver receiver) {
6683        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6684
6685        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6686        ActivityRecord topRecord = null;
6687
6688        synchronized(this) {
6689            if (localLOGV) Slog.v(
6690                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6691                + ", receiver=" + receiver);
6692
6693            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6694                    != PackageManager.PERMISSION_GRANTED) {
6695                if (receiver != null) {
6696                    // If the caller wants to wait for pending thumbnails,
6697                    // it ain't gonna get them.
6698                    try {
6699                        receiver.finished();
6700                    } catch (RemoteException ex) {
6701                    }
6702                }
6703                String msg = "Permission Denial: getTasks() from pid="
6704                        + Binder.getCallingPid()
6705                        + ", uid=" + Binder.getCallingUid()
6706                        + " requires " + android.Manifest.permission.GET_TASKS;
6707                Slog.w(TAG, msg);
6708                throw new SecurityException(msg);
6709            }
6710
6711            // TODO: Improve with MRU list from all ActivityStacks.
6712            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6713
6714            if (!pending.pendingRecords.isEmpty()) {
6715                mPendingThumbnails.add(pending);
6716            }
6717        }
6718
6719        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6720
6721        if (topRecord != null) {
6722            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6723            try {
6724                IApplicationThread topThumbnail = topRecord.app.thread;
6725                topThumbnail.requestThumbnail(topRecord.appToken);
6726            } catch (Exception e) {
6727                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6728                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6729            }
6730        }
6731
6732        if (pending == null && receiver != null) {
6733            // In this case all thumbnails were available and the client
6734            // is being asked to be told when the remaining ones come in...
6735            // which is unusually, since the top-most currently running
6736            // activity should never have a canned thumbnail!  Oh well.
6737            try {
6738                receiver.finished();
6739            } catch (RemoteException ex) {
6740            }
6741        }
6742
6743        return list;
6744    }
6745
6746    TaskRecord getMostRecentTask() {
6747        return mRecentTasks.get(0);
6748    }
6749
6750    @Override
6751    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6752            int flags, int userId) {
6753        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6754                false, true, "getRecentTasks", null);
6755
6756        synchronized (this) {
6757            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6758                    "getRecentTasks()");
6759            final boolean detailed = checkCallingPermission(
6760                    android.Manifest.permission.GET_DETAILED_TASKS)
6761                    == PackageManager.PERMISSION_GRANTED;
6762
6763            IPackageManager pm = AppGlobals.getPackageManager();
6764
6765            final int N = mRecentTasks.size();
6766            ArrayList<ActivityManager.RecentTaskInfo> res
6767                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6768                            maxNum < N ? maxNum : N);
6769            for (int i=0; i<N && maxNum > 0; i++) {
6770                TaskRecord tr = mRecentTasks.get(i);
6771                // Only add calling user's recent tasks
6772                if (tr.userId != userId) continue;
6773                // Return the entry if desired by the caller.  We always return
6774                // the first entry, because callers always expect this to be the
6775                // foreground app.  We may filter others if the caller has
6776                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6777                // we should exclude the entry.
6778
6779                if (i == 0
6780                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6781                        || (tr.intent == null)
6782                        || ((tr.intent.getFlags()
6783                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6784                    ActivityManager.RecentTaskInfo rti
6785                            = new ActivityManager.RecentTaskInfo();
6786                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6787                    rti.persistentId = tr.taskId;
6788                    rti.baseIntent = new Intent(
6789                            tr.intent != null ? tr.intent : tr.affinityIntent);
6790                    if (!detailed) {
6791                        rti.baseIntent.replaceExtras((Bundle)null);
6792                    }
6793                    rti.origActivity = tr.origActivity;
6794                    rti.description = tr.lastDescription;
6795                    rti.stackId = tr.stack.mStackId;
6796
6797                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6798                        // Check whether this activity is currently available.
6799                        try {
6800                            if (rti.origActivity != null) {
6801                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6802                                        == null) {
6803                                    continue;
6804                                }
6805                            } else if (rti.baseIntent != null) {
6806                                if (pm.queryIntentActivities(rti.baseIntent,
6807                                        null, 0, userId) == null) {
6808                                    continue;
6809                                }
6810                            }
6811                        } catch (RemoteException e) {
6812                            // Will never happen.
6813                        }
6814                    }
6815
6816                    res.add(rti);
6817                    maxNum--;
6818                }
6819            }
6820            return res;
6821        }
6822    }
6823
6824    private TaskRecord recentTaskForIdLocked(int id) {
6825        final int N = mRecentTasks.size();
6826            for (int i=0; i<N; i++) {
6827                TaskRecord tr = mRecentTasks.get(i);
6828                if (tr.taskId == id) {
6829                    return tr;
6830                }
6831            }
6832            return null;
6833    }
6834
6835    @Override
6836    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6837        synchronized (this) {
6838            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6839                    "getTaskThumbnails()");
6840            TaskRecord tr = recentTaskForIdLocked(id);
6841            if (tr != null) {
6842                return tr.getTaskThumbnailsLocked();
6843            }
6844        }
6845        return null;
6846    }
6847
6848    @Override
6849    public Bitmap getTaskTopThumbnail(int id) {
6850        synchronized (this) {
6851            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6852                    "getTaskTopThumbnail()");
6853            TaskRecord tr = recentTaskForIdLocked(id);
6854            if (tr != null) {
6855                return tr.getTaskTopThumbnailLocked();
6856            }
6857        }
6858        return null;
6859    }
6860
6861    @Override
6862    public boolean removeSubTask(int taskId, int subTaskIndex) {
6863        synchronized (this) {
6864            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6865                    "removeSubTask()");
6866            long ident = Binder.clearCallingIdentity();
6867            try {
6868                TaskRecord tr = recentTaskForIdLocked(taskId);
6869                if (tr != null) {
6870                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6871                }
6872                return false;
6873            } finally {
6874                Binder.restoreCallingIdentity(ident);
6875            }
6876        }
6877    }
6878
6879    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6880        if (!pr.killedByAm) {
6881            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6882            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6883                    pr.processName, pr.setAdj, reason);
6884            pr.killedByAm = true;
6885            Process.killProcessQuiet(pr.pid);
6886        }
6887    }
6888
6889    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6890        tr.disposeThumbnail();
6891        mRecentTasks.remove(tr);
6892        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6893        Intent baseIntent = new Intent(
6894                tr.intent != null ? tr.intent : tr.affinityIntent);
6895        ComponentName component = baseIntent.getComponent();
6896        if (component == null) {
6897            Slog.w(TAG, "Now component for base intent of task: " + tr);
6898            return;
6899        }
6900
6901        // Find any running services associated with this app.
6902        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6903
6904        if (killProcesses) {
6905            // Find any running processes associated with this app.
6906            final String pkg = component.getPackageName();
6907            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6908            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6909            for (int i=0; i<pmap.size(); i++) {
6910                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6911                for (int j=0; j<uids.size(); j++) {
6912                    ProcessRecord proc = uids.valueAt(j);
6913                    if (proc.userId != tr.userId) {
6914                        continue;
6915                    }
6916                    if (!proc.pkgList.containsKey(pkg)) {
6917                        continue;
6918                    }
6919                    procs.add(proc);
6920                }
6921            }
6922
6923            // Kill the running processes.
6924            for (int i=0; i<procs.size(); i++) {
6925                ProcessRecord pr = procs.get(i);
6926                if (pr == mHomeProcess) {
6927                    // Don't kill the home process along with tasks from the same package.
6928                    continue;
6929                }
6930                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6931                    killUnneededProcessLocked(pr, "remove task");
6932                } else {
6933                    pr.waitingToKill = "remove task";
6934                }
6935            }
6936        }
6937    }
6938
6939    @Override
6940    public boolean removeTask(int taskId, int flags) {
6941        synchronized (this) {
6942            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6943                    "removeTask()");
6944            long ident = Binder.clearCallingIdentity();
6945            try {
6946                TaskRecord tr = recentTaskForIdLocked(taskId);
6947                if (tr != null) {
6948                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6949                    if (r != null) {
6950                        cleanUpRemovedTaskLocked(tr, flags);
6951                        return true;
6952                    }
6953                    if (tr.mActivities.size() == 0) {
6954                        // Caller is just removing a recent task that is
6955                        // not actively running.  That is easy!
6956                        cleanUpRemovedTaskLocked(tr, flags);
6957                        return true;
6958                    }
6959                    Slog.w(TAG, "removeTask: task " + taskId
6960                            + " does not have activities to remove, "
6961                            + " but numActivities=" + tr.numActivities
6962                            + ": " + tr);
6963                }
6964            } finally {
6965                Binder.restoreCallingIdentity(ident);
6966            }
6967        }
6968        return false;
6969    }
6970
6971    /**
6972     * TODO: Add mController hook
6973     */
6974    @Override
6975    public void moveTaskToFront(int task, int flags, Bundle options) {
6976        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6977                "moveTaskToFront()");
6978
6979        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
6980        synchronized(this) {
6981            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6982                    Binder.getCallingUid(), "Task to front")) {
6983                ActivityOptions.abort(options);
6984                return;
6985            }
6986            final long origId = Binder.clearCallingIdentity();
6987            try {
6988                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
6989            } finally {
6990                Binder.restoreCallingIdentity(origId);
6991            }
6992            ActivityOptions.abort(options);
6993        }
6994    }
6995
6996    @Override
6997    public void moveTaskToBack(int taskId) {
6998        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6999                "moveTaskToBack()");
7000
7001        synchronized(this) {
7002            TaskRecord tr = recentTaskForIdLocked(taskId);
7003            if (tr != null) {
7004                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7005                ActivityStack stack = tr.stack;
7006                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7007                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7008                            Binder.getCallingUid(), "Task to back")) {
7009                        return;
7010                    }
7011                }
7012                final long origId = Binder.clearCallingIdentity();
7013                try {
7014                    stack.moveTaskToBackLocked(taskId, null);
7015                } finally {
7016                    Binder.restoreCallingIdentity(origId);
7017                }
7018            }
7019        }
7020    }
7021
7022    /**
7023     * Moves an activity, and all of the other activities within the same task, to the bottom
7024     * of the history stack.  The activity's order within the task is unchanged.
7025     *
7026     * @param token A reference to the activity we wish to move
7027     * @param nonRoot If false then this only works if the activity is the root
7028     *                of a task; if true it will work for any activity in a task.
7029     * @return Returns true if the move completed, false if not.
7030     */
7031    @Override
7032    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7033        enforceNotIsolatedCaller("moveActivityTaskToBack");
7034        synchronized(this) {
7035            final long origId = Binder.clearCallingIdentity();
7036            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7037            if (taskId >= 0) {
7038                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7039            }
7040            Binder.restoreCallingIdentity(origId);
7041        }
7042        return false;
7043    }
7044
7045    @Override
7046    public void moveTaskBackwards(int task) {
7047        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7048                "moveTaskBackwards()");
7049
7050        synchronized(this) {
7051            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7052                    Binder.getCallingUid(), "Task backwards")) {
7053                return;
7054            }
7055            final long origId = Binder.clearCallingIdentity();
7056            moveTaskBackwardsLocked(task);
7057            Binder.restoreCallingIdentity(origId);
7058        }
7059    }
7060
7061    private final void moveTaskBackwardsLocked(int task) {
7062        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7063    }
7064
7065    @Override
7066    public IBinder getHomeActivityToken() throws RemoteException {
7067        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7068                "getHomeActivityToken()");
7069        synchronized (this) {
7070            return mStackSupervisor.getHomeActivityToken();
7071        }
7072    }
7073
7074    @Override
7075    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7076            IActivityContainerCallback callback) throws RemoteException {
7077        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7078                "createActivityContainer()");
7079        synchronized (this) {
7080            if (parentActivityToken == null) {
7081                throw new IllegalArgumentException("parent token must not be null");
7082            }
7083            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7084            if (r == null) {
7085                return null;
7086            }
7087            if (callback == null) {
7088                throw new IllegalArgumentException("callback must not be null");
7089            }
7090            return mStackSupervisor.createActivityContainer(r, callback);
7091        }
7092    }
7093
7094    @Override
7095    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7096        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7097                "deleteActivityContainer()");
7098        synchronized (this) {
7099            mStackSupervisor.deleteActivityContainer(container);
7100        }
7101    }
7102
7103    @Override
7104    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7105            throws RemoteException {
7106        synchronized (this) {
7107            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7108            if (stack != null) {
7109                return stack.mActivityContainer;
7110            }
7111            return null;
7112        }
7113    }
7114
7115    @Override
7116    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7117        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7118                "moveTaskToStack()");
7119        if (stackId == HOME_STACK_ID) {
7120            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7121                    new RuntimeException("here").fillInStackTrace());
7122        }
7123        synchronized (this) {
7124            long ident = Binder.clearCallingIdentity();
7125            try {
7126                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7127                        + stackId + " toTop=" + toTop);
7128                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7129            } finally {
7130                Binder.restoreCallingIdentity(ident);
7131            }
7132        }
7133    }
7134
7135    @Override
7136    public void resizeStack(int stackBoxId, Rect bounds) {
7137        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7138                "resizeStackBox()");
7139        long ident = Binder.clearCallingIdentity();
7140        try {
7141            mWindowManager.resizeStack(stackBoxId, bounds);
7142        } finally {
7143            Binder.restoreCallingIdentity(ident);
7144        }
7145    }
7146
7147    @Override
7148    public List<StackInfo> getAllStackInfos() {
7149        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7150                "getAllStackInfos()");
7151        long ident = Binder.clearCallingIdentity();
7152        try {
7153            synchronized (this) {
7154                return mStackSupervisor.getAllStackInfosLocked();
7155            }
7156        } finally {
7157            Binder.restoreCallingIdentity(ident);
7158        }
7159    }
7160
7161    @Override
7162    public StackInfo getStackInfo(int stackId) {
7163        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7164                "getStackInfo()");
7165        long ident = Binder.clearCallingIdentity();
7166        try {
7167            synchronized (this) {
7168                return mStackSupervisor.getStackInfoLocked(stackId);
7169            }
7170        } finally {
7171            Binder.restoreCallingIdentity(ident);
7172        }
7173    }
7174
7175    @Override
7176    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7177        synchronized(this) {
7178            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7179        }
7180    }
7181
7182    // =========================================================
7183    // THUMBNAILS
7184    // =========================================================
7185
7186    public void reportThumbnail(IBinder token,
7187            Bitmap thumbnail, CharSequence description) {
7188        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7189        final long origId = Binder.clearCallingIdentity();
7190        sendPendingThumbnail(null, token, thumbnail, description, true);
7191        Binder.restoreCallingIdentity(origId);
7192    }
7193
7194    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7195            Bitmap thumbnail, CharSequence description, boolean always) {
7196        TaskRecord task;
7197        ArrayList<PendingThumbnailsRecord> receivers = null;
7198
7199        //System.out.println("Send pending thumbnail: " + r);
7200
7201        synchronized(this) {
7202            if (r == null) {
7203                r = ActivityRecord.isInStackLocked(token);
7204                if (r == null) {
7205                    return;
7206                }
7207            }
7208            if (thumbnail == null && r.thumbHolder != null) {
7209                thumbnail = r.thumbHolder.lastThumbnail;
7210                description = r.thumbHolder.lastDescription;
7211            }
7212            if (thumbnail == null && !always) {
7213                // If there is no thumbnail, and this entry is not actually
7214                // going away, then abort for now and pick up the next
7215                // thumbnail we get.
7216                return;
7217            }
7218            task = r.task;
7219
7220            int N = mPendingThumbnails.size();
7221            int i=0;
7222            while (i<N) {
7223                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7224                //System.out.println("Looking in " + pr.pendingRecords);
7225                if (pr.pendingRecords.remove(r)) {
7226                    if (receivers == null) {
7227                        receivers = new ArrayList<PendingThumbnailsRecord>();
7228                    }
7229                    receivers.add(pr);
7230                    if (pr.pendingRecords.size() == 0) {
7231                        pr.finished = true;
7232                        mPendingThumbnails.remove(i);
7233                        N--;
7234                        continue;
7235                    }
7236                }
7237                i++;
7238            }
7239        }
7240
7241        if (receivers != null) {
7242            final int N = receivers.size();
7243            for (int i=0; i<N; i++) {
7244                try {
7245                    PendingThumbnailsRecord pr = receivers.get(i);
7246                    pr.receiver.newThumbnail(
7247                        task != null ? task.taskId : -1, thumbnail, description);
7248                    if (pr.finished) {
7249                        pr.receiver.finished();
7250                    }
7251                } catch (Exception e) {
7252                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7253                }
7254            }
7255        }
7256    }
7257
7258    // =========================================================
7259    // CONTENT PROVIDERS
7260    // =========================================================
7261
7262    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7263        List<ProviderInfo> providers = null;
7264        try {
7265            providers = AppGlobals.getPackageManager().
7266                queryContentProviders(app.processName, app.uid,
7267                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7268        } catch (RemoteException ex) {
7269        }
7270        if (DEBUG_MU)
7271            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7272        int userId = app.userId;
7273        if (providers != null) {
7274            int N = providers.size();
7275            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7276            for (int i=0; i<N; i++) {
7277                ProviderInfo cpi =
7278                    (ProviderInfo)providers.get(i);
7279                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7280                        cpi.name, cpi.flags);
7281                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7282                    // This is a singleton provider, but a user besides the
7283                    // default user is asking to initialize a process it runs
7284                    // in...  well, no, it doesn't actually run in this process,
7285                    // it runs in the process of the default user.  Get rid of it.
7286                    providers.remove(i);
7287                    N--;
7288                    i--;
7289                    continue;
7290                }
7291
7292                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7293                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7294                if (cpr == null) {
7295                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7296                    mProviderMap.putProviderByClass(comp, cpr);
7297                }
7298                if (DEBUG_MU)
7299                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7300                app.pubProviders.put(cpi.name, cpr);
7301                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7302                    // Don't add this if it is a platform component that is marked
7303                    // to run in multiple processes, because this is actually
7304                    // part of the framework so doesn't make sense to track as a
7305                    // separate apk in the process.
7306                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7307                }
7308                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7309            }
7310        }
7311        return providers;
7312    }
7313
7314    /**
7315     * Check if {@link ProcessRecord} has a possible chance at accessing the
7316     * given {@link ProviderInfo}. Final permission checking is always done
7317     * in {@link ContentProvider}.
7318     */
7319    private final String checkContentProviderPermissionLocked(
7320            ProviderInfo cpi, ProcessRecord r) {
7321        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7322        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7323        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7324                cpi.applicationInfo.uid, cpi.exported)
7325                == PackageManager.PERMISSION_GRANTED) {
7326            return null;
7327        }
7328        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7329                cpi.applicationInfo.uid, cpi.exported)
7330                == PackageManager.PERMISSION_GRANTED) {
7331            return null;
7332        }
7333
7334        PathPermission[] pps = cpi.pathPermissions;
7335        if (pps != null) {
7336            int i = pps.length;
7337            while (i > 0) {
7338                i--;
7339                PathPermission pp = pps[i];
7340                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7341                        cpi.applicationInfo.uid, cpi.exported)
7342                        == PackageManager.PERMISSION_GRANTED) {
7343                    return null;
7344                }
7345                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7346                        cpi.applicationInfo.uid, cpi.exported)
7347                        == PackageManager.PERMISSION_GRANTED) {
7348                    return null;
7349                }
7350            }
7351        }
7352
7353        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7354        if (perms != null) {
7355            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7356                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7357                    return null;
7358                }
7359            }
7360        }
7361
7362        String msg;
7363        if (!cpi.exported) {
7364            msg = "Permission Denial: opening provider " + cpi.name
7365                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7366                    + ", uid=" + callingUid + ") that is not exported from uid "
7367                    + cpi.applicationInfo.uid;
7368        } else {
7369            msg = "Permission Denial: opening provider " + cpi.name
7370                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7371                    + ", uid=" + callingUid + ") requires "
7372                    + cpi.readPermission + " or " + cpi.writePermission;
7373        }
7374        Slog.w(TAG, msg);
7375        return msg;
7376    }
7377
7378    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7379            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7380        if (r != null) {
7381            for (int i=0; i<r.conProviders.size(); i++) {
7382                ContentProviderConnection conn = r.conProviders.get(i);
7383                if (conn.provider == cpr) {
7384                    if (DEBUG_PROVIDER) Slog.v(TAG,
7385                            "Adding provider requested by "
7386                            + r.processName + " from process "
7387                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7388                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7389                    if (stable) {
7390                        conn.stableCount++;
7391                        conn.numStableIncs++;
7392                    } else {
7393                        conn.unstableCount++;
7394                        conn.numUnstableIncs++;
7395                    }
7396                    return conn;
7397                }
7398            }
7399            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7400            if (stable) {
7401                conn.stableCount = 1;
7402                conn.numStableIncs = 1;
7403            } else {
7404                conn.unstableCount = 1;
7405                conn.numUnstableIncs = 1;
7406            }
7407            cpr.connections.add(conn);
7408            r.conProviders.add(conn);
7409            return conn;
7410        }
7411        cpr.addExternalProcessHandleLocked(externalProcessToken);
7412        return null;
7413    }
7414
7415    boolean decProviderCountLocked(ContentProviderConnection conn,
7416            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7417        if (conn != null) {
7418            cpr = conn.provider;
7419            if (DEBUG_PROVIDER) Slog.v(TAG,
7420                    "Removing provider requested by "
7421                    + conn.client.processName + " from process "
7422                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7423                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7424            if (stable) {
7425                conn.stableCount--;
7426            } else {
7427                conn.unstableCount--;
7428            }
7429            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7430                cpr.connections.remove(conn);
7431                conn.client.conProviders.remove(conn);
7432                return true;
7433            }
7434            return false;
7435        }
7436        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7437        return false;
7438    }
7439
7440    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7441            String name, IBinder token, boolean stable, int userId) {
7442        ContentProviderRecord cpr;
7443        ContentProviderConnection conn = null;
7444        ProviderInfo cpi = null;
7445
7446        synchronized(this) {
7447            ProcessRecord r = null;
7448            if (caller != null) {
7449                r = getRecordForAppLocked(caller);
7450                if (r == null) {
7451                    throw new SecurityException(
7452                            "Unable to find app for caller " + caller
7453                          + " (pid=" + Binder.getCallingPid()
7454                          + ") when getting content provider " + name);
7455                }
7456            }
7457
7458            // First check if this content provider has been published...
7459            cpr = mProviderMap.getProviderByName(name, userId);
7460            boolean providerRunning = cpr != null;
7461            if (providerRunning) {
7462                cpi = cpr.info;
7463                String msg;
7464                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7465                    throw new SecurityException(msg);
7466                }
7467
7468                if (r != null && cpr.canRunHere(r)) {
7469                    // This provider has been published or is in the process
7470                    // of being published...  but it is also allowed to run
7471                    // in the caller's process, so don't make a connection
7472                    // and just let the caller instantiate its own instance.
7473                    ContentProviderHolder holder = cpr.newHolder(null);
7474                    // don't give caller the provider object, it needs
7475                    // to make its own.
7476                    holder.provider = null;
7477                    return holder;
7478                }
7479
7480                final long origId = Binder.clearCallingIdentity();
7481
7482                // In this case the provider instance already exists, so we can
7483                // return it right away.
7484                conn = incProviderCountLocked(r, cpr, token, stable);
7485                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7486                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7487                        // If this is a perceptible app accessing the provider,
7488                        // make sure to count it as being accessed and thus
7489                        // back up on the LRU list.  This is good because
7490                        // content providers are often expensive to start.
7491                        updateLruProcessLocked(cpr.proc, false, null);
7492                    }
7493                }
7494
7495                if (cpr.proc != null) {
7496                    if (false) {
7497                        if (cpr.name.flattenToShortString().equals(
7498                                "com.android.providers.calendar/.CalendarProvider2")) {
7499                            Slog.v(TAG, "****************** KILLING "
7500                                + cpr.name.flattenToShortString());
7501                            Process.killProcess(cpr.proc.pid);
7502                        }
7503                    }
7504                    boolean success = updateOomAdjLocked(cpr.proc);
7505                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7506                    // NOTE: there is still a race here where a signal could be
7507                    // pending on the process even though we managed to update its
7508                    // adj level.  Not sure what to do about this, but at least
7509                    // the race is now smaller.
7510                    if (!success) {
7511                        // Uh oh...  it looks like the provider's process
7512                        // has been killed on us.  We need to wait for a new
7513                        // process to be started, and make sure its death
7514                        // doesn't kill our process.
7515                        Slog.i(TAG,
7516                                "Existing provider " + cpr.name.flattenToShortString()
7517                                + " is crashing; detaching " + r);
7518                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7519                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7520                        if (!lastRef) {
7521                            // This wasn't the last ref our process had on
7522                            // the provider...  we have now been killed, bail.
7523                            return null;
7524                        }
7525                        providerRunning = false;
7526                        conn = null;
7527                    }
7528                }
7529
7530                Binder.restoreCallingIdentity(origId);
7531            }
7532
7533            boolean singleton;
7534            if (!providerRunning) {
7535                try {
7536                    cpi = AppGlobals.getPackageManager().
7537                        resolveContentProvider(name,
7538                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7539                } catch (RemoteException ex) {
7540                }
7541                if (cpi == null) {
7542                    return null;
7543                }
7544                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7545                        cpi.name, cpi.flags);
7546                if (singleton) {
7547                    userId = 0;
7548                }
7549                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7550
7551                String msg;
7552                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7553                    throw new SecurityException(msg);
7554                }
7555
7556                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7557                        && !cpi.processName.equals("system")) {
7558                    // If this content provider does not run in the system
7559                    // process, and the system is not yet ready to run other
7560                    // processes, then fail fast instead of hanging.
7561                    throw new IllegalArgumentException(
7562                            "Attempt to launch content provider before system ready");
7563                }
7564
7565                // Make sure that the user who owns this provider is started.  If not,
7566                // we don't want to allow it to run.
7567                if (mStartedUsers.get(userId) == null) {
7568                    Slog.w(TAG, "Unable to launch app "
7569                            + cpi.applicationInfo.packageName + "/"
7570                            + cpi.applicationInfo.uid + " for provider "
7571                            + name + ": user " + userId + " is stopped");
7572                    return null;
7573                }
7574
7575                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7576                cpr = mProviderMap.getProviderByClass(comp, userId);
7577                final boolean firstClass = cpr == null;
7578                if (firstClass) {
7579                    try {
7580                        ApplicationInfo ai =
7581                            AppGlobals.getPackageManager().
7582                                getApplicationInfo(
7583                                        cpi.applicationInfo.packageName,
7584                                        STOCK_PM_FLAGS, userId);
7585                        if (ai == null) {
7586                            Slog.w(TAG, "No package info for content provider "
7587                                    + cpi.name);
7588                            return null;
7589                        }
7590                        ai = getAppInfoForUser(ai, userId);
7591                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7592                    } catch (RemoteException ex) {
7593                        // pm is in same process, this will never happen.
7594                    }
7595                }
7596
7597                if (r != null && cpr.canRunHere(r)) {
7598                    // If this is a multiprocess provider, then just return its
7599                    // info and allow the caller to instantiate it.  Only do
7600                    // this if the provider is the same user as the caller's
7601                    // process, or can run as root (so can be in any process).
7602                    return cpr.newHolder(null);
7603                }
7604
7605                if (DEBUG_PROVIDER) {
7606                    RuntimeException e = new RuntimeException("here");
7607                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7608                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7609                }
7610
7611                // This is single process, and our app is now connecting to it.
7612                // See if we are already in the process of launching this
7613                // provider.
7614                final int N = mLaunchingProviders.size();
7615                int i;
7616                for (i=0; i<N; i++) {
7617                    if (mLaunchingProviders.get(i) == cpr) {
7618                        break;
7619                    }
7620                }
7621
7622                // If the provider is not already being launched, then get it
7623                // started.
7624                if (i >= N) {
7625                    final long origId = Binder.clearCallingIdentity();
7626
7627                    try {
7628                        // Content provider is now in use, its package can't be stopped.
7629                        try {
7630                            AppGlobals.getPackageManager().setPackageStoppedState(
7631                                    cpr.appInfo.packageName, false, userId);
7632                        } catch (RemoteException e) {
7633                        } catch (IllegalArgumentException e) {
7634                            Slog.w(TAG, "Failed trying to unstop package "
7635                                    + cpr.appInfo.packageName + ": " + e);
7636                        }
7637
7638                        // Use existing process if already started
7639                        ProcessRecord proc = getProcessRecordLocked(
7640                                cpi.processName, cpr.appInfo.uid, false);
7641                        if (proc != null && proc.thread != null) {
7642                            if (DEBUG_PROVIDER) {
7643                                Slog.d(TAG, "Installing in existing process " + proc);
7644                            }
7645                            proc.pubProviders.put(cpi.name, cpr);
7646                            try {
7647                                proc.thread.scheduleInstallProvider(cpi);
7648                            } catch (RemoteException e) {
7649                            }
7650                        } else {
7651                            proc = startProcessLocked(cpi.processName,
7652                                    cpr.appInfo, false, 0, "content provider",
7653                                    new ComponentName(cpi.applicationInfo.packageName,
7654                                            cpi.name), false, false, false);
7655                            if (proc == null) {
7656                                Slog.w(TAG, "Unable to launch app "
7657                                        + cpi.applicationInfo.packageName + "/"
7658                                        + cpi.applicationInfo.uid + " for provider "
7659                                        + name + ": process is bad");
7660                                return null;
7661                            }
7662                        }
7663                        cpr.launchingApp = proc;
7664                        mLaunchingProviders.add(cpr);
7665                    } finally {
7666                        Binder.restoreCallingIdentity(origId);
7667                    }
7668                }
7669
7670                // Make sure the provider is published (the same provider class
7671                // may be published under multiple names).
7672                if (firstClass) {
7673                    mProviderMap.putProviderByClass(comp, cpr);
7674                }
7675
7676                mProviderMap.putProviderByName(name, cpr);
7677                conn = incProviderCountLocked(r, cpr, token, stable);
7678                if (conn != null) {
7679                    conn.waiting = true;
7680                }
7681            }
7682        }
7683
7684        // Wait for the provider to be published...
7685        synchronized (cpr) {
7686            while (cpr.provider == null) {
7687                if (cpr.launchingApp == null) {
7688                    Slog.w(TAG, "Unable to launch app "
7689                            + cpi.applicationInfo.packageName + "/"
7690                            + cpi.applicationInfo.uid + " for provider "
7691                            + name + ": launching app became null");
7692                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7693                            UserHandle.getUserId(cpi.applicationInfo.uid),
7694                            cpi.applicationInfo.packageName,
7695                            cpi.applicationInfo.uid, name);
7696                    return null;
7697                }
7698                try {
7699                    if (DEBUG_MU) {
7700                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7701                                + cpr.launchingApp);
7702                    }
7703                    if (conn != null) {
7704                        conn.waiting = true;
7705                    }
7706                    cpr.wait();
7707                } catch (InterruptedException ex) {
7708                } finally {
7709                    if (conn != null) {
7710                        conn.waiting = false;
7711                    }
7712                }
7713            }
7714        }
7715        return cpr != null ? cpr.newHolder(conn) : null;
7716    }
7717
7718    public final ContentProviderHolder getContentProvider(
7719            IApplicationThread caller, String name, int userId, boolean stable) {
7720        enforceNotIsolatedCaller("getContentProvider");
7721        if (caller == null) {
7722            String msg = "null IApplicationThread when getting content provider "
7723                    + name;
7724            Slog.w(TAG, msg);
7725            throw new SecurityException(msg);
7726        }
7727
7728        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7729                false, true, "getContentProvider", null);
7730        return getContentProviderImpl(caller, name, null, stable, userId);
7731    }
7732
7733    public ContentProviderHolder getContentProviderExternal(
7734            String name, int userId, IBinder token) {
7735        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7736            "Do not have permission in call getContentProviderExternal()");
7737        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7738                false, true, "getContentProvider", null);
7739        return getContentProviderExternalUnchecked(name, token, userId);
7740    }
7741
7742    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7743            IBinder token, int userId) {
7744        return getContentProviderImpl(null, name, token, true, userId);
7745    }
7746
7747    /**
7748     * Drop a content provider from a ProcessRecord's bookkeeping
7749     */
7750    public void removeContentProvider(IBinder connection, boolean stable) {
7751        enforceNotIsolatedCaller("removeContentProvider");
7752        synchronized (this) {
7753            ContentProviderConnection conn;
7754            try {
7755                conn = (ContentProviderConnection)connection;
7756            } catch (ClassCastException e) {
7757                String msg ="removeContentProvider: " + connection
7758                        + " not a ContentProviderConnection";
7759                Slog.w(TAG, msg);
7760                throw new IllegalArgumentException(msg);
7761            }
7762            if (conn == null) {
7763                throw new NullPointerException("connection is null");
7764            }
7765            if (decProviderCountLocked(conn, null, null, stable)) {
7766                updateOomAdjLocked();
7767            }
7768        }
7769    }
7770
7771    public void removeContentProviderExternal(String name, IBinder token) {
7772        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7773            "Do not have permission in call removeContentProviderExternal()");
7774        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7775    }
7776
7777    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7778        synchronized (this) {
7779            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7780            if(cpr == null) {
7781                //remove from mProvidersByClass
7782                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7783                return;
7784            }
7785
7786            //update content provider record entry info
7787            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7788            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7789            if (localCpr.hasExternalProcessHandles()) {
7790                if (localCpr.removeExternalProcessHandleLocked(token)) {
7791                    updateOomAdjLocked();
7792                } else {
7793                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7794                            + " with no external reference for token: "
7795                            + token + ".");
7796                }
7797            } else {
7798                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7799                        + " with no external references.");
7800            }
7801        }
7802    }
7803
7804    public final void publishContentProviders(IApplicationThread caller,
7805            List<ContentProviderHolder> providers) {
7806        if (providers == null) {
7807            return;
7808        }
7809
7810        enforceNotIsolatedCaller("publishContentProviders");
7811        synchronized (this) {
7812            final ProcessRecord r = getRecordForAppLocked(caller);
7813            if (DEBUG_MU)
7814                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7815            if (r == null) {
7816                throw new SecurityException(
7817                        "Unable to find app for caller " + caller
7818                      + " (pid=" + Binder.getCallingPid()
7819                      + ") when publishing content providers");
7820            }
7821
7822            final long origId = Binder.clearCallingIdentity();
7823
7824            final int N = providers.size();
7825            for (int i=0; i<N; i++) {
7826                ContentProviderHolder src = providers.get(i);
7827                if (src == null || src.info == null || src.provider == null) {
7828                    continue;
7829                }
7830                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7831                if (DEBUG_MU)
7832                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7833                if (dst != null) {
7834                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7835                    mProviderMap.putProviderByClass(comp, dst);
7836                    String names[] = dst.info.authority.split(";");
7837                    for (int j = 0; j < names.length; j++) {
7838                        mProviderMap.putProviderByName(names[j], dst);
7839                    }
7840
7841                    int NL = mLaunchingProviders.size();
7842                    int j;
7843                    for (j=0; j<NL; j++) {
7844                        if (mLaunchingProviders.get(j) == dst) {
7845                            mLaunchingProviders.remove(j);
7846                            j--;
7847                            NL--;
7848                        }
7849                    }
7850                    synchronized (dst) {
7851                        dst.provider = src.provider;
7852                        dst.proc = r;
7853                        dst.notifyAll();
7854                    }
7855                    updateOomAdjLocked(r);
7856                }
7857            }
7858
7859            Binder.restoreCallingIdentity(origId);
7860        }
7861    }
7862
7863    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7864        ContentProviderConnection conn;
7865        try {
7866            conn = (ContentProviderConnection)connection;
7867        } catch (ClassCastException e) {
7868            String msg ="refContentProvider: " + connection
7869                    + " not a ContentProviderConnection";
7870            Slog.w(TAG, msg);
7871            throw new IllegalArgumentException(msg);
7872        }
7873        if (conn == null) {
7874            throw new NullPointerException("connection is null");
7875        }
7876
7877        synchronized (this) {
7878            if (stable > 0) {
7879                conn.numStableIncs += stable;
7880            }
7881            stable = conn.stableCount + stable;
7882            if (stable < 0) {
7883                throw new IllegalStateException("stableCount < 0: " + stable);
7884            }
7885
7886            if (unstable > 0) {
7887                conn.numUnstableIncs += unstable;
7888            }
7889            unstable = conn.unstableCount + unstable;
7890            if (unstable < 0) {
7891                throw new IllegalStateException("unstableCount < 0: " + unstable);
7892            }
7893
7894            if ((stable+unstable) <= 0) {
7895                throw new IllegalStateException("ref counts can't go to zero here: stable="
7896                        + stable + " unstable=" + unstable);
7897            }
7898            conn.stableCount = stable;
7899            conn.unstableCount = unstable;
7900            return !conn.dead;
7901        }
7902    }
7903
7904    public void unstableProviderDied(IBinder connection) {
7905        ContentProviderConnection conn;
7906        try {
7907            conn = (ContentProviderConnection)connection;
7908        } catch (ClassCastException e) {
7909            String msg ="refContentProvider: " + connection
7910                    + " not a ContentProviderConnection";
7911            Slog.w(TAG, msg);
7912            throw new IllegalArgumentException(msg);
7913        }
7914        if (conn == null) {
7915            throw new NullPointerException("connection is null");
7916        }
7917
7918        // Safely retrieve the content provider associated with the connection.
7919        IContentProvider provider;
7920        synchronized (this) {
7921            provider = conn.provider.provider;
7922        }
7923
7924        if (provider == null) {
7925            // Um, yeah, we're way ahead of you.
7926            return;
7927        }
7928
7929        // Make sure the caller is being honest with us.
7930        if (provider.asBinder().pingBinder()) {
7931            // Er, no, still looks good to us.
7932            synchronized (this) {
7933                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7934                        + " says " + conn + " died, but we don't agree");
7935                return;
7936            }
7937        }
7938
7939        // Well look at that!  It's dead!
7940        synchronized (this) {
7941            if (conn.provider.provider != provider) {
7942                // But something changed...  good enough.
7943                return;
7944            }
7945
7946            ProcessRecord proc = conn.provider.proc;
7947            if (proc == null || proc.thread == null) {
7948                // Seems like the process is already cleaned up.
7949                return;
7950            }
7951
7952            // As far as we're concerned, this is just like receiving a
7953            // death notification...  just a bit prematurely.
7954            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7955                    + ") early provider death");
7956            final long ident = Binder.clearCallingIdentity();
7957            try {
7958                appDiedLocked(proc, proc.pid, proc.thread);
7959            } finally {
7960                Binder.restoreCallingIdentity(ident);
7961            }
7962        }
7963    }
7964
7965    @Override
7966    public void appNotRespondingViaProvider(IBinder connection) {
7967        enforceCallingPermission(
7968                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7969
7970        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7971        if (conn == null) {
7972            Slog.w(TAG, "ContentProviderConnection is null");
7973            return;
7974        }
7975
7976        final ProcessRecord host = conn.provider.proc;
7977        if (host == null) {
7978            Slog.w(TAG, "Failed to find hosting ProcessRecord");
7979            return;
7980        }
7981
7982        final long token = Binder.clearCallingIdentity();
7983        try {
7984            appNotResponding(host, null, null, false, "ContentProvider not responding");
7985        } finally {
7986            Binder.restoreCallingIdentity(token);
7987        }
7988    }
7989
7990    public final void installSystemProviders() {
7991        List<ProviderInfo> providers;
7992        synchronized (this) {
7993            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
7994            providers = generateApplicationProvidersLocked(app);
7995            if (providers != null) {
7996                for (int i=providers.size()-1; i>=0; i--) {
7997                    ProviderInfo pi = (ProviderInfo)providers.get(i);
7998                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7999                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8000                                + ": not system .apk");
8001                        providers.remove(i);
8002                    }
8003                }
8004            }
8005        }
8006        if (providers != null) {
8007            mSystemThread.installSystemProviders(providers);
8008        }
8009
8010        mCoreSettingsObserver = new CoreSettingsObserver(this);
8011
8012        mUsageStatsService.monitorPackages();
8013    }
8014
8015    /**
8016     * Allows app to retrieve the MIME type of a URI without having permission
8017     * to access its content provider.
8018     *
8019     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8020     *
8021     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8022     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8023     */
8024    public String getProviderMimeType(Uri uri, int userId) {
8025        enforceNotIsolatedCaller("getProviderMimeType");
8026        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8027                userId, false, true, "getProviderMimeType", null);
8028        final String name = uri.getAuthority();
8029        final long ident = Binder.clearCallingIdentity();
8030        ContentProviderHolder holder = null;
8031
8032        try {
8033            holder = getContentProviderExternalUnchecked(name, null, userId);
8034            if (holder != null) {
8035                return holder.provider.getType(uri);
8036            }
8037        } catch (RemoteException e) {
8038            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8039            return null;
8040        } finally {
8041            if (holder != null) {
8042                removeContentProviderExternalUnchecked(name, null, userId);
8043            }
8044            Binder.restoreCallingIdentity(ident);
8045        }
8046
8047        return null;
8048    }
8049
8050    // =========================================================
8051    // GLOBAL MANAGEMENT
8052    // =========================================================
8053
8054    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8055            boolean isolated) {
8056        String proc = customProcess != null ? customProcess : info.processName;
8057        BatteryStatsImpl.Uid.Proc ps = null;
8058        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8059        int uid = info.uid;
8060        if (isolated) {
8061            int userId = UserHandle.getUserId(uid);
8062            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8063            while (true) {
8064                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8065                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8066                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8067                }
8068                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8069                mNextIsolatedProcessUid++;
8070                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8071                    // No process for this uid, use it.
8072                    break;
8073                }
8074                stepsLeft--;
8075                if (stepsLeft <= 0) {
8076                    return null;
8077                }
8078            }
8079        }
8080        return new ProcessRecord(stats, info, proc, uid);
8081    }
8082
8083    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8084        ProcessRecord app;
8085        if (!isolated) {
8086            app = getProcessRecordLocked(info.processName, info.uid, true);
8087        } else {
8088            app = null;
8089        }
8090
8091        if (app == null) {
8092            app = newProcessRecordLocked(info, null, isolated);
8093            mProcessNames.put(info.processName, app.uid, app);
8094            if (isolated) {
8095                mIsolatedProcesses.put(app.uid, app);
8096            }
8097            updateLruProcessLocked(app, false, null);
8098            updateOomAdjLocked();
8099        }
8100
8101        // This package really, really can not be stopped.
8102        try {
8103            AppGlobals.getPackageManager().setPackageStoppedState(
8104                    info.packageName, false, UserHandle.getUserId(app.uid));
8105        } catch (RemoteException e) {
8106        } catch (IllegalArgumentException e) {
8107            Slog.w(TAG, "Failed trying to unstop package "
8108                    + info.packageName + ": " + e);
8109        }
8110
8111        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8112                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8113            app.persistent = true;
8114            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8115        }
8116        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8117            mPersistentStartingProcesses.add(app);
8118            startProcessLocked(app, "added application", app.processName);
8119        }
8120
8121        return app;
8122    }
8123
8124    public void unhandledBack() {
8125        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8126                "unhandledBack()");
8127
8128        synchronized(this) {
8129            final long origId = Binder.clearCallingIdentity();
8130            try {
8131                getFocusedStack().unhandledBackLocked();
8132            } finally {
8133                Binder.restoreCallingIdentity(origId);
8134            }
8135        }
8136    }
8137
8138    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8139        enforceNotIsolatedCaller("openContentUri");
8140        final int userId = UserHandle.getCallingUserId();
8141        String name = uri.getAuthority();
8142        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8143        ParcelFileDescriptor pfd = null;
8144        if (cph != null) {
8145            // We record the binder invoker's uid in thread-local storage before
8146            // going to the content provider to open the file.  Later, in the code
8147            // that handles all permissions checks, we look for this uid and use
8148            // that rather than the Activity Manager's own uid.  The effect is that
8149            // we do the check against the caller's permissions even though it looks
8150            // to the content provider like the Activity Manager itself is making
8151            // the request.
8152            sCallerIdentity.set(new Identity(
8153                    Binder.getCallingPid(), Binder.getCallingUid()));
8154            try {
8155                pfd = cph.provider.openFile(null, uri, "r", null);
8156            } catch (FileNotFoundException e) {
8157                // do nothing; pfd will be returned null
8158            } finally {
8159                // Ensure that whatever happens, we clean up the identity state
8160                sCallerIdentity.remove();
8161            }
8162
8163            // We've got the fd now, so we're done with the provider.
8164            removeContentProviderExternalUnchecked(name, null, userId);
8165        } else {
8166            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8167        }
8168        return pfd;
8169    }
8170
8171    // Actually is sleeping or shutting down or whatever else in the future
8172    // is an inactive state.
8173    public boolean isSleepingOrShuttingDown() {
8174        return mSleeping || mShuttingDown;
8175    }
8176
8177    void goingToSleep() {
8178        synchronized(this) {
8179            mWentToSleep = true;
8180            updateEventDispatchingLocked();
8181
8182            if (!mSleeping) {
8183                mSleeping = true;
8184                mStackSupervisor.goingToSleepLocked();
8185
8186                // Initialize the wake times of all processes.
8187                checkExcessivePowerUsageLocked(false);
8188                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8189                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8190                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8191            }
8192        }
8193    }
8194
8195    @Override
8196    public boolean shutdown(int timeout) {
8197        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8198                != PackageManager.PERMISSION_GRANTED) {
8199            throw new SecurityException("Requires permission "
8200                    + android.Manifest.permission.SHUTDOWN);
8201        }
8202
8203        boolean timedout = false;
8204
8205        synchronized(this) {
8206            mShuttingDown = true;
8207            updateEventDispatchingLocked();
8208            timedout = mStackSupervisor.shutdownLocked(timeout);
8209        }
8210
8211        mAppOpsService.shutdown();
8212        mUsageStatsService.shutdown();
8213        mBatteryStatsService.shutdown();
8214        synchronized (this) {
8215            mProcessStats.shutdownLocked();
8216        }
8217
8218        return timedout;
8219    }
8220
8221    public final void activitySlept(IBinder token) {
8222        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8223
8224        final long origId = Binder.clearCallingIdentity();
8225
8226        synchronized (this) {
8227            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8228            if (r != null) {
8229                mStackSupervisor.activitySleptLocked(r);
8230            }
8231        }
8232
8233        Binder.restoreCallingIdentity(origId);
8234    }
8235
8236    void logLockScreen(String msg) {
8237        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8238                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8239                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8240                mStackSupervisor.mDismissKeyguardOnNextActivity);
8241    }
8242
8243    private void comeOutOfSleepIfNeededLocked() {
8244        if (!mWentToSleep && !mLockScreenShown) {
8245            if (mSleeping) {
8246                mSleeping = false;
8247                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8248            }
8249        }
8250    }
8251
8252    void wakingUp() {
8253        synchronized(this) {
8254            mWentToSleep = false;
8255            updateEventDispatchingLocked();
8256            comeOutOfSleepIfNeededLocked();
8257        }
8258    }
8259
8260    private void updateEventDispatchingLocked() {
8261        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8262    }
8263
8264    public void setLockScreenShown(boolean shown) {
8265        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8266                != PackageManager.PERMISSION_GRANTED) {
8267            throw new SecurityException("Requires permission "
8268                    + android.Manifest.permission.DEVICE_POWER);
8269        }
8270
8271        synchronized(this) {
8272            long ident = Binder.clearCallingIdentity();
8273            try {
8274                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8275                mLockScreenShown = shown;
8276                comeOutOfSleepIfNeededLocked();
8277            } finally {
8278                Binder.restoreCallingIdentity(ident);
8279            }
8280        }
8281    }
8282
8283    public void stopAppSwitches() {
8284        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8285                != PackageManager.PERMISSION_GRANTED) {
8286            throw new SecurityException("Requires permission "
8287                    + android.Manifest.permission.STOP_APP_SWITCHES);
8288        }
8289
8290        synchronized(this) {
8291            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8292                    + APP_SWITCH_DELAY_TIME;
8293            mDidAppSwitch = false;
8294            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8295            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8296            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8297        }
8298    }
8299
8300    public void resumeAppSwitches() {
8301        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8302                != PackageManager.PERMISSION_GRANTED) {
8303            throw new SecurityException("Requires permission "
8304                    + android.Manifest.permission.STOP_APP_SWITCHES);
8305        }
8306
8307        synchronized(this) {
8308            // Note that we don't execute any pending app switches... we will
8309            // let those wait until either the timeout, or the next start
8310            // activity request.
8311            mAppSwitchesAllowedTime = 0;
8312        }
8313    }
8314
8315    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8316            String name) {
8317        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8318            return true;
8319        }
8320
8321        final int perm = checkComponentPermission(
8322                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8323                callingUid, -1, true);
8324        if (perm == PackageManager.PERMISSION_GRANTED) {
8325            return true;
8326        }
8327
8328        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8329        return false;
8330    }
8331
8332    public void setDebugApp(String packageName, boolean waitForDebugger,
8333            boolean persistent) {
8334        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8335                "setDebugApp()");
8336
8337        long ident = Binder.clearCallingIdentity();
8338        try {
8339            // Note that this is not really thread safe if there are multiple
8340            // callers into it at the same time, but that's not a situation we
8341            // care about.
8342            if (persistent) {
8343                final ContentResolver resolver = mContext.getContentResolver();
8344                Settings.Global.putString(
8345                    resolver, Settings.Global.DEBUG_APP,
8346                    packageName);
8347                Settings.Global.putInt(
8348                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8349                    waitForDebugger ? 1 : 0);
8350            }
8351
8352            synchronized (this) {
8353                if (!persistent) {
8354                    mOrigDebugApp = mDebugApp;
8355                    mOrigWaitForDebugger = mWaitForDebugger;
8356                }
8357                mDebugApp = packageName;
8358                mWaitForDebugger = waitForDebugger;
8359                mDebugTransient = !persistent;
8360                if (packageName != null) {
8361                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8362                            UserHandle.USER_ALL, "set debug app");
8363                }
8364            }
8365        } finally {
8366            Binder.restoreCallingIdentity(ident);
8367        }
8368    }
8369
8370    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8371        synchronized (this) {
8372            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8373            if (!isDebuggable) {
8374                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8375                    throw new SecurityException("Process not debuggable: " + app.packageName);
8376                }
8377            }
8378
8379            mOpenGlTraceApp = processName;
8380        }
8381    }
8382
8383    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8384            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8385        synchronized (this) {
8386            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8387            if (!isDebuggable) {
8388                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8389                    throw new SecurityException("Process not debuggable: " + app.packageName);
8390                }
8391            }
8392            mProfileApp = processName;
8393            mProfileFile = profileFile;
8394            if (mProfileFd != null) {
8395                try {
8396                    mProfileFd.close();
8397                } catch (IOException e) {
8398                }
8399                mProfileFd = null;
8400            }
8401            mProfileFd = profileFd;
8402            mProfileType = 0;
8403            mAutoStopProfiler = autoStopProfiler;
8404        }
8405    }
8406
8407    @Override
8408    public void setAlwaysFinish(boolean enabled) {
8409        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8410                "setAlwaysFinish()");
8411
8412        Settings.Global.putInt(
8413                mContext.getContentResolver(),
8414                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8415
8416        synchronized (this) {
8417            mAlwaysFinishActivities = enabled;
8418        }
8419    }
8420
8421    @Override
8422    public void setActivityController(IActivityController controller) {
8423        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8424                "setActivityController()");
8425        synchronized (this) {
8426            mController = controller;
8427            Watchdog.getInstance().setActivityController(controller);
8428        }
8429    }
8430
8431    @Override
8432    public void setUserIsMonkey(boolean userIsMonkey) {
8433        synchronized (this) {
8434            synchronized (mPidsSelfLocked) {
8435                final int callingPid = Binder.getCallingPid();
8436                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8437                if (precessRecord == null) {
8438                    throw new SecurityException("Unknown process: " + callingPid);
8439                }
8440                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8441                    throw new SecurityException("Only an instrumentation process "
8442                            + "with a UiAutomation can call setUserIsMonkey");
8443                }
8444            }
8445            mUserIsMonkey = userIsMonkey;
8446        }
8447    }
8448
8449    @Override
8450    public boolean isUserAMonkey() {
8451        synchronized (this) {
8452            // If there is a controller also implies the user is a monkey.
8453            return (mUserIsMonkey || mController != null);
8454        }
8455    }
8456
8457    public void requestBugReport() {
8458        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8459        SystemProperties.set("ctl.start", "bugreport");
8460    }
8461
8462    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8463        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8464    }
8465
8466    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8467        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8468            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8469        }
8470        return KEY_DISPATCHING_TIMEOUT;
8471    }
8472
8473    @Override
8474    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8475        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8476                != PackageManager.PERMISSION_GRANTED) {
8477            throw new SecurityException("Requires permission "
8478                    + android.Manifest.permission.FILTER_EVENTS);
8479        }
8480        ProcessRecord proc;
8481        long timeout;
8482        synchronized (this) {
8483            synchronized (mPidsSelfLocked) {
8484                proc = mPidsSelfLocked.get(pid);
8485            }
8486            timeout = getInputDispatchingTimeoutLocked(proc);
8487        }
8488
8489        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8490            return -1;
8491        }
8492
8493        return timeout;
8494    }
8495
8496    /**
8497     * Handle input dispatching timeouts.
8498     * Returns whether input dispatching should be aborted or not.
8499     */
8500    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8501            final ActivityRecord activity, final ActivityRecord parent,
8502            final boolean aboveSystem, String reason) {
8503        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8504                != PackageManager.PERMISSION_GRANTED) {
8505            throw new SecurityException("Requires permission "
8506                    + android.Manifest.permission.FILTER_EVENTS);
8507        }
8508
8509        final String annotation;
8510        if (reason == null) {
8511            annotation = "Input dispatching timed out";
8512        } else {
8513            annotation = "Input dispatching timed out (" + reason + ")";
8514        }
8515
8516        if (proc != null) {
8517            synchronized (this) {
8518                if (proc.debugging) {
8519                    return false;
8520                }
8521
8522                if (mDidDexOpt) {
8523                    // Give more time since we were dexopting.
8524                    mDidDexOpt = false;
8525                    return false;
8526                }
8527
8528                if (proc.instrumentationClass != null) {
8529                    Bundle info = new Bundle();
8530                    info.putString("shortMsg", "keyDispatchingTimedOut");
8531                    info.putString("longMsg", annotation);
8532                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8533                    return true;
8534                }
8535            }
8536            mHandler.post(new Runnable() {
8537                @Override
8538                public void run() {
8539                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8540                }
8541            });
8542        }
8543
8544        return true;
8545    }
8546
8547    public Bundle getAssistContextExtras(int requestType) {
8548        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8549                "getAssistContextExtras()");
8550        PendingAssistExtras pae;
8551        Bundle extras = new Bundle();
8552        synchronized (this) {
8553            ActivityRecord activity = getFocusedStack().mResumedActivity;
8554            if (activity == null) {
8555                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8556                return null;
8557            }
8558            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8559            if (activity.app == null || activity.app.thread == null) {
8560                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8561                return extras;
8562            }
8563            if (activity.app.pid == Binder.getCallingPid()) {
8564                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8565                return extras;
8566            }
8567            pae = new PendingAssistExtras(activity);
8568            try {
8569                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8570                        requestType);
8571                mPendingAssistExtras.add(pae);
8572                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8573            } catch (RemoteException e) {
8574                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8575                return extras;
8576            }
8577        }
8578        synchronized (pae) {
8579            while (!pae.haveResult) {
8580                try {
8581                    pae.wait();
8582                } catch (InterruptedException e) {
8583                }
8584            }
8585            if (pae.result != null) {
8586                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8587            }
8588        }
8589        synchronized (this) {
8590            mPendingAssistExtras.remove(pae);
8591            mHandler.removeCallbacks(pae);
8592        }
8593        return extras;
8594    }
8595
8596    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8597        PendingAssistExtras pae = (PendingAssistExtras)token;
8598        synchronized (pae) {
8599            pae.result = extras;
8600            pae.haveResult = true;
8601            pae.notifyAll();
8602        }
8603    }
8604
8605    public void registerProcessObserver(IProcessObserver observer) {
8606        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8607                "registerProcessObserver()");
8608        synchronized (this) {
8609            mProcessObservers.register(observer);
8610        }
8611    }
8612
8613    @Override
8614    public void unregisterProcessObserver(IProcessObserver observer) {
8615        synchronized (this) {
8616            mProcessObservers.unregister(observer);
8617        }
8618    }
8619
8620    @Override
8621    public boolean convertFromTranslucent(IBinder token) {
8622        final long origId = Binder.clearCallingIdentity();
8623        try {
8624            synchronized (this) {
8625                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8626                if (r == null) {
8627                    return false;
8628                }
8629                if (r.changeWindowTranslucency(true)) {
8630                    mWindowManager.setAppFullscreen(token, true);
8631                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8632                    return true;
8633                }
8634                return false;
8635            }
8636        } finally {
8637            Binder.restoreCallingIdentity(origId);
8638        }
8639    }
8640
8641    @Override
8642    public boolean convertToTranslucent(IBinder token) {
8643        final long origId = Binder.clearCallingIdentity();
8644        try {
8645            synchronized (this) {
8646                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8647                if (r == null) {
8648                    return false;
8649                }
8650                if (r.changeWindowTranslucency(false)) {
8651                    r.task.stack.convertToTranslucent(r);
8652                    mWindowManager.setAppFullscreen(token, false);
8653                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8654                    return true;
8655                }
8656                return false;
8657            }
8658        } finally {
8659            Binder.restoreCallingIdentity(origId);
8660        }
8661    }
8662
8663    @Override
8664    public void setImmersive(IBinder token, boolean immersive) {
8665        synchronized(this) {
8666            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8667            if (r == null) {
8668                throw new IllegalArgumentException();
8669            }
8670            r.immersive = immersive;
8671
8672            // update associated state if we're frontmost
8673            if (r == mFocusedActivity) {
8674                if (DEBUG_IMMERSIVE) {
8675                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8676                }
8677                applyUpdateLockStateLocked(r);
8678            }
8679        }
8680    }
8681
8682    @Override
8683    public boolean isImmersive(IBinder token) {
8684        synchronized (this) {
8685            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8686            if (r == null) {
8687                throw new IllegalArgumentException();
8688            }
8689            return r.immersive;
8690        }
8691    }
8692
8693    public boolean isTopActivityImmersive() {
8694        enforceNotIsolatedCaller("startActivity");
8695        synchronized (this) {
8696            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8697            return (r != null) ? r.immersive : false;
8698        }
8699    }
8700
8701    public final void enterSafeMode() {
8702        synchronized(this) {
8703            // It only makes sense to do this before the system is ready
8704            // and started launching other packages.
8705            if (!mSystemReady) {
8706                try {
8707                    AppGlobals.getPackageManager().enterSafeMode();
8708                } catch (RemoteException e) {
8709                }
8710            }
8711        }
8712    }
8713
8714    public final void showSafeModeOverlay() {
8715        View v = LayoutInflater.from(mContext).inflate(
8716                com.android.internal.R.layout.safe_mode, null);
8717        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8718        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8719        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8720        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8721        lp.gravity = Gravity.BOTTOM | Gravity.START;
8722        lp.format = v.getBackground().getOpacity();
8723        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8724                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8725        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8726        ((WindowManager)mContext.getSystemService(
8727                Context.WINDOW_SERVICE)).addView(v, lp);
8728    }
8729
8730    public void noteWakeupAlarm(IIntentSender sender) {
8731        if (!(sender instanceof PendingIntentRecord)) {
8732            return;
8733        }
8734        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8735        synchronized (stats) {
8736            if (mBatteryStatsService.isOnBattery()) {
8737                mBatteryStatsService.enforceCallingPermission();
8738                PendingIntentRecord rec = (PendingIntentRecord)sender;
8739                int MY_UID = Binder.getCallingUid();
8740                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8741                BatteryStatsImpl.Uid.Pkg pkg =
8742                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8743                pkg.incWakeupsLocked();
8744            }
8745        }
8746    }
8747
8748    public boolean killPids(int[] pids, String pReason, boolean secure) {
8749        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8750            throw new SecurityException("killPids only available to the system");
8751        }
8752        String reason = (pReason == null) ? "Unknown" : pReason;
8753        // XXX Note: don't acquire main activity lock here, because the window
8754        // manager calls in with its locks held.
8755
8756        boolean killed = false;
8757        synchronized (mPidsSelfLocked) {
8758            int[] types = new int[pids.length];
8759            int worstType = 0;
8760            for (int i=0; i<pids.length; i++) {
8761                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8762                if (proc != null) {
8763                    int type = proc.setAdj;
8764                    types[i] = type;
8765                    if (type > worstType) {
8766                        worstType = type;
8767                    }
8768                }
8769            }
8770
8771            // If the worst oom_adj is somewhere in the cached proc LRU range,
8772            // then constrain it so we will kill all cached procs.
8773            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8774                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8775                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8776            }
8777
8778            // If this is not a secure call, don't let it kill processes that
8779            // are important.
8780            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8781                worstType = ProcessList.SERVICE_ADJ;
8782            }
8783
8784            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8785            for (int i=0; i<pids.length; i++) {
8786                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8787                if (proc == null) {
8788                    continue;
8789                }
8790                int adj = proc.setAdj;
8791                if (adj >= worstType && !proc.killedByAm) {
8792                    killUnneededProcessLocked(proc, reason);
8793                    killed = true;
8794                }
8795            }
8796        }
8797        return killed;
8798    }
8799
8800    @Override
8801    public void killUid(int uid, String reason) {
8802        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8803            throw new SecurityException("killUid only available to the system");
8804        }
8805        synchronized (this) {
8806            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8807                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8808                    reason != null ? reason : "kill uid");
8809        }
8810    }
8811
8812    @Override
8813    public boolean killProcessesBelowForeground(String reason) {
8814        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8815            throw new SecurityException("killProcessesBelowForeground() only available to system");
8816        }
8817
8818        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8819    }
8820
8821    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8822        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8823            throw new SecurityException("killProcessesBelowAdj() only available to system");
8824        }
8825
8826        boolean killed = false;
8827        synchronized (mPidsSelfLocked) {
8828            final int size = mPidsSelfLocked.size();
8829            for (int i = 0; i < size; i++) {
8830                final int pid = mPidsSelfLocked.keyAt(i);
8831                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8832                if (proc == null) continue;
8833
8834                final int adj = proc.setAdj;
8835                if (adj > belowAdj && !proc.killedByAm) {
8836                    killUnneededProcessLocked(proc, reason);
8837                    killed = true;
8838                }
8839            }
8840        }
8841        return killed;
8842    }
8843
8844    @Override
8845    public void hang(final IBinder who, boolean allowRestart) {
8846        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8847                != PackageManager.PERMISSION_GRANTED) {
8848            throw new SecurityException("Requires permission "
8849                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8850        }
8851
8852        final IBinder.DeathRecipient death = new DeathRecipient() {
8853            @Override
8854            public void binderDied() {
8855                synchronized (this) {
8856                    notifyAll();
8857                }
8858            }
8859        };
8860
8861        try {
8862            who.linkToDeath(death, 0);
8863        } catch (RemoteException e) {
8864            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8865            return;
8866        }
8867
8868        synchronized (this) {
8869            Watchdog.getInstance().setAllowRestart(allowRestart);
8870            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8871            synchronized (death) {
8872                while (who.isBinderAlive()) {
8873                    try {
8874                        death.wait();
8875                    } catch (InterruptedException e) {
8876                    }
8877                }
8878            }
8879            Watchdog.getInstance().setAllowRestart(true);
8880        }
8881    }
8882
8883    @Override
8884    public void restart() {
8885        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8886                != PackageManager.PERMISSION_GRANTED) {
8887            throw new SecurityException("Requires permission "
8888                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8889        }
8890
8891        Log.i(TAG, "Sending shutdown broadcast...");
8892
8893        BroadcastReceiver br = new BroadcastReceiver() {
8894            @Override public void onReceive(Context context, Intent intent) {
8895                // Now the broadcast is done, finish up the low-level shutdown.
8896                Log.i(TAG, "Shutting down activity manager...");
8897                shutdown(10000);
8898                Log.i(TAG, "Shutdown complete, restarting!");
8899                Process.killProcess(Process.myPid());
8900                System.exit(10);
8901            }
8902        };
8903
8904        // First send the high-level shut down broadcast.
8905        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8906        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8907        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8908        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8909        mContext.sendOrderedBroadcastAsUser(intent,
8910                UserHandle.ALL, null, br, mHandler, 0, null, null);
8911        */
8912        br.onReceive(mContext, intent);
8913    }
8914
8915    private long getLowRamTimeSinceIdle(long now) {
8916        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8917    }
8918
8919    @Override
8920    public void performIdleMaintenance() {
8921        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8922                != PackageManager.PERMISSION_GRANTED) {
8923            throw new SecurityException("Requires permission "
8924                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8925        }
8926
8927        synchronized (this) {
8928            final long now = SystemClock.uptimeMillis();
8929            final long timeSinceLastIdle = now - mLastIdleTime;
8930            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8931            mLastIdleTime = now;
8932            mLowRamTimeSinceLastIdle = 0;
8933            if (mLowRamStartTime != 0) {
8934                mLowRamStartTime = now;
8935            }
8936
8937            StringBuilder sb = new StringBuilder(128);
8938            sb.append("Idle maintenance over ");
8939            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8940            sb.append(" low RAM for ");
8941            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8942            Slog.i(TAG, sb.toString());
8943
8944            // If at least 1/3 of our time since the last idle period has been spent
8945            // with RAM low, then we want to kill processes.
8946            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8947
8948            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8949                ProcessRecord proc = mLruProcesses.get(i);
8950                if (proc.notCachedSinceIdle) {
8951                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8952                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8953                        if (doKilling && proc.initialIdlePss != 0
8954                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8955                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8956                                    + " from " + proc.initialIdlePss + ")");
8957                        }
8958                    }
8959                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8960                    proc.notCachedSinceIdle = true;
8961                    proc.initialIdlePss = 0;
8962                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8963                            mSleeping, now);
8964                }
8965            }
8966
8967            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8968            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8969        }
8970    }
8971
8972    private void retrieveSettings() {
8973        final ContentResolver resolver = mContext.getContentResolver();
8974        String debugApp = Settings.Global.getString(
8975            resolver, Settings.Global.DEBUG_APP);
8976        boolean waitForDebugger = Settings.Global.getInt(
8977            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
8978        boolean alwaysFinishActivities = Settings.Global.getInt(
8979            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
8980        boolean forceRtl = Settings.Global.getInt(
8981                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
8982        // Transfer any global setting for forcing RTL layout, into a System Property
8983        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
8984
8985        Configuration configuration = new Configuration();
8986        Settings.System.getConfiguration(resolver, configuration);
8987        if (forceRtl) {
8988            // This will take care of setting the correct layout direction flags
8989            configuration.setLayoutDirection(configuration.locale);
8990        }
8991
8992        synchronized (this) {
8993            mDebugApp = mOrigDebugApp = debugApp;
8994            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
8995            mAlwaysFinishActivities = alwaysFinishActivities;
8996            // This happens before any activities are started, so we can
8997            // change mConfiguration in-place.
8998            updateConfigurationLocked(configuration, null, false, true);
8999            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9000        }
9001    }
9002
9003    public boolean testIsSystemReady() {
9004        // no need to synchronize(this) just to read & return the value
9005        return mSystemReady;
9006    }
9007
9008    private static File getCalledPreBootReceiversFile() {
9009        File dataDir = Environment.getDataDirectory();
9010        File systemDir = new File(dataDir, "system");
9011        File fname = new File(systemDir, "called_pre_boots.dat");
9012        return fname;
9013    }
9014
9015    static final int LAST_DONE_VERSION = 10000;
9016
9017    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9018        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9019        File file = getCalledPreBootReceiversFile();
9020        FileInputStream fis = null;
9021        try {
9022            fis = new FileInputStream(file);
9023            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9024            int fvers = dis.readInt();
9025            if (fvers == LAST_DONE_VERSION) {
9026                String vers = dis.readUTF();
9027                String codename = dis.readUTF();
9028                String build = dis.readUTF();
9029                if (android.os.Build.VERSION.RELEASE.equals(vers)
9030                        && android.os.Build.VERSION.CODENAME.equals(codename)
9031                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9032                    int num = dis.readInt();
9033                    while (num > 0) {
9034                        num--;
9035                        String pkg = dis.readUTF();
9036                        String cls = dis.readUTF();
9037                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9038                    }
9039                }
9040            }
9041        } catch (FileNotFoundException e) {
9042        } catch (IOException e) {
9043            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9044        } finally {
9045            if (fis != null) {
9046                try {
9047                    fis.close();
9048                } catch (IOException e) {
9049                }
9050            }
9051        }
9052        return lastDoneReceivers;
9053    }
9054
9055    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9056        File file = getCalledPreBootReceiversFile();
9057        FileOutputStream fos = null;
9058        DataOutputStream dos = null;
9059        try {
9060            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9061            fos = new FileOutputStream(file);
9062            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9063            dos.writeInt(LAST_DONE_VERSION);
9064            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9065            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9066            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9067            dos.writeInt(list.size());
9068            for (int i=0; i<list.size(); i++) {
9069                dos.writeUTF(list.get(i).getPackageName());
9070                dos.writeUTF(list.get(i).getClassName());
9071            }
9072        } catch (IOException e) {
9073            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9074            file.delete();
9075        } finally {
9076            FileUtils.sync(fos);
9077            if (dos != null) {
9078                try {
9079                    dos.close();
9080                } catch (IOException e) {
9081                    // TODO Auto-generated catch block
9082                    e.printStackTrace();
9083                }
9084            }
9085        }
9086    }
9087
9088    public void systemReady(final Runnable goingCallback) {
9089        synchronized(this) {
9090            if (mSystemReady) {
9091                if (goingCallback != null) goingCallback.run();
9092                return;
9093            }
9094
9095            // Check to see if there are any update receivers to run.
9096            if (!mDidUpdate) {
9097                if (mWaitingUpdate) {
9098                    return;
9099                }
9100                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9101                List<ResolveInfo> ris = null;
9102                try {
9103                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9104                            intent, null, 0, 0);
9105                } catch (RemoteException e) {
9106                }
9107                if (ris != null) {
9108                    for (int i=ris.size()-1; i>=0; i--) {
9109                        if ((ris.get(i).activityInfo.applicationInfo.flags
9110                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9111                            ris.remove(i);
9112                        }
9113                    }
9114                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9115
9116                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9117
9118                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9119                    for (int i=0; i<ris.size(); i++) {
9120                        ActivityInfo ai = ris.get(i).activityInfo;
9121                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9122                        if (lastDoneReceivers.contains(comp)) {
9123                            // We already did the pre boot receiver for this app with the current
9124                            // platform version, so don't do it again...
9125                            ris.remove(i);
9126                            i--;
9127                            // ...however, do keep it as one that has been done, so we don't
9128                            // forget about it when rewriting the file of last done receivers.
9129                            doneReceivers.add(comp);
9130                        }
9131                    }
9132
9133                    final int[] users = getUsersLocked();
9134                    for (int i=0; i<ris.size(); i++) {
9135                        ActivityInfo ai = ris.get(i).activityInfo;
9136                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9137                        doneReceivers.add(comp);
9138                        intent.setComponent(comp);
9139                        for (int j=0; j<users.length; j++) {
9140                            IIntentReceiver finisher = null;
9141                            if (i == ris.size()-1 && j == users.length-1) {
9142                                finisher = new IIntentReceiver.Stub() {
9143                                    public void performReceive(Intent intent, int resultCode,
9144                                            String data, Bundle extras, boolean ordered,
9145                                            boolean sticky, int sendingUser) {
9146                                        // The raw IIntentReceiver interface is called
9147                                        // with the AM lock held, so redispatch to
9148                                        // execute our code without the lock.
9149                                        mHandler.post(new Runnable() {
9150                                            public void run() {
9151                                                synchronized (ActivityManagerService.this) {
9152                                                    mDidUpdate = true;
9153                                                }
9154                                                writeLastDonePreBootReceivers(doneReceivers);
9155                                                showBootMessage(mContext.getText(
9156                                                        R.string.android_upgrading_complete),
9157                                                        false);
9158                                                systemReady(goingCallback);
9159                                            }
9160                                        });
9161                                    }
9162                                };
9163                            }
9164                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9165                                    + " for user " + users[j]);
9166                            broadcastIntentLocked(null, null, intent, null, finisher,
9167                                    0, null, null, null, AppOpsManager.OP_NONE,
9168                                    true, false, MY_PID, Process.SYSTEM_UID,
9169                                    users[j]);
9170                            if (finisher != null) {
9171                                mWaitingUpdate = true;
9172                            }
9173                        }
9174                    }
9175                }
9176                if (mWaitingUpdate) {
9177                    return;
9178                }
9179                mDidUpdate = true;
9180            }
9181
9182            mAppOpsService.systemReady();
9183            mSystemReady = true;
9184        }
9185
9186        ArrayList<ProcessRecord> procsToKill = null;
9187        synchronized(mPidsSelfLocked) {
9188            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9189                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9190                if (!isAllowedWhileBooting(proc.info)){
9191                    if (procsToKill == null) {
9192                        procsToKill = new ArrayList<ProcessRecord>();
9193                    }
9194                    procsToKill.add(proc);
9195                }
9196            }
9197        }
9198
9199        synchronized(this) {
9200            if (procsToKill != null) {
9201                for (int i=procsToKill.size()-1; i>=0; i--) {
9202                    ProcessRecord proc = procsToKill.get(i);
9203                    Slog.i(TAG, "Removing system update proc: " + proc);
9204                    removeProcessLocked(proc, true, false, "system update done");
9205                }
9206            }
9207
9208            // Now that we have cleaned up any update processes, we
9209            // are ready to start launching real processes and know that
9210            // we won't trample on them any more.
9211            mProcessesReady = true;
9212        }
9213
9214        Slog.i(TAG, "System now ready");
9215        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9216            SystemClock.uptimeMillis());
9217
9218        synchronized(this) {
9219            // Make sure we have no pre-ready processes sitting around.
9220
9221            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9222                ResolveInfo ri = mContext.getPackageManager()
9223                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9224                                STOCK_PM_FLAGS);
9225                CharSequence errorMsg = null;
9226                if (ri != null) {
9227                    ActivityInfo ai = ri.activityInfo;
9228                    ApplicationInfo app = ai.applicationInfo;
9229                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9230                        mTopAction = Intent.ACTION_FACTORY_TEST;
9231                        mTopData = null;
9232                        mTopComponent = new ComponentName(app.packageName,
9233                                ai.name);
9234                    } else {
9235                        errorMsg = mContext.getResources().getText(
9236                                com.android.internal.R.string.factorytest_not_system);
9237                    }
9238                } else {
9239                    errorMsg = mContext.getResources().getText(
9240                            com.android.internal.R.string.factorytest_no_action);
9241                }
9242                if (errorMsg != null) {
9243                    mTopAction = null;
9244                    mTopData = null;
9245                    mTopComponent = null;
9246                    Message msg = Message.obtain();
9247                    msg.what = SHOW_FACTORY_ERROR_MSG;
9248                    msg.getData().putCharSequence("msg", errorMsg);
9249                    mHandler.sendMessage(msg);
9250                }
9251            }
9252        }
9253
9254        retrieveSettings();
9255
9256        synchronized (this) {
9257            readGrantedUriPermissionsLocked();
9258        }
9259
9260        if (goingCallback != null) goingCallback.run();
9261
9262        synchronized (this) {
9263            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9264                try {
9265                    List apps = AppGlobals.getPackageManager().
9266                        getPersistentApplications(STOCK_PM_FLAGS);
9267                    if (apps != null) {
9268                        int N = apps.size();
9269                        int i;
9270                        for (i=0; i<N; i++) {
9271                            ApplicationInfo info
9272                                = (ApplicationInfo)apps.get(i);
9273                            if (info != null &&
9274                                    !info.packageName.equals("android")) {
9275                                addAppLocked(info, false);
9276                            }
9277                        }
9278                    }
9279                } catch (RemoteException ex) {
9280                    // pm is in same process, this will never happen.
9281                }
9282            }
9283
9284            // Start up initial activity.
9285            mBooting = true;
9286
9287            try {
9288                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9289                    Message msg = Message.obtain();
9290                    msg.what = SHOW_UID_ERROR_MSG;
9291                    mHandler.sendMessage(msg);
9292                }
9293            } catch (RemoteException e) {
9294            }
9295
9296            long ident = Binder.clearCallingIdentity();
9297            try {
9298                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9299                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9300                        | Intent.FLAG_RECEIVER_FOREGROUND);
9301                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9302                broadcastIntentLocked(null, null, intent,
9303                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9304                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9305                intent = new Intent(Intent.ACTION_USER_STARTING);
9306                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9307                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9308                broadcastIntentLocked(null, null, intent,
9309                        null, new IIntentReceiver.Stub() {
9310                            @Override
9311                            public void performReceive(Intent intent, int resultCode, String data,
9312                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9313                                    throws RemoteException {
9314                            }
9315                        }, 0, null, null,
9316                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9317                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9318            } finally {
9319                Binder.restoreCallingIdentity(ident);
9320            }
9321            mStackSupervisor.resumeTopActivitiesLocked();
9322            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9323        }
9324    }
9325
9326    private boolean makeAppCrashingLocked(ProcessRecord app,
9327            String shortMsg, String longMsg, String stackTrace) {
9328        app.crashing = true;
9329        app.crashingReport = generateProcessError(app,
9330                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9331        startAppProblemLocked(app);
9332        app.stopFreezingAllLocked();
9333        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9334    }
9335
9336    private void makeAppNotRespondingLocked(ProcessRecord app,
9337            String activity, String shortMsg, String longMsg) {
9338        app.notResponding = true;
9339        app.notRespondingReport = generateProcessError(app,
9340                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9341                activity, shortMsg, longMsg, null);
9342        startAppProblemLocked(app);
9343        app.stopFreezingAllLocked();
9344    }
9345
9346    /**
9347     * Generate a process error record, suitable for attachment to a ProcessRecord.
9348     *
9349     * @param app The ProcessRecord in which the error occurred.
9350     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9351     *                      ActivityManager.AppErrorStateInfo
9352     * @param activity The activity associated with the crash, if known.
9353     * @param shortMsg Short message describing the crash.
9354     * @param longMsg Long message describing the crash.
9355     * @param stackTrace Full crash stack trace, may be null.
9356     *
9357     * @return Returns a fully-formed AppErrorStateInfo record.
9358     */
9359    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9360            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9361        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9362
9363        report.condition = condition;
9364        report.processName = app.processName;
9365        report.pid = app.pid;
9366        report.uid = app.info.uid;
9367        report.tag = activity;
9368        report.shortMsg = shortMsg;
9369        report.longMsg = longMsg;
9370        report.stackTrace = stackTrace;
9371
9372        return report;
9373    }
9374
9375    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9376        synchronized (this) {
9377            app.crashing = false;
9378            app.crashingReport = null;
9379            app.notResponding = false;
9380            app.notRespondingReport = null;
9381            if (app.anrDialog == fromDialog) {
9382                app.anrDialog = null;
9383            }
9384            if (app.waitDialog == fromDialog) {
9385                app.waitDialog = null;
9386            }
9387            if (app.pid > 0 && app.pid != MY_PID) {
9388                handleAppCrashLocked(app, null, null, null);
9389                killUnneededProcessLocked(app, "user request after error");
9390            }
9391        }
9392    }
9393
9394    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9395            String stackTrace) {
9396        long now = SystemClock.uptimeMillis();
9397
9398        Long crashTime;
9399        if (!app.isolated) {
9400            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9401        } else {
9402            crashTime = null;
9403        }
9404        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9405            // This process loses!
9406            Slog.w(TAG, "Process " + app.info.processName
9407                    + " has crashed too many times: killing!");
9408            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9409                    app.userId, app.info.processName, app.uid);
9410            mStackSupervisor.handleAppCrashLocked(app);
9411            if (!app.persistent) {
9412                // We don't want to start this process again until the user
9413                // explicitly does so...  but for persistent process, we really
9414                // need to keep it running.  If a persistent process is actually
9415                // repeatedly crashing, then badness for everyone.
9416                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9417                        app.info.processName);
9418                if (!app.isolated) {
9419                    // XXX We don't have a way to mark isolated processes
9420                    // as bad, since they don't have a peristent identity.
9421                    mBadProcesses.put(app.info.processName, app.uid,
9422                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9423                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9424                }
9425                app.bad = true;
9426                app.removed = true;
9427                // Don't let services in this process be restarted and potentially
9428                // annoy the user repeatedly.  Unless it is persistent, since those
9429                // processes run critical code.
9430                removeProcessLocked(app, false, false, "crash");
9431                mStackSupervisor.resumeTopActivitiesLocked();
9432                return false;
9433            }
9434            mStackSupervisor.resumeTopActivitiesLocked();
9435        } else {
9436            mStackSupervisor.finishTopRunningActivityLocked(app);
9437        }
9438
9439        // Bump up the crash count of any services currently running in the proc.
9440        for (int i=app.services.size()-1; i>=0; i--) {
9441            // Any services running in the application need to be placed
9442            // back in the pending list.
9443            ServiceRecord sr = app.services.valueAt(i);
9444            sr.crashCount++;
9445        }
9446
9447        // If the crashing process is what we consider to be the "home process" and it has been
9448        // replaced by a third-party app, clear the package preferred activities from packages
9449        // with a home activity running in the process to prevent a repeatedly crashing app
9450        // from blocking the user to manually clear the list.
9451        final ArrayList<ActivityRecord> activities = app.activities;
9452        if (app == mHomeProcess && activities.size() > 0
9453                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9454            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9455                final ActivityRecord r = activities.get(activityNdx);
9456                if (r.isHomeActivity()) {
9457                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9458                    try {
9459                        ActivityThread.getPackageManager()
9460                                .clearPackagePreferredActivities(r.packageName);
9461                    } catch (RemoteException c) {
9462                        // pm is in same process, this will never happen.
9463                    }
9464                }
9465            }
9466        }
9467
9468        if (!app.isolated) {
9469            // XXX Can't keep track of crash times for isolated processes,
9470            // because they don't have a perisistent identity.
9471            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9472        }
9473
9474        return true;
9475    }
9476
9477    void startAppProblemLocked(ProcessRecord app) {
9478        if (app.userId == mCurrentUserId) {
9479            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9480                    mContext, app.info.packageName, app.info.flags);
9481        } else {
9482            // If this app is not running under the current user, then we
9483            // can't give it a report button because that would require
9484            // launching the report UI under a different user.
9485            app.errorReportReceiver = null;
9486        }
9487        skipCurrentReceiverLocked(app);
9488    }
9489
9490    void skipCurrentReceiverLocked(ProcessRecord app) {
9491        for (BroadcastQueue queue : mBroadcastQueues) {
9492            queue.skipCurrentReceiverLocked(app);
9493        }
9494    }
9495
9496    /**
9497     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9498     * The application process will exit immediately after this call returns.
9499     * @param app object of the crashing app, null for the system server
9500     * @param crashInfo describing the exception
9501     */
9502    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9503        ProcessRecord r = findAppProcess(app, "Crash");
9504        final String processName = app == null ? "system_server"
9505                : (r == null ? "unknown" : r.processName);
9506
9507        handleApplicationCrashInner("crash", r, processName, crashInfo);
9508    }
9509
9510    /* Native crash reporting uses this inner version because it needs to be somewhat
9511     * decoupled from the AM-managed cleanup lifecycle
9512     */
9513    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9514            ApplicationErrorReport.CrashInfo crashInfo) {
9515        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9516                UserHandle.getUserId(Binder.getCallingUid()), processName,
9517                r == null ? -1 : r.info.flags,
9518                crashInfo.exceptionClassName,
9519                crashInfo.exceptionMessage,
9520                crashInfo.throwFileName,
9521                crashInfo.throwLineNumber);
9522
9523        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9524
9525        crashApplication(r, crashInfo);
9526    }
9527
9528    public void handleApplicationStrictModeViolation(
9529            IBinder app,
9530            int violationMask,
9531            StrictMode.ViolationInfo info) {
9532        ProcessRecord r = findAppProcess(app, "StrictMode");
9533        if (r == null) {
9534            return;
9535        }
9536
9537        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9538            Integer stackFingerprint = info.hashCode();
9539            boolean logIt = true;
9540            synchronized (mAlreadyLoggedViolatedStacks) {
9541                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9542                    logIt = false;
9543                    // TODO: sub-sample into EventLog for these, with
9544                    // the info.durationMillis?  Then we'd get
9545                    // the relative pain numbers, without logging all
9546                    // the stack traces repeatedly.  We'd want to do
9547                    // likewise in the client code, which also does
9548                    // dup suppression, before the Binder call.
9549                } else {
9550                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9551                        mAlreadyLoggedViolatedStacks.clear();
9552                    }
9553                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9554                }
9555            }
9556            if (logIt) {
9557                logStrictModeViolationToDropBox(r, info);
9558            }
9559        }
9560
9561        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9562            AppErrorResult result = new AppErrorResult();
9563            synchronized (this) {
9564                final long origId = Binder.clearCallingIdentity();
9565
9566                Message msg = Message.obtain();
9567                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9568                HashMap<String, Object> data = new HashMap<String, Object>();
9569                data.put("result", result);
9570                data.put("app", r);
9571                data.put("violationMask", violationMask);
9572                data.put("info", info);
9573                msg.obj = data;
9574                mHandler.sendMessage(msg);
9575
9576                Binder.restoreCallingIdentity(origId);
9577            }
9578            int res = result.get();
9579            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9580        }
9581    }
9582
9583    // Depending on the policy in effect, there could be a bunch of
9584    // these in quick succession so we try to batch these together to
9585    // minimize disk writes, number of dropbox entries, and maximize
9586    // compression, by having more fewer, larger records.
9587    private void logStrictModeViolationToDropBox(
9588            ProcessRecord process,
9589            StrictMode.ViolationInfo info) {
9590        if (info == null) {
9591            return;
9592        }
9593        final boolean isSystemApp = process == null ||
9594                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9595                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9596        final String processName = process == null ? "unknown" : process.processName;
9597        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9598        final DropBoxManager dbox = (DropBoxManager)
9599                mContext.getSystemService(Context.DROPBOX_SERVICE);
9600
9601        // Exit early if the dropbox isn't configured to accept this report type.
9602        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9603
9604        boolean bufferWasEmpty;
9605        boolean needsFlush;
9606        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9607        synchronized (sb) {
9608            bufferWasEmpty = sb.length() == 0;
9609            appendDropBoxProcessHeaders(process, processName, sb);
9610            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9611            sb.append("System-App: ").append(isSystemApp).append("\n");
9612            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9613            if (info.violationNumThisLoop != 0) {
9614                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9615            }
9616            if (info.numAnimationsRunning != 0) {
9617                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9618            }
9619            if (info.broadcastIntentAction != null) {
9620                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9621            }
9622            if (info.durationMillis != -1) {
9623                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9624            }
9625            if (info.numInstances != -1) {
9626                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9627            }
9628            if (info.tags != null) {
9629                for (String tag : info.tags) {
9630                    sb.append("Span-Tag: ").append(tag).append("\n");
9631                }
9632            }
9633            sb.append("\n");
9634            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9635                sb.append(info.crashInfo.stackTrace);
9636            }
9637            sb.append("\n");
9638
9639            // Only buffer up to ~64k.  Various logging bits truncate
9640            // things at 128k.
9641            needsFlush = (sb.length() > 64 * 1024);
9642        }
9643
9644        // Flush immediately if the buffer's grown too large, or this
9645        // is a non-system app.  Non-system apps are isolated with a
9646        // different tag & policy and not batched.
9647        //
9648        // Batching is useful during internal testing with
9649        // StrictMode settings turned up high.  Without batching,
9650        // thousands of separate files could be created on boot.
9651        if (!isSystemApp || needsFlush) {
9652            new Thread("Error dump: " + dropboxTag) {
9653                @Override
9654                public void run() {
9655                    String report;
9656                    synchronized (sb) {
9657                        report = sb.toString();
9658                        sb.delete(0, sb.length());
9659                        sb.trimToSize();
9660                    }
9661                    if (report.length() != 0) {
9662                        dbox.addText(dropboxTag, report);
9663                    }
9664                }
9665            }.start();
9666            return;
9667        }
9668
9669        // System app batching:
9670        if (!bufferWasEmpty) {
9671            // An existing dropbox-writing thread is outstanding, so
9672            // we don't need to start it up.  The existing thread will
9673            // catch the buffer appends we just did.
9674            return;
9675        }
9676
9677        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9678        // (After this point, we shouldn't access AMS internal data structures.)
9679        new Thread("Error dump: " + dropboxTag) {
9680            @Override
9681            public void run() {
9682                // 5 second sleep to let stacks arrive and be batched together
9683                try {
9684                    Thread.sleep(5000);  // 5 seconds
9685                } catch (InterruptedException e) {}
9686
9687                String errorReport;
9688                synchronized (mStrictModeBuffer) {
9689                    errorReport = mStrictModeBuffer.toString();
9690                    if (errorReport.length() == 0) {
9691                        return;
9692                    }
9693                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9694                    mStrictModeBuffer.trimToSize();
9695                }
9696                dbox.addText(dropboxTag, errorReport);
9697            }
9698        }.start();
9699    }
9700
9701    /**
9702     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9703     * @param app object of the crashing app, null for the system server
9704     * @param tag reported by the caller
9705     * @param crashInfo describing the context of the error
9706     * @return true if the process should exit immediately (WTF is fatal)
9707     */
9708    public boolean handleApplicationWtf(IBinder app, String tag,
9709            ApplicationErrorReport.CrashInfo crashInfo) {
9710        ProcessRecord r = findAppProcess(app, "WTF");
9711        final String processName = app == null ? "system_server"
9712                : (r == null ? "unknown" : r.processName);
9713
9714        EventLog.writeEvent(EventLogTags.AM_WTF,
9715                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9716                processName,
9717                r == null ? -1 : r.info.flags,
9718                tag, crashInfo.exceptionMessage);
9719
9720        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9721
9722        if (r != null && r.pid != Process.myPid() &&
9723                Settings.Global.getInt(mContext.getContentResolver(),
9724                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9725            crashApplication(r, crashInfo);
9726            return true;
9727        } else {
9728            return false;
9729        }
9730    }
9731
9732    /**
9733     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9734     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9735     */
9736    private ProcessRecord findAppProcess(IBinder app, String reason) {
9737        if (app == null) {
9738            return null;
9739        }
9740
9741        synchronized (this) {
9742            final int NP = mProcessNames.getMap().size();
9743            for (int ip=0; ip<NP; ip++) {
9744                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9745                final int NA = apps.size();
9746                for (int ia=0; ia<NA; ia++) {
9747                    ProcessRecord p = apps.valueAt(ia);
9748                    if (p.thread != null && p.thread.asBinder() == app) {
9749                        return p;
9750                    }
9751                }
9752            }
9753
9754            Slog.w(TAG, "Can't find mystery application for " + reason
9755                    + " from pid=" + Binder.getCallingPid()
9756                    + " uid=" + Binder.getCallingUid() + ": " + app);
9757            return null;
9758        }
9759    }
9760
9761    /**
9762     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9763     * to append various headers to the dropbox log text.
9764     */
9765    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9766            StringBuilder sb) {
9767        // Watchdog thread ends up invoking this function (with
9768        // a null ProcessRecord) to add the stack file to dropbox.
9769        // Do not acquire a lock on this (am) in such cases, as it
9770        // could cause a potential deadlock, if and when watchdog
9771        // is invoked due to unavailability of lock on am and it
9772        // would prevent watchdog from killing system_server.
9773        if (process == null) {
9774            sb.append("Process: ").append(processName).append("\n");
9775            return;
9776        }
9777        // Note: ProcessRecord 'process' is guarded by the service
9778        // instance.  (notably process.pkgList, which could otherwise change
9779        // concurrently during execution of this method)
9780        synchronized (this) {
9781            sb.append("Process: ").append(processName).append("\n");
9782            int flags = process.info.flags;
9783            IPackageManager pm = AppGlobals.getPackageManager();
9784            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9785            for (int ip=0; ip<process.pkgList.size(); ip++) {
9786                String pkg = process.pkgList.keyAt(ip);
9787                sb.append("Package: ").append(pkg);
9788                try {
9789                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9790                    if (pi != null) {
9791                        sb.append(" v").append(pi.versionCode);
9792                        if (pi.versionName != null) {
9793                            sb.append(" (").append(pi.versionName).append(")");
9794                        }
9795                    }
9796                } catch (RemoteException e) {
9797                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9798                }
9799                sb.append("\n");
9800            }
9801        }
9802    }
9803
9804    private static String processClass(ProcessRecord process) {
9805        if (process == null || process.pid == MY_PID) {
9806            return "system_server";
9807        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9808            return "system_app";
9809        } else {
9810            return "data_app";
9811        }
9812    }
9813
9814    /**
9815     * Write a description of an error (crash, WTF, ANR) to the drop box.
9816     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9817     * @param process which caused the error, null means the system server
9818     * @param activity which triggered the error, null if unknown
9819     * @param parent activity related to the error, null if unknown
9820     * @param subject line related to the error, null if absent
9821     * @param report in long form describing the error, null if absent
9822     * @param logFile to include in the report, null if none
9823     * @param crashInfo giving an application stack trace, null if absent
9824     */
9825    public void addErrorToDropBox(String eventType,
9826            ProcessRecord process, String processName, ActivityRecord activity,
9827            ActivityRecord parent, String subject,
9828            final String report, final File logFile,
9829            final ApplicationErrorReport.CrashInfo crashInfo) {
9830        // NOTE -- this must never acquire the ActivityManagerService lock,
9831        // otherwise the watchdog may be prevented from resetting the system.
9832
9833        final String dropboxTag = processClass(process) + "_" + eventType;
9834        final DropBoxManager dbox = (DropBoxManager)
9835                mContext.getSystemService(Context.DROPBOX_SERVICE);
9836
9837        // Exit early if the dropbox isn't configured to accept this report type.
9838        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9839
9840        final StringBuilder sb = new StringBuilder(1024);
9841        appendDropBoxProcessHeaders(process, processName, sb);
9842        if (activity != null) {
9843            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9844        }
9845        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9846            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9847        }
9848        if (parent != null && parent != activity) {
9849            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9850        }
9851        if (subject != null) {
9852            sb.append("Subject: ").append(subject).append("\n");
9853        }
9854        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9855        if (Debug.isDebuggerConnected()) {
9856            sb.append("Debugger: Connected\n");
9857        }
9858        sb.append("\n");
9859
9860        // Do the rest in a worker thread to avoid blocking the caller on I/O
9861        // (After this point, we shouldn't access AMS internal data structures.)
9862        Thread worker = new Thread("Error dump: " + dropboxTag) {
9863            @Override
9864            public void run() {
9865                if (report != null) {
9866                    sb.append(report);
9867                }
9868                if (logFile != null) {
9869                    try {
9870                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9871                                    "\n\n[[TRUNCATED]]"));
9872                    } catch (IOException e) {
9873                        Slog.e(TAG, "Error reading " + logFile, e);
9874                    }
9875                }
9876                if (crashInfo != null && crashInfo.stackTrace != null) {
9877                    sb.append(crashInfo.stackTrace);
9878                }
9879
9880                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9881                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9882                if (lines > 0) {
9883                    sb.append("\n");
9884
9885                    // Merge several logcat streams, and take the last N lines
9886                    InputStreamReader input = null;
9887                    try {
9888                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9889                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9890                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9891
9892                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9893                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9894                        input = new InputStreamReader(logcat.getInputStream());
9895
9896                        int num;
9897                        char[] buf = new char[8192];
9898                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9899                    } catch (IOException e) {
9900                        Slog.e(TAG, "Error running logcat", e);
9901                    } finally {
9902                        if (input != null) try { input.close(); } catch (IOException e) {}
9903                    }
9904                }
9905
9906                dbox.addText(dropboxTag, sb.toString());
9907            }
9908        };
9909
9910        if (process == null) {
9911            // If process is null, we are being called from some internal code
9912            // and may be about to die -- run this synchronously.
9913            worker.run();
9914        } else {
9915            worker.start();
9916        }
9917    }
9918
9919    /**
9920     * Bring up the "unexpected error" dialog box for a crashing app.
9921     * Deal with edge cases (intercepts from instrumented applications,
9922     * ActivityController, error intent receivers, that sort of thing).
9923     * @param r the application crashing
9924     * @param crashInfo describing the failure
9925     */
9926    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9927        long timeMillis = System.currentTimeMillis();
9928        String shortMsg = crashInfo.exceptionClassName;
9929        String longMsg = crashInfo.exceptionMessage;
9930        String stackTrace = crashInfo.stackTrace;
9931        if (shortMsg != null && longMsg != null) {
9932            longMsg = shortMsg + ": " + longMsg;
9933        } else if (shortMsg != null) {
9934            longMsg = shortMsg;
9935        }
9936
9937        AppErrorResult result = new AppErrorResult();
9938        synchronized (this) {
9939            if (mController != null) {
9940                try {
9941                    String name = r != null ? r.processName : null;
9942                    int pid = r != null ? r.pid : Binder.getCallingPid();
9943                    if (!mController.appCrashed(name, pid,
9944                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9945                        Slog.w(TAG, "Force-killing crashed app " + name
9946                                + " at watcher's request");
9947                        Process.killProcess(pid);
9948                        return;
9949                    }
9950                } catch (RemoteException e) {
9951                    mController = null;
9952                    Watchdog.getInstance().setActivityController(null);
9953                }
9954            }
9955
9956            final long origId = Binder.clearCallingIdentity();
9957
9958            // If this process is running instrumentation, finish it.
9959            if (r != null && r.instrumentationClass != null) {
9960                Slog.w(TAG, "Error in app " + r.processName
9961                      + " running instrumentation " + r.instrumentationClass + ":");
9962                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
9963                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
9964                Bundle info = new Bundle();
9965                info.putString("shortMsg", shortMsg);
9966                info.putString("longMsg", longMsg);
9967                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
9968                Binder.restoreCallingIdentity(origId);
9969                return;
9970            }
9971
9972            // If we can't identify the process or it's already exceeded its crash quota,
9973            // quit right away without showing a crash dialog.
9974            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
9975                Binder.restoreCallingIdentity(origId);
9976                return;
9977            }
9978
9979            Message msg = Message.obtain();
9980            msg.what = SHOW_ERROR_MSG;
9981            HashMap data = new HashMap();
9982            data.put("result", result);
9983            data.put("app", r);
9984            msg.obj = data;
9985            mHandler.sendMessage(msg);
9986
9987            Binder.restoreCallingIdentity(origId);
9988        }
9989
9990        int res = result.get();
9991
9992        Intent appErrorIntent = null;
9993        synchronized (this) {
9994            if (r != null && !r.isolated) {
9995                // XXX Can't keep track of crash time for isolated processes,
9996                // since they don't have a persistent identity.
9997                mProcessCrashTimes.put(r.info.processName, r.uid,
9998                        SystemClock.uptimeMillis());
9999            }
10000            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10001                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10002            }
10003        }
10004
10005        if (appErrorIntent != null) {
10006            try {
10007                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10008            } catch (ActivityNotFoundException e) {
10009                Slog.w(TAG, "bug report receiver dissappeared", e);
10010            }
10011        }
10012    }
10013
10014    Intent createAppErrorIntentLocked(ProcessRecord r,
10015            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10016        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10017        if (report == null) {
10018            return null;
10019        }
10020        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10021        result.setComponent(r.errorReportReceiver);
10022        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10023        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10024        return result;
10025    }
10026
10027    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10028            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10029        if (r.errorReportReceiver == null) {
10030            return null;
10031        }
10032
10033        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10034            return null;
10035        }
10036
10037        ApplicationErrorReport report = new ApplicationErrorReport();
10038        report.packageName = r.info.packageName;
10039        report.installerPackageName = r.errorReportReceiver.getPackageName();
10040        report.processName = r.processName;
10041        report.time = timeMillis;
10042        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10043
10044        if (r.crashing || r.forceCrashReport) {
10045            report.type = ApplicationErrorReport.TYPE_CRASH;
10046            report.crashInfo = crashInfo;
10047        } else if (r.notResponding) {
10048            report.type = ApplicationErrorReport.TYPE_ANR;
10049            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10050
10051            report.anrInfo.activity = r.notRespondingReport.tag;
10052            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10053            report.anrInfo.info = r.notRespondingReport.longMsg;
10054        }
10055
10056        return report;
10057    }
10058
10059    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10060        enforceNotIsolatedCaller("getProcessesInErrorState");
10061        // assume our apps are happy - lazy create the list
10062        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10063
10064        final boolean allUsers = ActivityManager.checkUidPermission(
10065                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10066                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10067        int userId = UserHandle.getUserId(Binder.getCallingUid());
10068
10069        synchronized (this) {
10070
10071            // iterate across all processes
10072            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10073                ProcessRecord app = mLruProcesses.get(i);
10074                if (!allUsers && app.userId != userId) {
10075                    continue;
10076                }
10077                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10078                    // This one's in trouble, so we'll generate a report for it
10079                    // crashes are higher priority (in case there's a crash *and* an anr)
10080                    ActivityManager.ProcessErrorStateInfo report = null;
10081                    if (app.crashing) {
10082                        report = app.crashingReport;
10083                    } else if (app.notResponding) {
10084                        report = app.notRespondingReport;
10085                    }
10086
10087                    if (report != null) {
10088                        if (errList == null) {
10089                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10090                        }
10091                        errList.add(report);
10092                    } else {
10093                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10094                                " crashing = " + app.crashing +
10095                                " notResponding = " + app.notResponding);
10096                    }
10097                }
10098            }
10099        }
10100
10101        return errList;
10102    }
10103
10104    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10105        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10106            if (currApp != null) {
10107                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10108            }
10109            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10110        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10111            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10112        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10113            if (currApp != null) {
10114                currApp.lru = 0;
10115            }
10116            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10117        } else if (adj >= ProcessList.SERVICE_ADJ) {
10118            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10119        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10120            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10121        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10122            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10123        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10124            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10125        } else {
10126            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10127        }
10128    }
10129
10130    private void fillInProcMemInfo(ProcessRecord app,
10131            ActivityManager.RunningAppProcessInfo outInfo) {
10132        outInfo.pid = app.pid;
10133        outInfo.uid = app.info.uid;
10134        if (mHeavyWeightProcess == app) {
10135            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10136        }
10137        if (app.persistent) {
10138            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10139        }
10140        if (app.activities.size() > 0) {
10141            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10142        }
10143        outInfo.lastTrimLevel = app.trimMemoryLevel;
10144        int adj = app.curAdj;
10145        outInfo.importance = oomAdjToImportance(adj, outInfo);
10146        outInfo.importanceReasonCode = app.adjTypeCode;
10147    }
10148
10149    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10150        enforceNotIsolatedCaller("getRunningAppProcesses");
10151        // Lazy instantiation of list
10152        List<ActivityManager.RunningAppProcessInfo> runList = null;
10153        final boolean allUsers = ActivityManager.checkUidPermission(
10154                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10155                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10156        int userId = UserHandle.getUserId(Binder.getCallingUid());
10157        synchronized (this) {
10158            // Iterate across all processes
10159            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10160                ProcessRecord app = mLruProcesses.get(i);
10161                if (!allUsers && app.userId != userId) {
10162                    continue;
10163                }
10164                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10165                    // Generate process state info for running application
10166                    ActivityManager.RunningAppProcessInfo currApp =
10167                        new ActivityManager.RunningAppProcessInfo(app.processName,
10168                                app.pid, app.getPackageList());
10169                    fillInProcMemInfo(app, currApp);
10170                    if (app.adjSource instanceof ProcessRecord) {
10171                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10172                        currApp.importanceReasonImportance = oomAdjToImportance(
10173                                app.adjSourceOom, null);
10174                    } else if (app.adjSource instanceof ActivityRecord) {
10175                        ActivityRecord r = (ActivityRecord)app.adjSource;
10176                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10177                    }
10178                    if (app.adjTarget instanceof ComponentName) {
10179                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10180                    }
10181                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10182                    //        + " lru=" + currApp.lru);
10183                    if (runList == null) {
10184                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10185                    }
10186                    runList.add(currApp);
10187                }
10188            }
10189        }
10190        return runList;
10191    }
10192
10193    public List<ApplicationInfo> getRunningExternalApplications() {
10194        enforceNotIsolatedCaller("getRunningExternalApplications");
10195        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10196        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10197        if (runningApps != null && runningApps.size() > 0) {
10198            Set<String> extList = new HashSet<String>();
10199            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10200                if (app.pkgList != null) {
10201                    for (String pkg : app.pkgList) {
10202                        extList.add(pkg);
10203                    }
10204                }
10205            }
10206            IPackageManager pm = AppGlobals.getPackageManager();
10207            for (String pkg : extList) {
10208                try {
10209                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10210                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10211                        retList.add(info);
10212                    }
10213                } catch (RemoteException e) {
10214                }
10215            }
10216        }
10217        return retList;
10218    }
10219
10220    @Override
10221    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10222        enforceNotIsolatedCaller("getMyMemoryState");
10223        synchronized (this) {
10224            ProcessRecord proc;
10225            synchronized (mPidsSelfLocked) {
10226                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10227            }
10228            fillInProcMemInfo(proc, outInfo);
10229        }
10230    }
10231
10232    @Override
10233    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10234        if (checkCallingPermission(android.Manifest.permission.DUMP)
10235                != PackageManager.PERMISSION_GRANTED) {
10236            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10237                    + Binder.getCallingPid()
10238                    + ", uid=" + Binder.getCallingUid()
10239                    + " without permission "
10240                    + android.Manifest.permission.DUMP);
10241            return;
10242        }
10243
10244        boolean dumpAll = false;
10245        boolean dumpClient = false;
10246        String dumpPackage = null;
10247
10248        int opti = 0;
10249        while (opti < args.length) {
10250            String opt = args[opti];
10251            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10252                break;
10253            }
10254            opti++;
10255            if ("-a".equals(opt)) {
10256                dumpAll = true;
10257            } else if ("-c".equals(opt)) {
10258                dumpClient = true;
10259            } else if ("-h".equals(opt)) {
10260                pw.println("Activity manager dump options:");
10261                pw.println("  [-a] [-c] [-h] [cmd] ...");
10262                pw.println("  cmd may be one of:");
10263                pw.println("    a[ctivities]: activity stack state");
10264                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10265                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10266                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10267                pw.println("    o[om]: out of memory management");
10268                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10269                pw.println("    provider [COMP_SPEC]: provider client-side state");
10270                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10271                pw.println("    service [COMP_SPEC]: service client-side state");
10272                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10273                pw.println("    all: dump all activities");
10274                pw.println("    top: dump the top activity");
10275                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10276                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10277                pw.println("    a partial substring in a component name, a");
10278                pw.println("    hex object identifier.");
10279                pw.println("  -a: include all available server state.");
10280                pw.println("  -c: include client state.");
10281                return;
10282            } else {
10283                pw.println("Unknown argument: " + opt + "; use -h for help");
10284            }
10285        }
10286
10287        long origId = Binder.clearCallingIdentity();
10288        boolean more = false;
10289        // Is the caller requesting to dump a particular piece of data?
10290        if (opti < args.length) {
10291            String cmd = args[opti];
10292            opti++;
10293            if ("activities".equals(cmd) || "a".equals(cmd)) {
10294                synchronized (this) {
10295                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10296                }
10297            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10298                String[] newArgs;
10299                String name;
10300                if (opti >= args.length) {
10301                    name = null;
10302                    newArgs = EMPTY_STRING_ARRAY;
10303                } else {
10304                    name = args[opti];
10305                    opti++;
10306                    newArgs = new String[args.length - opti];
10307                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10308                            args.length - opti);
10309                }
10310                synchronized (this) {
10311                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10312                }
10313            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10314                String[] newArgs;
10315                String name;
10316                if (opti >= args.length) {
10317                    name = null;
10318                    newArgs = EMPTY_STRING_ARRAY;
10319                } else {
10320                    name = args[opti];
10321                    opti++;
10322                    newArgs = new String[args.length - opti];
10323                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10324                            args.length - opti);
10325                }
10326                synchronized (this) {
10327                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10328                }
10329            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10330                String[] newArgs;
10331                String name;
10332                if (opti >= args.length) {
10333                    name = null;
10334                    newArgs = EMPTY_STRING_ARRAY;
10335                } else {
10336                    name = args[opti];
10337                    opti++;
10338                    newArgs = new String[args.length - opti];
10339                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10340                            args.length - opti);
10341                }
10342                synchronized (this) {
10343                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10344                }
10345            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10346                synchronized (this) {
10347                    dumpOomLocked(fd, pw, args, opti, true);
10348                }
10349            } else if ("provider".equals(cmd)) {
10350                String[] newArgs;
10351                String name;
10352                if (opti >= args.length) {
10353                    name = null;
10354                    newArgs = EMPTY_STRING_ARRAY;
10355                } else {
10356                    name = args[opti];
10357                    opti++;
10358                    newArgs = new String[args.length - opti];
10359                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10360                }
10361                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10362                    pw.println("No providers match: " + name);
10363                    pw.println("Use -h for help.");
10364                }
10365            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10366                synchronized (this) {
10367                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10368                }
10369            } else if ("service".equals(cmd)) {
10370                String[] newArgs;
10371                String name;
10372                if (opti >= args.length) {
10373                    name = null;
10374                    newArgs = EMPTY_STRING_ARRAY;
10375                } else {
10376                    name = args[opti];
10377                    opti++;
10378                    newArgs = new String[args.length - opti];
10379                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10380                            args.length - opti);
10381                }
10382                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10383                    pw.println("No services match: " + name);
10384                    pw.println("Use -h for help.");
10385                }
10386            } else if ("package".equals(cmd)) {
10387                String[] newArgs;
10388                if (opti >= args.length) {
10389                    pw.println("package: no package name specified");
10390                    pw.println("Use -h for help.");
10391                } else {
10392                    dumpPackage = args[opti];
10393                    opti++;
10394                    newArgs = new String[args.length - opti];
10395                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10396                            args.length - opti);
10397                    args = newArgs;
10398                    opti = 0;
10399                    more = true;
10400                }
10401            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10402                synchronized (this) {
10403                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10404                }
10405            } else {
10406                // Dumping a single activity?
10407                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10408                    pw.println("Bad activity command, or no activities match: " + cmd);
10409                    pw.println("Use -h for help.");
10410                }
10411            }
10412            if (!more) {
10413                Binder.restoreCallingIdentity(origId);
10414                return;
10415            }
10416        }
10417
10418        // No piece of data specified, dump everything.
10419        synchronized (this) {
10420            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10421            pw.println();
10422            if (dumpAll) {
10423                pw.println("-------------------------------------------------------------------------------");
10424            }
10425            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10426            pw.println();
10427            if (dumpAll) {
10428                pw.println("-------------------------------------------------------------------------------");
10429            }
10430            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10431            pw.println();
10432            if (dumpAll) {
10433                pw.println("-------------------------------------------------------------------------------");
10434            }
10435            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10436            pw.println();
10437            if (dumpAll) {
10438                pw.println("-------------------------------------------------------------------------------");
10439            }
10440            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10441            pw.println();
10442            if (dumpAll) {
10443                pw.println("-------------------------------------------------------------------------------");
10444            }
10445            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10446        }
10447        Binder.restoreCallingIdentity(origId);
10448    }
10449
10450    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10451            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10452        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10453
10454        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10455                dumpPackage);
10456        boolean needSep = printedAnything;
10457
10458        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10459                dumpPackage, needSep, "  mFocusedActivity: ");
10460        if (printed) {
10461            printedAnything = true;
10462            needSep = false;
10463        }
10464
10465        if (dumpPackage == null) {
10466            if (needSep) {
10467                pw.println();
10468            }
10469            needSep = true;
10470            printedAnything = true;
10471            mStackSupervisor.dump(pw, "  ");
10472        }
10473
10474        if (mRecentTasks.size() > 0) {
10475            boolean printedHeader = false;
10476
10477            final int N = mRecentTasks.size();
10478            for (int i=0; i<N; i++) {
10479                TaskRecord tr = mRecentTasks.get(i);
10480                if (dumpPackage != null) {
10481                    if (tr.realActivity == null ||
10482                            !dumpPackage.equals(tr.realActivity)) {
10483                        continue;
10484                    }
10485                }
10486                if (!printedHeader) {
10487                    if (needSep) {
10488                        pw.println();
10489                    }
10490                    pw.println("  Recent tasks:");
10491                    printedHeader = true;
10492                    printedAnything = true;
10493                }
10494                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10495                        pw.println(tr);
10496                if (dumpAll) {
10497                    mRecentTasks.get(i).dump(pw, "    ");
10498                }
10499            }
10500        }
10501
10502        if (!printedAnything) {
10503            pw.println("  (nothing)");
10504        }
10505    }
10506
10507    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10508            int opti, boolean dumpAll, String dumpPackage) {
10509        boolean needSep = false;
10510        boolean printedAnything = false;
10511        int numPers = 0;
10512
10513        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10514
10515        if (dumpAll) {
10516            final int NP = mProcessNames.getMap().size();
10517            for (int ip=0; ip<NP; ip++) {
10518                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10519                final int NA = procs.size();
10520                for (int ia=0; ia<NA; ia++) {
10521                    ProcessRecord r = procs.valueAt(ia);
10522                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10523                        continue;
10524                    }
10525                    if (!needSep) {
10526                        pw.println("  All known processes:");
10527                        needSep = true;
10528                        printedAnything = true;
10529                    }
10530                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10531                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10532                        pw.print(" "); pw.println(r);
10533                    r.dump(pw, "    ");
10534                    if (r.persistent) {
10535                        numPers++;
10536                    }
10537                }
10538            }
10539        }
10540
10541        if (mIsolatedProcesses.size() > 0) {
10542            boolean printed = false;
10543            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10544                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10545                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10546                    continue;
10547                }
10548                if (!printed) {
10549                    if (needSep) {
10550                        pw.println();
10551                    }
10552                    pw.println("  Isolated process list (sorted by uid):");
10553                    printedAnything = true;
10554                    printed = true;
10555                    needSep = true;
10556                }
10557                pw.println(String.format("%sIsolated #%2d: %s",
10558                        "    ", i, r.toString()));
10559            }
10560        }
10561
10562        if (mLruProcesses.size() > 0) {
10563            if (needSep) {
10564                pw.println();
10565            }
10566            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10567                    pw.print(" total, non-act at ");
10568                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10569                    pw.print(", non-svc at ");
10570                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10571                    pw.println("):");
10572            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10573            needSep = true;
10574            printedAnything = true;
10575        }
10576
10577        if (dumpAll || dumpPackage != null) {
10578            synchronized (mPidsSelfLocked) {
10579                boolean printed = false;
10580                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10581                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10582                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10583                        continue;
10584                    }
10585                    if (!printed) {
10586                        if (needSep) pw.println();
10587                        needSep = true;
10588                        pw.println("  PID mappings:");
10589                        printed = true;
10590                        printedAnything = true;
10591                    }
10592                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10593                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10594                }
10595            }
10596        }
10597
10598        if (mForegroundProcesses.size() > 0) {
10599            synchronized (mPidsSelfLocked) {
10600                boolean printed = false;
10601                for (int i=0; i<mForegroundProcesses.size(); i++) {
10602                    ProcessRecord r = mPidsSelfLocked.get(
10603                            mForegroundProcesses.valueAt(i).pid);
10604                    if (dumpPackage != null && (r == null
10605                            || !r.pkgList.containsKey(dumpPackage))) {
10606                        continue;
10607                    }
10608                    if (!printed) {
10609                        if (needSep) pw.println();
10610                        needSep = true;
10611                        pw.println("  Foreground Processes:");
10612                        printed = true;
10613                        printedAnything = true;
10614                    }
10615                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10616                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10617                }
10618            }
10619        }
10620
10621        if (mPersistentStartingProcesses.size() > 0) {
10622            if (needSep) pw.println();
10623            needSep = true;
10624            printedAnything = true;
10625            pw.println("  Persisent processes that are starting:");
10626            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10627                    "Starting Norm", "Restarting PERS", dumpPackage);
10628        }
10629
10630        if (mRemovedProcesses.size() > 0) {
10631            if (needSep) pw.println();
10632            needSep = true;
10633            printedAnything = true;
10634            pw.println("  Processes that are being removed:");
10635            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10636                    "Removed Norm", "Removed PERS", dumpPackage);
10637        }
10638
10639        if (mProcessesOnHold.size() > 0) {
10640            if (needSep) pw.println();
10641            needSep = true;
10642            printedAnything = true;
10643            pw.println("  Processes that are on old until the system is ready:");
10644            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10645                    "OnHold Norm", "OnHold PERS", dumpPackage);
10646        }
10647
10648        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10649
10650        if (mProcessCrashTimes.getMap().size() > 0) {
10651            boolean printed = false;
10652            long now = SystemClock.uptimeMillis();
10653            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10654            final int NP = pmap.size();
10655            for (int ip=0; ip<NP; ip++) {
10656                String pname = pmap.keyAt(ip);
10657                SparseArray<Long> uids = pmap.valueAt(ip);
10658                final int N = uids.size();
10659                for (int i=0; i<N; i++) {
10660                    int puid = uids.keyAt(i);
10661                    ProcessRecord r = mProcessNames.get(pname, puid);
10662                    if (dumpPackage != null && (r == null
10663                            || !r.pkgList.containsKey(dumpPackage))) {
10664                        continue;
10665                    }
10666                    if (!printed) {
10667                        if (needSep) pw.println();
10668                        needSep = true;
10669                        pw.println("  Time since processes crashed:");
10670                        printed = true;
10671                        printedAnything = true;
10672                    }
10673                    pw.print("    Process "); pw.print(pname);
10674                            pw.print(" uid "); pw.print(puid);
10675                            pw.print(": last crashed ");
10676                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10677                            pw.println(" ago");
10678                }
10679            }
10680        }
10681
10682        if (mBadProcesses.getMap().size() > 0) {
10683            boolean printed = false;
10684            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10685            final int NP = pmap.size();
10686            for (int ip=0; ip<NP; ip++) {
10687                String pname = pmap.keyAt(ip);
10688                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10689                final int N = uids.size();
10690                for (int i=0; i<N; i++) {
10691                    int puid = uids.keyAt(i);
10692                    ProcessRecord r = mProcessNames.get(pname, puid);
10693                    if (dumpPackage != null && (r == null
10694                            || !r.pkgList.containsKey(dumpPackage))) {
10695                        continue;
10696                    }
10697                    if (!printed) {
10698                        if (needSep) pw.println();
10699                        needSep = true;
10700                        pw.println("  Bad processes:");
10701                        printedAnything = true;
10702                    }
10703                    BadProcessInfo info = uids.valueAt(i);
10704                    pw.print("    Bad process "); pw.print(pname);
10705                            pw.print(" uid "); pw.print(puid);
10706                            pw.print(": crashed at time "); pw.println(info.time);
10707                    if (info.shortMsg != null) {
10708                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10709                    }
10710                    if (info.longMsg != null) {
10711                        pw.print("      Long msg: "); pw.println(info.longMsg);
10712                    }
10713                    if (info.stack != null) {
10714                        pw.println("      Stack:");
10715                        int lastPos = 0;
10716                        for (int pos=0; pos<info.stack.length(); pos++) {
10717                            if (info.stack.charAt(pos) == '\n') {
10718                                pw.print("        ");
10719                                pw.write(info.stack, lastPos, pos-lastPos);
10720                                pw.println();
10721                                lastPos = pos+1;
10722                            }
10723                        }
10724                        if (lastPos < info.stack.length()) {
10725                            pw.print("        ");
10726                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10727                            pw.println();
10728                        }
10729                    }
10730                }
10731            }
10732        }
10733
10734        if (dumpPackage == null) {
10735            pw.println();
10736            needSep = false;
10737            pw.println("  mStartedUsers:");
10738            for (int i=0; i<mStartedUsers.size(); i++) {
10739                UserStartedState uss = mStartedUsers.valueAt(i);
10740                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10741                        pw.print(": "); uss.dump("", pw);
10742            }
10743            pw.print("  mStartedUserArray: [");
10744            for (int i=0; i<mStartedUserArray.length; i++) {
10745                if (i > 0) pw.print(", ");
10746                pw.print(mStartedUserArray[i]);
10747            }
10748            pw.println("]");
10749            pw.print("  mUserLru: [");
10750            for (int i=0; i<mUserLru.size(); i++) {
10751                if (i > 0) pw.print(", ");
10752                pw.print(mUserLru.get(i));
10753            }
10754            pw.println("]");
10755            if (dumpAll) {
10756                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10757            }
10758        }
10759        if (mHomeProcess != null && (dumpPackage == null
10760                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10761            if (needSep) {
10762                pw.println();
10763                needSep = false;
10764            }
10765            pw.println("  mHomeProcess: " + mHomeProcess);
10766        }
10767        if (mPreviousProcess != null && (dumpPackage == null
10768                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10769            if (needSep) {
10770                pw.println();
10771                needSep = false;
10772            }
10773            pw.println("  mPreviousProcess: " + mPreviousProcess);
10774        }
10775        if (dumpAll) {
10776            StringBuilder sb = new StringBuilder(128);
10777            sb.append("  mPreviousProcessVisibleTime: ");
10778            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10779            pw.println(sb);
10780        }
10781        if (mHeavyWeightProcess != null && (dumpPackage == null
10782                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10783            if (needSep) {
10784                pw.println();
10785                needSep = false;
10786            }
10787            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10788        }
10789        if (dumpPackage == null) {
10790            pw.println("  mConfiguration: " + mConfiguration);
10791        }
10792        if (dumpAll) {
10793            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10794            if (mCompatModePackages.getPackages().size() > 0) {
10795                boolean printed = false;
10796                for (Map.Entry<String, Integer> entry
10797                        : mCompatModePackages.getPackages().entrySet()) {
10798                    String pkg = entry.getKey();
10799                    int mode = entry.getValue();
10800                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10801                        continue;
10802                    }
10803                    if (!printed) {
10804                        pw.println("  mScreenCompatPackages:");
10805                        printed = true;
10806                    }
10807                    pw.print("    "); pw.print(pkg); pw.print(": ");
10808                            pw.print(mode); pw.println();
10809                }
10810            }
10811        }
10812        if (dumpPackage == null) {
10813            if (mSleeping || mWentToSleep || mLockScreenShown) {
10814                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10815                        + " mLockScreenShown " + mLockScreenShown);
10816            }
10817            if (mShuttingDown) {
10818                pw.println("  mShuttingDown=" + mShuttingDown);
10819            }
10820        }
10821        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10822                || mOrigWaitForDebugger) {
10823            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10824                    || dumpPackage.equals(mOrigDebugApp)) {
10825                if (needSep) {
10826                    pw.println();
10827                    needSep = false;
10828                }
10829                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10830                        + " mDebugTransient=" + mDebugTransient
10831                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10832            }
10833        }
10834        if (mOpenGlTraceApp != null) {
10835            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10836                if (needSep) {
10837                    pw.println();
10838                    needSep = false;
10839                }
10840                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10841            }
10842        }
10843        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10844                || mProfileFd != null) {
10845            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10846                if (needSep) {
10847                    pw.println();
10848                    needSep = false;
10849                }
10850                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10851                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10852                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10853                        + mAutoStopProfiler);
10854            }
10855        }
10856        if (dumpPackage == null) {
10857            if (mAlwaysFinishActivities || mController != null) {
10858                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10859                        + " mController=" + mController);
10860            }
10861            if (dumpAll) {
10862                pw.println("  Total persistent processes: " + numPers);
10863                pw.println("  mProcessesReady=" + mProcessesReady
10864                        + " mSystemReady=" + mSystemReady);
10865                pw.println("  mBooting=" + mBooting
10866                        + " mBooted=" + mBooted
10867                        + " mFactoryTest=" + mFactoryTest);
10868                pw.print("  mLastPowerCheckRealtime=");
10869                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10870                        pw.println("");
10871                pw.print("  mLastPowerCheckUptime=");
10872                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10873                        pw.println("");
10874                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10875                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10876                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10877                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10878                        + " (" + mLruProcesses.size() + " total)"
10879                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10880                        + " mNumServiceProcs=" + mNumServiceProcs
10881                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10882                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10883                        + " mLastMemoryLevel" + mLastMemoryLevel
10884                        + " mLastNumProcesses" + mLastNumProcesses);
10885                long now = SystemClock.uptimeMillis();
10886                pw.print("  mLastIdleTime=");
10887                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10888                        pw.print(" mLowRamSinceLastIdle=");
10889                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10890                        pw.println();
10891            }
10892        }
10893
10894        if (!printedAnything) {
10895            pw.println("  (nothing)");
10896        }
10897    }
10898
10899    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10900            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10901        if (mProcessesToGc.size() > 0) {
10902            boolean printed = false;
10903            long now = SystemClock.uptimeMillis();
10904            for (int i=0; i<mProcessesToGc.size(); i++) {
10905                ProcessRecord proc = mProcessesToGc.get(i);
10906                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10907                    continue;
10908                }
10909                if (!printed) {
10910                    if (needSep) pw.println();
10911                    needSep = true;
10912                    pw.println("  Processes that are waiting to GC:");
10913                    printed = true;
10914                }
10915                pw.print("    Process "); pw.println(proc);
10916                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10917                        pw.print(", last gced=");
10918                        pw.print(now-proc.lastRequestedGc);
10919                        pw.print(" ms ago, last lowMem=");
10920                        pw.print(now-proc.lastLowMemory);
10921                        pw.println(" ms ago");
10922
10923            }
10924        }
10925        return needSep;
10926    }
10927
10928    void printOomLevel(PrintWriter pw, String name, int adj) {
10929        pw.print("    ");
10930        if (adj >= 0) {
10931            pw.print(' ');
10932            if (adj < 10) pw.print(' ');
10933        } else {
10934            if (adj > -10) pw.print(' ');
10935        }
10936        pw.print(adj);
10937        pw.print(": ");
10938        pw.print(name);
10939        pw.print(" (");
10940        pw.print(mProcessList.getMemLevel(adj)/1024);
10941        pw.println(" kB)");
10942    }
10943
10944    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10945            int opti, boolean dumpAll) {
10946        boolean needSep = false;
10947
10948        if (mLruProcesses.size() > 0) {
10949            if (needSep) pw.println();
10950            needSep = true;
10951            pw.println("  OOM levels:");
10952            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10953            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10954            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10955            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10956            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10957            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10958            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10959            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10960            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
10961            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
10962            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
10963            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
10964            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
10965
10966            if (needSep) pw.println();
10967            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
10968                    pw.print(" total, non-act at ");
10969                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10970                    pw.print(", non-svc at ");
10971                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10972                    pw.println("):");
10973            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
10974            needSep = true;
10975        }
10976
10977        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
10978
10979        pw.println();
10980        pw.println("  mHomeProcess: " + mHomeProcess);
10981        pw.println("  mPreviousProcess: " + mPreviousProcess);
10982        if (mHeavyWeightProcess != null) {
10983            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10984        }
10985
10986        return true;
10987    }
10988
10989    /**
10990     * There are three ways to call this:
10991     *  - no provider specified: dump all the providers
10992     *  - a flattened component name that matched an existing provider was specified as the
10993     *    first arg: dump that one provider
10994     *  - the first arg isn't the flattened component name of an existing provider:
10995     *    dump all providers whose component contains the first arg as a substring
10996     */
10997    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
10998            int opti, boolean dumpAll) {
10999        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11000    }
11001
11002    static class ItemMatcher {
11003        ArrayList<ComponentName> components;
11004        ArrayList<String> strings;
11005        ArrayList<Integer> objects;
11006        boolean all;
11007
11008        ItemMatcher() {
11009            all = true;
11010        }
11011
11012        void build(String name) {
11013            ComponentName componentName = ComponentName.unflattenFromString(name);
11014            if (componentName != null) {
11015                if (components == null) {
11016                    components = new ArrayList<ComponentName>();
11017                }
11018                components.add(componentName);
11019                all = false;
11020            } else {
11021                int objectId = 0;
11022                // Not a '/' separated full component name; maybe an object ID?
11023                try {
11024                    objectId = Integer.parseInt(name, 16);
11025                    if (objects == null) {
11026                        objects = new ArrayList<Integer>();
11027                    }
11028                    objects.add(objectId);
11029                    all = false;
11030                } catch (RuntimeException e) {
11031                    // Not an integer; just do string match.
11032                    if (strings == null) {
11033                        strings = new ArrayList<String>();
11034                    }
11035                    strings.add(name);
11036                    all = false;
11037                }
11038            }
11039        }
11040
11041        int build(String[] args, int opti) {
11042            for (; opti<args.length; opti++) {
11043                String name = args[opti];
11044                if ("--".equals(name)) {
11045                    return opti+1;
11046                }
11047                build(name);
11048            }
11049            return opti;
11050        }
11051
11052        boolean match(Object object, ComponentName comp) {
11053            if (all) {
11054                return true;
11055            }
11056            if (components != null) {
11057                for (int i=0; i<components.size(); i++) {
11058                    if (components.get(i).equals(comp)) {
11059                        return true;
11060                    }
11061                }
11062            }
11063            if (objects != null) {
11064                for (int i=0; i<objects.size(); i++) {
11065                    if (System.identityHashCode(object) == objects.get(i)) {
11066                        return true;
11067                    }
11068                }
11069            }
11070            if (strings != null) {
11071                String flat = comp.flattenToString();
11072                for (int i=0; i<strings.size(); i++) {
11073                    if (flat.contains(strings.get(i))) {
11074                        return true;
11075                    }
11076                }
11077            }
11078            return false;
11079        }
11080    }
11081
11082    /**
11083     * There are three things that cmd can be:
11084     *  - a flattened component name that matches an existing activity
11085     *  - the cmd arg isn't the flattened component name of an existing activity:
11086     *    dump all activity whose component contains the cmd as a substring
11087     *  - A hex number of the ActivityRecord object instance.
11088     */
11089    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11090            int opti, boolean dumpAll) {
11091        ArrayList<ActivityRecord> activities;
11092
11093        synchronized (this) {
11094            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11095        }
11096
11097        if (activities.size() <= 0) {
11098            return false;
11099        }
11100
11101        String[] newArgs = new String[args.length - opti];
11102        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11103
11104        TaskRecord lastTask = null;
11105        boolean needSep = false;
11106        for (int i=activities.size()-1; i>=0; i--) {
11107            ActivityRecord r = activities.get(i);
11108            if (needSep) {
11109                pw.println();
11110            }
11111            needSep = true;
11112            synchronized (this) {
11113                if (lastTask != r.task) {
11114                    lastTask = r.task;
11115                    pw.print("TASK "); pw.print(lastTask.affinity);
11116                            pw.print(" id="); pw.println(lastTask.taskId);
11117                    if (dumpAll) {
11118                        lastTask.dump(pw, "  ");
11119                    }
11120                }
11121            }
11122            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11123        }
11124        return true;
11125    }
11126
11127    /**
11128     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11129     * there is a thread associated with the activity.
11130     */
11131    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11132            final ActivityRecord r, String[] args, boolean dumpAll) {
11133        String innerPrefix = prefix + "  ";
11134        synchronized (this) {
11135            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11136                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11137                    pw.print(" pid=");
11138                    if (r.app != null) pw.println(r.app.pid);
11139                    else pw.println("(not running)");
11140            if (dumpAll) {
11141                r.dump(pw, innerPrefix);
11142            }
11143        }
11144        if (r.app != null && r.app.thread != null) {
11145            // flush anything that is already in the PrintWriter since the thread is going
11146            // to write to the file descriptor directly
11147            pw.flush();
11148            try {
11149                TransferPipe tp = new TransferPipe();
11150                try {
11151                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11152                            r.appToken, innerPrefix, args);
11153                    tp.go(fd);
11154                } finally {
11155                    tp.kill();
11156                }
11157            } catch (IOException e) {
11158                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11159            } catch (RemoteException e) {
11160                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11161            }
11162        }
11163    }
11164
11165    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11166            int opti, boolean dumpAll, String dumpPackage) {
11167        boolean needSep = false;
11168        boolean onlyHistory = false;
11169        boolean printedAnything = false;
11170
11171        if ("history".equals(dumpPackage)) {
11172            if (opti < args.length && "-s".equals(args[opti])) {
11173                dumpAll = false;
11174            }
11175            onlyHistory = true;
11176            dumpPackage = null;
11177        }
11178
11179        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11180        if (!onlyHistory && dumpAll) {
11181            if (mRegisteredReceivers.size() > 0) {
11182                boolean printed = false;
11183                Iterator it = mRegisteredReceivers.values().iterator();
11184                while (it.hasNext()) {
11185                    ReceiverList r = (ReceiverList)it.next();
11186                    if (dumpPackage != null && (r.app == null ||
11187                            !dumpPackage.equals(r.app.info.packageName))) {
11188                        continue;
11189                    }
11190                    if (!printed) {
11191                        pw.println("  Registered Receivers:");
11192                        needSep = true;
11193                        printed = true;
11194                        printedAnything = true;
11195                    }
11196                    pw.print("  * "); pw.println(r);
11197                    r.dump(pw, "    ");
11198                }
11199            }
11200
11201            if (mReceiverResolver.dump(pw, needSep ?
11202                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11203                    "    ", dumpPackage, false)) {
11204                needSep = true;
11205                printedAnything = true;
11206            }
11207        }
11208
11209        for (BroadcastQueue q : mBroadcastQueues) {
11210            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11211            printedAnything |= needSep;
11212        }
11213
11214        needSep = true;
11215
11216        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11217            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11218                if (needSep) {
11219                    pw.println();
11220                }
11221                needSep = true;
11222                printedAnything = true;
11223                pw.print("  Sticky broadcasts for user ");
11224                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11225                StringBuilder sb = new StringBuilder(128);
11226                for (Map.Entry<String, ArrayList<Intent>> ent
11227                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11228                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11229                    if (dumpAll) {
11230                        pw.println(":");
11231                        ArrayList<Intent> intents = ent.getValue();
11232                        final int N = intents.size();
11233                        for (int i=0; i<N; i++) {
11234                            sb.setLength(0);
11235                            sb.append("    Intent: ");
11236                            intents.get(i).toShortString(sb, false, true, false, false);
11237                            pw.println(sb.toString());
11238                            Bundle bundle = intents.get(i).getExtras();
11239                            if (bundle != null) {
11240                                pw.print("      ");
11241                                pw.println(bundle.toString());
11242                            }
11243                        }
11244                    } else {
11245                        pw.println("");
11246                    }
11247                }
11248            }
11249        }
11250
11251        if (!onlyHistory && dumpAll) {
11252            pw.println();
11253            for (BroadcastQueue queue : mBroadcastQueues) {
11254                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11255                        + queue.mBroadcastsScheduled);
11256            }
11257            pw.println("  mHandler:");
11258            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11259            needSep = true;
11260            printedAnything = true;
11261        }
11262
11263        if (!printedAnything) {
11264            pw.println("  (nothing)");
11265        }
11266    }
11267
11268    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11269            int opti, boolean dumpAll, String dumpPackage) {
11270        boolean needSep;
11271        boolean printedAnything = false;
11272
11273        ItemMatcher matcher = new ItemMatcher();
11274        matcher.build(args, opti);
11275
11276        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11277
11278        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11279        printedAnything |= needSep;
11280
11281        if (mLaunchingProviders.size() > 0) {
11282            boolean printed = false;
11283            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11284                ContentProviderRecord r = mLaunchingProviders.get(i);
11285                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11286                    continue;
11287                }
11288                if (!printed) {
11289                    if (needSep) pw.println();
11290                    needSep = true;
11291                    pw.println("  Launching content providers:");
11292                    printed = true;
11293                    printedAnything = true;
11294                }
11295                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11296                        pw.println(r);
11297            }
11298        }
11299
11300        if (mGrantedUriPermissions.size() > 0) {
11301            boolean printed = false;
11302            int dumpUid = -2;
11303            if (dumpPackage != null) {
11304                try {
11305                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11306                } catch (NameNotFoundException e) {
11307                    dumpUid = -1;
11308                }
11309            }
11310            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11311                int uid = mGrantedUriPermissions.keyAt(i);
11312                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11313                    continue;
11314                }
11315                ArrayMap<Uri, UriPermission> perms
11316                        = mGrantedUriPermissions.valueAt(i);
11317                if (!printed) {
11318                    if (needSep) pw.println();
11319                    needSep = true;
11320                    pw.println("  Granted Uri Permissions:");
11321                    printed = true;
11322                    printedAnything = true;
11323                }
11324                pw.print("  * UID "); pw.print(uid);
11325                        pw.println(" holds:");
11326                for (UriPermission perm : perms.values()) {
11327                    pw.print("    "); pw.println(perm);
11328                    if (dumpAll) {
11329                        perm.dump(pw, "      ");
11330                    }
11331                }
11332            }
11333        }
11334
11335        if (!printedAnything) {
11336            pw.println("  (nothing)");
11337        }
11338    }
11339
11340    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11341            int opti, boolean dumpAll, String dumpPackage) {
11342        boolean printed = false;
11343
11344        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11345
11346        if (mIntentSenderRecords.size() > 0) {
11347            Iterator<WeakReference<PendingIntentRecord>> it
11348                    = mIntentSenderRecords.values().iterator();
11349            while (it.hasNext()) {
11350                WeakReference<PendingIntentRecord> ref = it.next();
11351                PendingIntentRecord rec = ref != null ? ref.get(): null;
11352                if (dumpPackage != null && (rec == null
11353                        || !dumpPackage.equals(rec.key.packageName))) {
11354                    continue;
11355                }
11356                printed = true;
11357                if (rec != null) {
11358                    pw.print("  * "); pw.println(rec);
11359                    if (dumpAll) {
11360                        rec.dump(pw, "    ");
11361                    }
11362                } else {
11363                    pw.print("  * "); pw.println(ref);
11364                }
11365            }
11366        }
11367
11368        if (!printed) {
11369            pw.println("  (nothing)");
11370        }
11371    }
11372
11373    private static final int dumpProcessList(PrintWriter pw,
11374            ActivityManagerService service, List list,
11375            String prefix, String normalLabel, String persistentLabel,
11376            String dumpPackage) {
11377        int numPers = 0;
11378        final int N = list.size()-1;
11379        for (int i=N; i>=0; i--) {
11380            ProcessRecord r = (ProcessRecord)list.get(i);
11381            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11382                continue;
11383            }
11384            pw.println(String.format("%s%s #%2d: %s",
11385                    prefix, (r.persistent ? persistentLabel : normalLabel),
11386                    i, r.toString()));
11387            if (r.persistent) {
11388                numPers++;
11389            }
11390        }
11391        return numPers;
11392    }
11393
11394    private static final boolean dumpProcessOomList(PrintWriter pw,
11395            ActivityManagerService service, List<ProcessRecord> origList,
11396            String prefix, String normalLabel, String persistentLabel,
11397            boolean inclDetails, String dumpPackage) {
11398
11399        ArrayList<Pair<ProcessRecord, Integer>> list
11400                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11401        for (int i=0; i<origList.size(); i++) {
11402            ProcessRecord r = origList.get(i);
11403            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11404                continue;
11405            }
11406            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11407        }
11408
11409        if (list.size() <= 0) {
11410            return false;
11411        }
11412
11413        Comparator<Pair<ProcessRecord, Integer>> comparator
11414                = new Comparator<Pair<ProcessRecord, Integer>>() {
11415            @Override
11416            public int compare(Pair<ProcessRecord, Integer> object1,
11417                    Pair<ProcessRecord, Integer> object2) {
11418                if (object1.first.setAdj != object2.first.setAdj) {
11419                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11420                }
11421                if (object1.second.intValue() != object2.second.intValue()) {
11422                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11423                }
11424                return 0;
11425            }
11426        };
11427
11428        Collections.sort(list, comparator);
11429
11430        final long curRealtime = SystemClock.elapsedRealtime();
11431        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11432        final long curUptime = SystemClock.uptimeMillis();
11433        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11434
11435        for (int i=list.size()-1; i>=0; i--) {
11436            ProcessRecord r = list.get(i).first;
11437            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11438            char schedGroup;
11439            switch (r.setSchedGroup) {
11440                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11441                    schedGroup = 'B';
11442                    break;
11443                case Process.THREAD_GROUP_DEFAULT:
11444                    schedGroup = 'F';
11445                    break;
11446                default:
11447                    schedGroup = '?';
11448                    break;
11449            }
11450            char foreground;
11451            if (r.foregroundActivities) {
11452                foreground = 'A';
11453            } else if (r.foregroundServices) {
11454                foreground = 'S';
11455            } else {
11456                foreground = ' ';
11457            }
11458            String procState = ProcessList.makeProcStateString(r.curProcState);
11459            pw.print(prefix);
11460            pw.print(r.persistent ? persistentLabel : normalLabel);
11461            pw.print(" #");
11462            int num = (origList.size()-1)-list.get(i).second;
11463            if (num < 10) pw.print(' ');
11464            pw.print(num);
11465            pw.print(": ");
11466            pw.print(oomAdj);
11467            pw.print(' ');
11468            pw.print(schedGroup);
11469            pw.print('/');
11470            pw.print(foreground);
11471            pw.print('/');
11472            pw.print(procState);
11473            pw.print(" trm:");
11474            if (r.trimMemoryLevel < 10) pw.print(' ');
11475            pw.print(r.trimMemoryLevel);
11476            pw.print(' ');
11477            pw.print(r.toShortString());
11478            pw.print(" (");
11479            pw.print(r.adjType);
11480            pw.println(')');
11481            if (r.adjSource != null || r.adjTarget != null) {
11482                pw.print(prefix);
11483                pw.print("    ");
11484                if (r.adjTarget instanceof ComponentName) {
11485                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11486                } else if (r.adjTarget != null) {
11487                    pw.print(r.adjTarget.toString());
11488                } else {
11489                    pw.print("{null}");
11490                }
11491                pw.print("<=");
11492                if (r.adjSource instanceof ProcessRecord) {
11493                    pw.print("Proc{");
11494                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11495                    pw.println("}");
11496                } else if (r.adjSource != null) {
11497                    pw.println(r.adjSource.toString());
11498                } else {
11499                    pw.println("{null}");
11500                }
11501            }
11502            if (inclDetails) {
11503                pw.print(prefix);
11504                pw.print("    ");
11505                pw.print("oom: max="); pw.print(r.maxAdj);
11506                pw.print(" curRaw="); pw.print(r.curRawAdj);
11507                pw.print(" setRaw="); pw.print(r.setRawAdj);
11508                pw.print(" cur="); pw.print(r.curAdj);
11509                pw.print(" set="); pw.println(r.setAdj);
11510                pw.print(prefix);
11511                pw.print("    ");
11512                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11513                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11514                pw.print(" lastPss="); pw.print(r.lastPss);
11515                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11516                pw.print(prefix);
11517                pw.print("    ");
11518                pw.print("keeping="); pw.print(r.keeping);
11519                pw.print(" cached="); pw.print(r.cached);
11520                pw.print(" empty="); pw.print(r.empty);
11521                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11522
11523                if (!r.keeping) {
11524                    if (r.lastWakeTime != 0) {
11525                        long wtime;
11526                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11527                        synchronized (stats) {
11528                            wtime = stats.getProcessWakeTime(r.info.uid,
11529                                    r.pid, curRealtime);
11530                        }
11531                        long timeUsed = wtime - r.lastWakeTime;
11532                        pw.print(prefix);
11533                        pw.print("    ");
11534                        pw.print("keep awake over ");
11535                        TimeUtils.formatDuration(realtimeSince, pw);
11536                        pw.print(" used ");
11537                        TimeUtils.formatDuration(timeUsed, pw);
11538                        pw.print(" (");
11539                        pw.print((timeUsed*100)/realtimeSince);
11540                        pw.println("%)");
11541                    }
11542                    if (r.lastCpuTime != 0) {
11543                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11544                        pw.print(prefix);
11545                        pw.print("    ");
11546                        pw.print("run cpu over ");
11547                        TimeUtils.formatDuration(uptimeSince, pw);
11548                        pw.print(" used ");
11549                        TimeUtils.formatDuration(timeUsed, pw);
11550                        pw.print(" (");
11551                        pw.print((timeUsed*100)/uptimeSince);
11552                        pw.println("%)");
11553                    }
11554                }
11555            }
11556        }
11557        return true;
11558    }
11559
11560    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11561        ArrayList<ProcessRecord> procs;
11562        synchronized (this) {
11563            if (args != null && args.length > start
11564                    && args[start].charAt(0) != '-') {
11565                procs = new ArrayList<ProcessRecord>();
11566                int pid = -1;
11567                try {
11568                    pid = Integer.parseInt(args[start]);
11569                } catch (NumberFormatException e) {
11570                }
11571                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11572                    ProcessRecord proc = mLruProcesses.get(i);
11573                    if (proc.pid == pid) {
11574                        procs.add(proc);
11575                    } else if (proc.processName.equals(args[start])) {
11576                        procs.add(proc);
11577                    }
11578                }
11579                if (procs.size() <= 0) {
11580                    return null;
11581                }
11582            } else {
11583                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11584            }
11585        }
11586        return procs;
11587    }
11588
11589    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11590            PrintWriter pw, String[] args) {
11591        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11592        if (procs == null) {
11593            pw.println("No process found for: " + args[0]);
11594            return;
11595        }
11596
11597        long uptime = SystemClock.uptimeMillis();
11598        long realtime = SystemClock.elapsedRealtime();
11599        pw.println("Applications Graphics Acceleration Info:");
11600        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11601
11602        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11603            ProcessRecord r = procs.get(i);
11604            if (r.thread != null) {
11605                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11606                pw.flush();
11607                try {
11608                    TransferPipe tp = new TransferPipe();
11609                    try {
11610                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11611                        tp.go(fd);
11612                    } finally {
11613                        tp.kill();
11614                    }
11615                } catch (IOException e) {
11616                    pw.println("Failure while dumping the app: " + r);
11617                    pw.flush();
11618                } catch (RemoteException e) {
11619                    pw.println("Got a RemoteException while dumping the app " + r);
11620                    pw.flush();
11621                }
11622            }
11623        }
11624    }
11625
11626    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11627        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11628        if (procs == null) {
11629            pw.println("No process found for: " + args[0]);
11630            return;
11631        }
11632
11633        pw.println("Applications Database Info:");
11634
11635        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11636            ProcessRecord r = procs.get(i);
11637            if (r.thread != null) {
11638                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11639                pw.flush();
11640                try {
11641                    TransferPipe tp = new TransferPipe();
11642                    try {
11643                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11644                        tp.go(fd);
11645                    } finally {
11646                        tp.kill();
11647                    }
11648                } catch (IOException e) {
11649                    pw.println("Failure while dumping the app: " + r);
11650                    pw.flush();
11651                } catch (RemoteException e) {
11652                    pw.println("Got a RemoteException while dumping the app " + r);
11653                    pw.flush();
11654                }
11655            }
11656        }
11657    }
11658
11659    final static class MemItem {
11660        final boolean isProc;
11661        final String label;
11662        final String shortLabel;
11663        final long pss;
11664        final int id;
11665        final boolean hasActivities;
11666        ArrayList<MemItem> subitems;
11667
11668        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11669                boolean _hasActivities) {
11670            isProc = true;
11671            label = _label;
11672            shortLabel = _shortLabel;
11673            pss = _pss;
11674            id = _id;
11675            hasActivities = _hasActivities;
11676        }
11677
11678        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11679            isProc = false;
11680            label = _label;
11681            shortLabel = _shortLabel;
11682            pss = _pss;
11683            id = _id;
11684            hasActivities = false;
11685        }
11686    }
11687
11688    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11689            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11690        if (sort && !isCompact) {
11691            Collections.sort(items, new Comparator<MemItem>() {
11692                @Override
11693                public int compare(MemItem lhs, MemItem rhs) {
11694                    if (lhs.pss < rhs.pss) {
11695                        return 1;
11696                    } else if (lhs.pss > rhs.pss) {
11697                        return -1;
11698                    }
11699                    return 0;
11700                }
11701            });
11702        }
11703
11704        for (int i=0; i<items.size(); i++) {
11705            MemItem mi = items.get(i);
11706            if (!isCompact) {
11707                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11708            } else if (mi.isProc) {
11709                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11710                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11711                pw.println(mi.hasActivities ? ",a" : ",e");
11712            } else {
11713                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11714                pw.println(mi.pss);
11715            }
11716            if (mi.subitems != null) {
11717                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11718                        true, isCompact);
11719            }
11720        }
11721    }
11722
11723    // These are in KB.
11724    static final long[] DUMP_MEM_BUCKETS = new long[] {
11725        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11726        120*1024, 160*1024, 200*1024,
11727        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11728        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11729    };
11730
11731    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11732            boolean stackLike) {
11733        int start = label.lastIndexOf('.');
11734        if (start >= 0) start++;
11735        else start = 0;
11736        int end = label.length();
11737        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11738            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11739                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11740                out.append(bucket);
11741                out.append(stackLike ? "MB." : "MB ");
11742                out.append(label, start, end);
11743                return;
11744            }
11745        }
11746        out.append(memKB/1024);
11747        out.append(stackLike ? "MB." : "MB ");
11748        out.append(label, start, end);
11749    }
11750
11751    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11752            ProcessList.NATIVE_ADJ,
11753            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11754            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11755            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11756            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11757            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11758    };
11759    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11760            "Native",
11761            "System", "Persistent", "Foreground",
11762            "Visible", "Perceptible",
11763            "Heavy Weight", "Backup",
11764            "A Services", "Home",
11765            "Previous", "B Services", "Cached"
11766    };
11767    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11768            "native",
11769            "sys", "pers", "fore",
11770            "vis", "percept",
11771            "heavy", "backup",
11772            "servicea", "home",
11773            "prev", "serviceb", "cached"
11774    };
11775
11776    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11777            long realtime, boolean isCheckinRequest, boolean isCompact) {
11778        if (isCheckinRequest || isCompact) {
11779            // short checkin version
11780            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11781        } else {
11782            pw.println("Applications Memory Usage (kB):");
11783            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11784        }
11785    }
11786
11787    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11788            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11789        boolean dumpDetails = false;
11790        boolean dumpFullDetails = false;
11791        boolean dumpDalvik = false;
11792        boolean oomOnly = false;
11793        boolean isCompact = false;
11794        boolean localOnly = false;
11795
11796        int opti = 0;
11797        while (opti < args.length) {
11798            String opt = args[opti];
11799            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11800                break;
11801            }
11802            opti++;
11803            if ("-a".equals(opt)) {
11804                dumpDetails = true;
11805                dumpFullDetails = true;
11806                dumpDalvik = true;
11807            } else if ("-d".equals(opt)) {
11808                dumpDalvik = true;
11809            } else if ("-c".equals(opt)) {
11810                isCompact = true;
11811            } else if ("--oom".equals(opt)) {
11812                oomOnly = true;
11813            } else if ("--local".equals(opt)) {
11814                localOnly = true;
11815            } else if ("-h".equals(opt)) {
11816                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11817                pw.println("  -a: include all available information for each process.");
11818                pw.println("  -d: include dalvik details when dumping process details.");
11819                pw.println("  -c: dump in a compact machine-parseable representation.");
11820                pw.println("  --oom: only show processes organized by oom adj.");
11821                pw.println("  --local: only collect details locally, don't call process.");
11822                pw.println("If [process] is specified it can be the name or ");
11823                pw.println("pid of a specific process to dump.");
11824                return;
11825            } else {
11826                pw.println("Unknown argument: " + opt + "; use -h for help");
11827            }
11828        }
11829
11830        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11831        long uptime = SystemClock.uptimeMillis();
11832        long realtime = SystemClock.elapsedRealtime();
11833        final long[] tmpLong = new long[1];
11834
11835        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11836        if (procs == null) {
11837            // No Java processes.  Maybe they want to print a native process.
11838            if (args != null && args.length > opti
11839                    && args[opti].charAt(0) != '-') {
11840                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11841                        = new ArrayList<ProcessCpuTracker.Stats>();
11842                updateCpuStatsNow();
11843                int findPid = -1;
11844                try {
11845                    findPid = Integer.parseInt(args[opti]);
11846                } catch (NumberFormatException e) {
11847                }
11848                synchronized (mProcessCpuThread) {
11849                    final int N = mProcessCpuTracker.countStats();
11850                    for (int i=0; i<N; i++) {
11851                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11852                        if (st.pid == findPid || (st.baseName != null
11853                                && st.baseName.equals(args[opti]))) {
11854                            nativeProcs.add(st);
11855                        }
11856                    }
11857                }
11858                if (nativeProcs.size() > 0) {
11859                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11860                            isCompact);
11861                    Debug.MemoryInfo mi = null;
11862                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11863                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11864                        final int pid = r.pid;
11865                        if (!isCheckinRequest && dumpDetails) {
11866                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11867                        }
11868                        if (mi == null) {
11869                            mi = new Debug.MemoryInfo();
11870                        }
11871                        if (dumpDetails || (!brief && !oomOnly)) {
11872                            Debug.getMemoryInfo(pid, mi);
11873                        } else {
11874                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11875                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11876                        }
11877                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11878                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11879                        if (isCheckinRequest) {
11880                            pw.println();
11881                        }
11882                    }
11883                    return;
11884                }
11885            }
11886            pw.println("No process found for: " + args[opti]);
11887            return;
11888        }
11889
11890        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11891            dumpDetails = true;
11892        }
11893
11894        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11895
11896        String[] innerArgs = new String[args.length-opti];
11897        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11898
11899        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11900        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11901        long nativePss=0, dalvikPss=0, otherPss=0;
11902        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11903
11904        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11905        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11906                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11907
11908        long totalPss = 0;
11909        long cachedPss = 0;
11910
11911        Debug.MemoryInfo mi = null;
11912        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11913            final ProcessRecord r = procs.get(i);
11914            final IApplicationThread thread;
11915            final int pid;
11916            final int oomAdj;
11917            final boolean hasActivities;
11918            synchronized (this) {
11919                thread = r.thread;
11920                pid = r.pid;
11921                oomAdj = r.getSetAdjWithServices();
11922                hasActivities = r.activities.size() > 0;
11923            }
11924            if (thread != null) {
11925                if (!isCheckinRequest && dumpDetails) {
11926                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11927                }
11928                if (mi == null) {
11929                    mi = new Debug.MemoryInfo();
11930                }
11931                if (dumpDetails || (!brief && !oomOnly)) {
11932                    Debug.getMemoryInfo(pid, mi);
11933                } else {
11934                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11935                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11936                }
11937                if (dumpDetails) {
11938                    if (localOnly) {
11939                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11940                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11941                        if (isCheckinRequest) {
11942                            pw.println();
11943                        }
11944                    } else {
11945                        try {
11946                            pw.flush();
11947                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11948                                    dumpDalvik, innerArgs);
11949                        } catch (RemoteException e) {
11950                            if (!isCheckinRequest) {
11951                                pw.println("Got RemoteException!");
11952                                pw.flush();
11953                            }
11954                        }
11955                    }
11956                }
11957
11958                final long myTotalPss = mi.getTotalPss();
11959                final long myTotalUss = mi.getTotalUss();
11960
11961                synchronized (this) {
11962                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
11963                        // Record this for posterity if the process has been stable.
11964                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
11965                    }
11966                }
11967
11968                if (!isCheckinRequest && mi != null) {
11969                    totalPss += myTotalPss;
11970                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
11971                            (hasActivities ? " / activities)" : ")"),
11972                            r.processName, myTotalPss, pid, hasActivities);
11973                    procMems.add(pssItem);
11974                    procMemsMap.put(pid, pssItem);
11975
11976                    nativePss += mi.nativePss;
11977                    dalvikPss += mi.dalvikPss;
11978                    otherPss += mi.otherPss;
11979                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
11980                        long mem = mi.getOtherPss(j);
11981                        miscPss[j] += mem;
11982                        otherPss -= mem;
11983                    }
11984
11985                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
11986                        cachedPss += myTotalPss;
11987                    }
11988
11989                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
11990                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
11991                                || oomIndex == (oomPss.length-1)) {
11992                            oomPss[oomIndex] += myTotalPss;
11993                            if (oomProcs[oomIndex] == null) {
11994                                oomProcs[oomIndex] = new ArrayList<MemItem>();
11995                            }
11996                            oomProcs[oomIndex].add(pssItem);
11997                            break;
11998                        }
11999                    }
12000                }
12001            }
12002        }
12003
12004        if (!isCheckinRequest && procs.size() > 1) {
12005            // If we are showing aggregations, also look for native processes to
12006            // include so that our aggregations are more accurate.
12007            updateCpuStatsNow();
12008            synchronized (mProcessCpuThread) {
12009                final int N = mProcessCpuTracker.countStats();
12010                for (int i=0; i<N; i++) {
12011                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12012                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12013                        if (mi == null) {
12014                            mi = new Debug.MemoryInfo();
12015                        }
12016                        if (!brief && !oomOnly) {
12017                            Debug.getMemoryInfo(st.pid, mi);
12018                        } else {
12019                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12020                            mi.nativePrivateDirty = (int)tmpLong[0];
12021                        }
12022
12023                        final long myTotalPss = mi.getTotalPss();
12024                        totalPss += myTotalPss;
12025
12026                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12027                                st.name, myTotalPss, st.pid, false);
12028                        procMems.add(pssItem);
12029
12030                        nativePss += mi.nativePss;
12031                        dalvikPss += mi.dalvikPss;
12032                        otherPss += mi.otherPss;
12033                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12034                            long mem = mi.getOtherPss(j);
12035                            miscPss[j] += mem;
12036                            otherPss -= mem;
12037                        }
12038                        oomPss[0] += myTotalPss;
12039                        if (oomProcs[0] == null) {
12040                            oomProcs[0] = new ArrayList<MemItem>();
12041                        }
12042                        oomProcs[0].add(pssItem);
12043                    }
12044                }
12045            }
12046
12047            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12048
12049            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12050            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12051            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12052            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12053                String label = Debug.MemoryInfo.getOtherLabel(j);
12054                catMems.add(new MemItem(label, label, miscPss[j], j));
12055            }
12056
12057            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12058            for (int j=0; j<oomPss.length; j++) {
12059                if (oomPss[j] != 0) {
12060                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12061                            : DUMP_MEM_OOM_LABEL[j];
12062                    MemItem item = new MemItem(label, label, oomPss[j],
12063                            DUMP_MEM_OOM_ADJ[j]);
12064                    item.subitems = oomProcs[j];
12065                    oomMems.add(item);
12066                }
12067            }
12068
12069            if (!brief && !oomOnly && !isCompact) {
12070                pw.println();
12071                pw.println("Total PSS by process:");
12072                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12073                pw.println();
12074            }
12075            if (!isCompact) {
12076                pw.println("Total PSS by OOM adjustment:");
12077            }
12078            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12079            if (!brief && !oomOnly) {
12080                PrintWriter out = categoryPw != null ? categoryPw : pw;
12081                if (!isCompact) {
12082                    out.println();
12083                    out.println("Total PSS by category:");
12084                }
12085                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12086            }
12087            if (!isCompact) {
12088                pw.println();
12089            }
12090            MemInfoReader memInfo = new MemInfoReader();
12091            memInfo.readMemInfo();
12092            if (!brief) {
12093                if (!isCompact) {
12094                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12095                    pw.println(" kB");
12096                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12097                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12098                            pw.print(cachedPss); pw.print(" cached pss + ");
12099                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12100                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12101                } else {
12102                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12103                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12104                            + memInfo.getFreeSizeKb()); pw.print(",");
12105                    pw.println(totalPss - cachedPss);
12106                }
12107            }
12108            if (!isCompact) {
12109                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12110                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12111                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12112                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12113                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12114                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12115                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12116                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12117                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12118                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12119                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12120            }
12121            if (!brief) {
12122                if (memInfo.getZramTotalSizeKb() != 0) {
12123                    if (!isCompact) {
12124                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12125                                pw.print(" kB physical used for ");
12126                                pw.print(memInfo.getSwapTotalSizeKb()
12127                                        - memInfo.getSwapFreeSizeKb());
12128                                pw.print(" kB in swap (");
12129                                pw.print(memInfo.getSwapTotalSizeKb());
12130                                pw.println(" kB total swap)");
12131                    } else {
12132                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12133                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12134                                pw.println(memInfo.getSwapFreeSizeKb());
12135                    }
12136                }
12137                final int[] SINGLE_LONG_FORMAT = new int[] {
12138                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12139                };
12140                long[] longOut = new long[1];
12141                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12142                        SINGLE_LONG_FORMAT, null, longOut, null);
12143                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12144                longOut[0] = 0;
12145                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12146                        SINGLE_LONG_FORMAT, null, longOut, null);
12147                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12148                longOut[0] = 0;
12149                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12150                        SINGLE_LONG_FORMAT, null, longOut, null);
12151                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12152                longOut[0] = 0;
12153                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12154                        SINGLE_LONG_FORMAT, null, longOut, null);
12155                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12156                if (!isCompact) {
12157                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12158                        pw.print("      KSM: "); pw.print(sharing);
12159                                pw.print(" kB saved from shared ");
12160                                pw.print(shared); pw.println(" kB");
12161                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12162                                pw.print(voltile); pw.println(" kB volatile");
12163                    }
12164                    pw.print("   Tuning: ");
12165                    pw.print(ActivityManager.staticGetMemoryClass());
12166                    pw.print(" (large ");
12167                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12168                    pw.print("), oom ");
12169                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12170                    pw.print(" kB");
12171                    pw.print(", restore limit ");
12172                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12173                    pw.print(" kB");
12174                    if (ActivityManager.isLowRamDeviceStatic()) {
12175                        pw.print(" (low-ram)");
12176                    }
12177                    if (ActivityManager.isHighEndGfx()) {
12178                        pw.print(" (high-end-gfx)");
12179                    }
12180                    pw.println();
12181                } else {
12182                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12183                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12184                    pw.println(voltile);
12185                    pw.print("tuning,");
12186                    pw.print(ActivityManager.staticGetMemoryClass());
12187                    pw.print(',');
12188                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12189                    pw.print(',');
12190                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12191                    if (ActivityManager.isLowRamDeviceStatic()) {
12192                        pw.print(",low-ram");
12193                    }
12194                    if (ActivityManager.isHighEndGfx()) {
12195                        pw.print(",high-end-gfx");
12196                    }
12197                    pw.println();
12198                }
12199            }
12200        }
12201    }
12202
12203    /**
12204     * Searches array of arguments for the specified string
12205     * @param args array of argument strings
12206     * @param value value to search for
12207     * @return true if the value is contained in the array
12208     */
12209    private static boolean scanArgs(String[] args, String value) {
12210        if (args != null) {
12211            for (String arg : args) {
12212                if (value.equals(arg)) {
12213                    return true;
12214                }
12215            }
12216        }
12217        return false;
12218    }
12219
12220    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12221            ContentProviderRecord cpr, boolean always) {
12222        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12223
12224        if (!inLaunching || always) {
12225            synchronized (cpr) {
12226                cpr.launchingApp = null;
12227                cpr.notifyAll();
12228            }
12229            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12230            String names[] = cpr.info.authority.split(";");
12231            for (int j = 0; j < names.length; j++) {
12232                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12233            }
12234        }
12235
12236        for (int i=0; i<cpr.connections.size(); i++) {
12237            ContentProviderConnection conn = cpr.connections.get(i);
12238            if (conn.waiting) {
12239                // If this connection is waiting for the provider, then we don't
12240                // need to mess with its process unless we are always removing
12241                // or for some reason the provider is not currently launching.
12242                if (inLaunching && !always) {
12243                    continue;
12244                }
12245            }
12246            ProcessRecord capp = conn.client;
12247            conn.dead = true;
12248            if (conn.stableCount > 0) {
12249                if (!capp.persistent && capp.thread != null
12250                        && capp.pid != 0
12251                        && capp.pid != MY_PID) {
12252                    killUnneededProcessLocked(capp, "depends on provider "
12253                            + cpr.name.flattenToShortString()
12254                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12255                }
12256            } else if (capp.thread != null && conn.provider.provider != null) {
12257                try {
12258                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12259                } catch (RemoteException e) {
12260                }
12261                // In the protocol here, we don't expect the client to correctly
12262                // clean up this connection, we'll just remove it.
12263                cpr.connections.remove(i);
12264                conn.client.conProviders.remove(conn);
12265            }
12266        }
12267
12268        if (inLaunching && always) {
12269            mLaunchingProviders.remove(cpr);
12270        }
12271        return inLaunching;
12272    }
12273
12274    /**
12275     * Main code for cleaning up a process when it has gone away.  This is
12276     * called both as a result of the process dying, or directly when stopping
12277     * a process when running in single process mode.
12278     */
12279    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12280            boolean restarting, boolean allowRestart, int index) {
12281        if (index >= 0) {
12282            removeLruProcessLocked(app);
12283            ProcessList.remove(app.pid);
12284        }
12285
12286        mProcessesToGc.remove(app);
12287        mPendingPssProcesses.remove(app);
12288
12289        // Dismiss any open dialogs.
12290        if (app.crashDialog != null && !app.forceCrashReport) {
12291            app.crashDialog.dismiss();
12292            app.crashDialog = null;
12293        }
12294        if (app.anrDialog != null) {
12295            app.anrDialog.dismiss();
12296            app.anrDialog = null;
12297        }
12298        if (app.waitDialog != null) {
12299            app.waitDialog.dismiss();
12300            app.waitDialog = null;
12301        }
12302
12303        app.crashing = false;
12304        app.notResponding = false;
12305
12306        app.resetPackageList(mProcessStats);
12307        app.unlinkDeathRecipient();
12308        app.makeInactive(mProcessStats);
12309        app.forcingToForeground = null;
12310        app.foregroundServices = false;
12311        app.foregroundActivities = false;
12312        app.hasShownUi = false;
12313        app.hasAboveClient = false;
12314
12315        mServices.killServicesLocked(app, allowRestart);
12316
12317        boolean restart = false;
12318
12319        // Remove published content providers.
12320        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12321            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12322            final boolean always = app.bad || !allowRestart;
12323            if (removeDyingProviderLocked(app, cpr, always) || always) {
12324                // We left the provider in the launching list, need to
12325                // restart it.
12326                restart = true;
12327            }
12328
12329            cpr.provider = null;
12330            cpr.proc = null;
12331        }
12332        app.pubProviders.clear();
12333
12334        // Take care of any launching providers waiting for this process.
12335        if (checkAppInLaunchingProvidersLocked(app, false)) {
12336            restart = true;
12337        }
12338
12339        // Unregister from connected content providers.
12340        if (!app.conProviders.isEmpty()) {
12341            for (int i=0; i<app.conProviders.size(); i++) {
12342                ContentProviderConnection conn = app.conProviders.get(i);
12343                conn.provider.connections.remove(conn);
12344            }
12345            app.conProviders.clear();
12346        }
12347
12348        // At this point there may be remaining entries in mLaunchingProviders
12349        // where we were the only one waiting, so they are no longer of use.
12350        // Look for these and clean up if found.
12351        // XXX Commented out for now.  Trying to figure out a way to reproduce
12352        // the actual situation to identify what is actually going on.
12353        if (false) {
12354            for (int i=0; i<mLaunchingProviders.size(); i++) {
12355                ContentProviderRecord cpr = (ContentProviderRecord)
12356                        mLaunchingProviders.get(i);
12357                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12358                    synchronized (cpr) {
12359                        cpr.launchingApp = null;
12360                        cpr.notifyAll();
12361                    }
12362                }
12363            }
12364        }
12365
12366        skipCurrentReceiverLocked(app);
12367
12368        // Unregister any receivers.
12369        for (int i=app.receivers.size()-1; i>=0; i--) {
12370            removeReceiverLocked(app.receivers.valueAt(i));
12371        }
12372        app.receivers.clear();
12373
12374        // If the app is undergoing backup, tell the backup manager about it
12375        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12376            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12377                    + mBackupTarget.appInfo + " died during backup");
12378            try {
12379                IBackupManager bm = IBackupManager.Stub.asInterface(
12380                        ServiceManager.getService(Context.BACKUP_SERVICE));
12381                bm.agentDisconnected(app.info.packageName);
12382            } catch (RemoteException e) {
12383                // can't happen; backup manager is local
12384            }
12385        }
12386
12387        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12388            ProcessChangeItem item = mPendingProcessChanges.get(i);
12389            if (item.pid == app.pid) {
12390                mPendingProcessChanges.remove(i);
12391                mAvailProcessChanges.add(item);
12392            }
12393        }
12394        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12395
12396        // If the caller is restarting this app, then leave it in its
12397        // current lists and let the caller take care of it.
12398        if (restarting) {
12399            return;
12400        }
12401
12402        if (!app.persistent || app.isolated) {
12403            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12404                    "Removing non-persistent process during cleanup: " + app);
12405            mProcessNames.remove(app.processName, app.uid);
12406            mIsolatedProcesses.remove(app.uid);
12407            if (mHeavyWeightProcess == app) {
12408                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12409                        mHeavyWeightProcess.userId, 0));
12410                mHeavyWeightProcess = null;
12411            }
12412        } else if (!app.removed) {
12413            // This app is persistent, so we need to keep its record around.
12414            // If it is not already on the pending app list, add it there
12415            // and start a new process for it.
12416            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12417                mPersistentStartingProcesses.add(app);
12418                restart = true;
12419            }
12420        }
12421        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12422                "Clean-up removing on hold: " + app);
12423        mProcessesOnHold.remove(app);
12424
12425        if (app == mHomeProcess) {
12426            mHomeProcess = null;
12427        }
12428        if (app == mPreviousProcess) {
12429            mPreviousProcess = null;
12430        }
12431
12432        if (restart && !app.isolated) {
12433            // We have components that still need to be running in the
12434            // process, so re-launch it.
12435            mProcessNames.put(app.processName, app.uid, app);
12436            startProcessLocked(app, "restart", app.processName);
12437        } else if (app.pid > 0 && app.pid != MY_PID) {
12438            // Goodbye!
12439            synchronized (mPidsSelfLocked) {
12440                mPidsSelfLocked.remove(app.pid);
12441                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12442            }
12443            app.setPid(0);
12444        }
12445    }
12446
12447    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12448        // Look through the content providers we are waiting to have launched,
12449        // and if any run in this process then either schedule a restart of
12450        // the process or kill the client waiting for it if this process has
12451        // gone bad.
12452        int NL = mLaunchingProviders.size();
12453        boolean restart = false;
12454        for (int i=0; i<NL; i++) {
12455            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12456            if (cpr.launchingApp == app) {
12457                if (!alwaysBad && !app.bad) {
12458                    restart = true;
12459                } else {
12460                    removeDyingProviderLocked(app, cpr, true);
12461                    // cpr should have been removed from mLaunchingProviders
12462                    NL = mLaunchingProviders.size();
12463                    i--;
12464                }
12465            }
12466        }
12467        return restart;
12468    }
12469
12470    // =========================================================
12471    // SERVICES
12472    // =========================================================
12473
12474    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12475            int flags) {
12476        enforceNotIsolatedCaller("getServices");
12477        synchronized (this) {
12478            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12479        }
12480    }
12481
12482    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12483        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12484        synchronized (this) {
12485            return mServices.getRunningServiceControlPanelLocked(name);
12486        }
12487    }
12488
12489    public ComponentName startService(IApplicationThread caller, Intent service,
12490            String resolvedType, int userId) {
12491        enforceNotIsolatedCaller("startService");
12492        // Refuse possible leaked file descriptors
12493        if (service != null && service.hasFileDescriptors() == true) {
12494            throw new IllegalArgumentException("File descriptors passed in Intent");
12495        }
12496
12497        if (DEBUG_SERVICE)
12498            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12499        synchronized(this) {
12500            final int callingPid = Binder.getCallingPid();
12501            final int callingUid = Binder.getCallingUid();
12502            final long origId = Binder.clearCallingIdentity();
12503            ComponentName res = mServices.startServiceLocked(caller, service,
12504                    resolvedType, callingPid, callingUid, userId);
12505            Binder.restoreCallingIdentity(origId);
12506            return res;
12507        }
12508    }
12509
12510    ComponentName startServiceInPackage(int uid,
12511            Intent service, String resolvedType, int userId) {
12512        synchronized(this) {
12513            if (DEBUG_SERVICE)
12514                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12515            final long origId = Binder.clearCallingIdentity();
12516            ComponentName res = mServices.startServiceLocked(null, service,
12517                    resolvedType, -1, uid, userId);
12518            Binder.restoreCallingIdentity(origId);
12519            return res;
12520        }
12521    }
12522
12523    public int stopService(IApplicationThread caller, Intent service,
12524            String resolvedType, int userId) {
12525        enforceNotIsolatedCaller("stopService");
12526        // Refuse possible leaked file descriptors
12527        if (service != null && service.hasFileDescriptors() == true) {
12528            throw new IllegalArgumentException("File descriptors passed in Intent");
12529        }
12530
12531        synchronized(this) {
12532            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12533        }
12534    }
12535
12536    public IBinder peekService(Intent service, String resolvedType) {
12537        enforceNotIsolatedCaller("peekService");
12538        // Refuse possible leaked file descriptors
12539        if (service != null && service.hasFileDescriptors() == true) {
12540            throw new IllegalArgumentException("File descriptors passed in Intent");
12541        }
12542        synchronized(this) {
12543            return mServices.peekServiceLocked(service, resolvedType);
12544        }
12545    }
12546
12547    public boolean stopServiceToken(ComponentName className, IBinder token,
12548            int startId) {
12549        synchronized(this) {
12550            return mServices.stopServiceTokenLocked(className, token, startId);
12551        }
12552    }
12553
12554    public void setServiceForeground(ComponentName className, IBinder token,
12555            int id, Notification notification, boolean removeNotification) {
12556        synchronized(this) {
12557            mServices.setServiceForegroundLocked(className, token, id, notification,
12558                    removeNotification);
12559        }
12560    }
12561
12562    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12563            boolean requireFull, String name, String callerPackage) {
12564        final int callingUserId = UserHandle.getUserId(callingUid);
12565        if (callingUserId != userId) {
12566            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12567                if ((requireFull || checkComponentPermission(
12568                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12569                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12570                        && checkComponentPermission(
12571                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12572                                callingPid, callingUid, -1, true)
12573                                != PackageManager.PERMISSION_GRANTED) {
12574                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12575                        // In this case, they would like to just execute as their
12576                        // owner user instead of failing.
12577                        userId = callingUserId;
12578                    } else {
12579                        StringBuilder builder = new StringBuilder(128);
12580                        builder.append("Permission Denial: ");
12581                        builder.append(name);
12582                        if (callerPackage != null) {
12583                            builder.append(" from ");
12584                            builder.append(callerPackage);
12585                        }
12586                        builder.append(" asks to run as user ");
12587                        builder.append(userId);
12588                        builder.append(" but is calling from user ");
12589                        builder.append(UserHandle.getUserId(callingUid));
12590                        builder.append("; this requires ");
12591                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12592                        if (!requireFull) {
12593                            builder.append(" or ");
12594                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12595                        }
12596                        String msg = builder.toString();
12597                        Slog.w(TAG, msg);
12598                        throw new SecurityException(msg);
12599                    }
12600                }
12601            }
12602            if (userId == UserHandle.USER_CURRENT
12603                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12604                // Note that we may be accessing this outside of a lock...
12605                // shouldn't be a big deal, if this is being called outside
12606                // of a locked context there is intrinsically a race with
12607                // the value the caller will receive and someone else changing it.
12608                userId = mCurrentUserId;
12609            }
12610            if (!allowAll && userId < 0) {
12611                throw new IllegalArgumentException(
12612                        "Call does not support special user #" + userId);
12613            }
12614        }
12615        return userId;
12616    }
12617
12618    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12619            String className, int flags) {
12620        boolean result = false;
12621        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12622            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12623                if (ActivityManager.checkUidPermission(
12624                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12625                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12626                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12627                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12628                            + " requests FLAG_SINGLE_USER, but app does not hold "
12629                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12630                    Slog.w(TAG, msg);
12631                    throw new SecurityException(msg);
12632                }
12633                result = true;
12634            }
12635        } else if (componentProcessName == aInfo.packageName) {
12636            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12637        } else if ("system".equals(componentProcessName)) {
12638            result = true;
12639        }
12640        if (DEBUG_MU) {
12641            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12642                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12643        }
12644        return result;
12645    }
12646
12647    public int bindService(IApplicationThread caller, IBinder token,
12648            Intent service, String resolvedType,
12649            IServiceConnection connection, int flags, int userId) {
12650        enforceNotIsolatedCaller("bindService");
12651        // Refuse possible leaked file descriptors
12652        if (service != null && service.hasFileDescriptors() == true) {
12653            throw new IllegalArgumentException("File descriptors passed in Intent");
12654        }
12655
12656        synchronized(this) {
12657            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12658                    connection, flags, userId);
12659        }
12660    }
12661
12662    public boolean unbindService(IServiceConnection connection) {
12663        synchronized (this) {
12664            return mServices.unbindServiceLocked(connection);
12665        }
12666    }
12667
12668    public void publishService(IBinder token, Intent intent, IBinder service) {
12669        // Refuse possible leaked file descriptors
12670        if (intent != null && intent.hasFileDescriptors() == true) {
12671            throw new IllegalArgumentException("File descriptors passed in Intent");
12672        }
12673
12674        synchronized(this) {
12675            if (!(token instanceof ServiceRecord)) {
12676                throw new IllegalArgumentException("Invalid service token");
12677            }
12678            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12679        }
12680    }
12681
12682    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12683        // Refuse possible leaked file descriptors
12684        if (intent != null && intent.hasFileDescriptors() == true) {
12685            throw new IllegalArgumentException("File descriptors passed in Intent");
12686        }
12687
12688        synchronized(this) {
12689            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12690        }
12691    }
12692
12693    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12694        synchronized(this) {
12695            if (!(token instanceof ServiceRecord)) {
12696                throw new IllegalArgumentException("Invalid service token");
12697            }
12698            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12699        }
12700    }
12701
12702    // =========================================================
12703    // BACKUP AND RESTORE
12704    // =========================================================
12705
12706    // Cause the target app to be launched if necessary and its backup agent
12707    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12708    // activity manager to announce its creation.
12709    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12710        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12711        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12712
12713        synchronized(this) {
12714            // !!! TODO: currently no check here that we're already bound
12715            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12716            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12717            synchronized (stats) {
12718                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12719            }
12720
12721            // Backup agent is now in use, its package can't be stopped.
12722            try {
12723                AppGlobals.getPackageManager().setPackageStoppedState(
12724                        app.packageName, false, UserHandle.getUserId(app.uid));
12725            } catch (RemoteException e) {
12726            } catch (IllegalArgumentException e) {
12727                Slog.w(TAG, "Failed trying to unstop package "
12728                        + app.packageName + ": " + e);
12729            }
12730
12731            BackupRecord r = new BackupRecord(ss, app, backupMode);
12732            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12733                    ? new ComponentName(app.packageName, app.backupAgentName)
12734                    : new ComponentName("android", "FullBackupAgent");
12735            // startProcessLocked() returns existing proc's record if it's already running
12736            ProcessRecord proc = startProcessLocked(app.processName, app,
12737                    false, 0, "backup", hostingName, false, false, false);
12738            if (proc == null) {
12739                Slog.e(TAG, "Unable to start backup agent process " + r);
12740                return false;
12741            }
12742
12743            r.app = proc;
12744            mBackupTarget = r;
12745            mBackupAppName = app.packageName;
12746
12747            // Try not to kill the process during backup
12748            updateOomAdjLocked(proc);
12749
12750            // If the process is already attached, schedule the creation of the backup agent now.
12751            // If it is not yet live, this will be done when it attaches to the framework.
12752            if (proc.thread != null) {
12753                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12754                try {
12755                    proc.thread.scheduleCreateBackupAgent(app,
12756                            compatibilityInfoForPackageLocked(app), backupMode);
12757                } catch (RemoteException e) {
12758                    // Will time out on the backup manager side
12759                }
12760            } else {
12761                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12762            }
12763            // Invariants: at this point, the target app process exists and the application
12764            // is either already running or in the process of coming up.  mBackupTarget and
12765            // mBackupAppName describe the app, so that when it binds back to the AM we
12766            // know that it's scheduled for a backup-agent operation.
12767        }
12768
12769        return true;
12770    }
12771
12772    @Override
12773    public void clearPendingBackup() {
12774        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12775        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12776
12777        synchronized (this) {
12778            mBackupTarget = null;
12779            mBackupAppName = null;
12780        }
12781    }
12782
12783    // A backup agent has just come up
12784    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12785        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12786                + " = " + agent);
12787
12788        synchronized(this) {
12789            if (!agentPackageName.equals(mBackupAppName)) {
12790                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12791                return;
12792            }
12793        }
12794
12795        long oldIdent = Binder.clearCallingIdentity();
12796        try {
12797            IBackupManager bm = IBackupManager.Stub.asInterface(
12798                    ServiceManager.getService(Context.BACKUP_SERVICE));
12799            bm.agentConnected(agentPackageName, agent);
12800        } catch (RemoteException e) {
12801            // can't happen; the backup manager service is local
12802        } catch (Exception e) {
12803            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12804            e.printStackTrace();
12805        } finally {
12806            Binder.restoreCallingIdentity(oldIdent);
12807        }
12808    }
12809
12810    // done with this agent
12811    public void unbindBackupAgent(ApplicationInfo appInfo) {
12812        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12813        if (appInfo == null) {
12814            Slog.w(TAG, "unbind backup agent for null app");
12815            return;
12816        }
12817
12818        synchronized(this) {
12819            try {
12820                if (mBackupAppName == null) {
12821                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12822                    return;
12823                }
12824
12825                if (!mBackupAppName.equals(appInfo.packageName)) {
12826                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12827                    return;
12828                }
12829
12830                // Not backing this app up any more; reset its OOM adjustment
12831                final ProcessRecord proc = mBackupTarget.app;
12832                updateOomAdjLocked(proc);
12833
12834                // If the app crashed during backup, 'thread' will be null here
12835                if (proc.thread != null) {
12836                    try {
12837                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12838                                compatibilityInfoForPackageLocked(appInfo));
12839                    } catch (Exception e) {
12840                        Slog.e(TAG, "Exception when unbinding backup agent:");
12841                        e.printStackTrace();
12842                    }
12843                }
12844            } finally {
12845                mBackupTarget = null;
12846                mBackupAppName = null;
12847            }
12848        }
12849    }
12850    // =========================================================
12851    // BROADCASTS
12852    // =========================================================
12853
12854    private final List getStickiesLocked(String action, IntentFilter filter,
12855            List cur, int userId) {
12856        final ContentResolver resolver = mContext.getContentResolver();
12857        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12858        if (stickies == null) {
12859            return cur;
12860        }
12861        final ArrayList<Intent> list = stickies.get(action);
12862        if (list == null) {
12863            return cur;
12864        }
12865        int N = list.size();
12866        for (int i=0; i<N; i++) {
12867            Intent intent = list.get(i);
12868            if (filter.match(resolver, intent, true, TAG) >= 0) {
12869                if (cur == null) {
12870                    cur = new ArrayList<Intent>();
12871                }
12872                cur.add(intent);
12873            }
12874        }
12875        return cur;
12876    }
12877
12878    boolean isPendingBroadcastProcessLocked(int pid) {
12879        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12880                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12881    }
12882
12883    void skipPendingBroadcastLocked(int pid) {
12884            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12885            for (BroadcastQueue queue : mBroadcastQueues) {
12886                queue.skipPendingBroadcastLocked(pid);
12887            }
12888    }
12889
12890    // The app just attached; send any pending broadcasts that it should receive
12891    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12892        boolean didSomething = false;
12893        for (BroadcastQueue queue : mBroadcastQueues) {
12894            didSomething |= queue.sendPendingBroadcastsLocked(app);
12895        }
12896        return didSomething;
12897    }
12898
12899    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12900            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12901        enforceNotIsolatedCaller("registerReceiver");
12902        int callingUid;
12903        int callingPid;
12904        synchronized(this) {
12905            ProcessRecord callerApp = null;
12906            if (caller != null) {
12907                callerApp = getRecordForAppLocked(caller);
12908                if (callerApp == null) {
12909                    throw new SecurityException(
12910                            "Unable to find app for caller " + caller
12911                            + " (pid=" + Binder.getCallingPid()
12912                            + ") when registering receiver " + receiver);
12913                }
12914                if (callerApp.info.uid != Process.SYSTEM_UID &&
12915                        !callerApp.pkgList.containsKey(callerPackage) &&
12916                        !"android".equals(callerPackage)) {
12917                    throw new SecurityException("Given caller package " + callerPackage
12918                            + " is not running in process " + callerApp);
12919                }
12920                callingUid = callerApp.info.uid;
12921                callingPid = callerApp.pid;
12922            } else {
12923                callerPackage = null;
12924                callingUid = Binder.getCallingUid();
12925                callingPid = Binder.getCallingPid();
12926            }
12927
12928            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12929                    true, true, "registerReceiver", callerPackage);
12930
12931            List allSticky = null;
12932
12933            // Look for any matching sticky broadcasts...
12934            Iterator actions = filter.actionsIterator();
12935            if (actions != null) {
12936                while (actions.hasNext()) {
12937                    String action = (String)actions.next();
12938                    allSticky = getStickiesLocked(action, filter, allSticky,
12939                            UserHandle.USER_ALL);
12940                    allSticky = getStickiesLocked(action, filter, allSticky,
12941                            UserHandle.getUserId(callingUid));
12942                }
12943            } else {
12944                allSticky = getStickiesLocked(null, filter, allSticky,
12945                        UserHandle.USER_ALL);
12946                allSticky = getStickiesLocked(null, filter, allSticky,
12947                        UserHandle.getUserId(callingUid));
12948            }
12949
12950            // The first sticky in the list is returned directly back to
12951            // the client.
12952            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12953
12954            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12955                    + ": " + sticky);
12956
12957            if (receiver == null) {
12958                return sticky;
12959            }
12960
12961            ReceiverList rl
12962                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12963            if (rl == null) {
12964                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
12965                        userId, receiver);
12966                if (rl.app != null) {
12967                    rl.app.receivers.add(rl);
12968                } else {
12969                    try {
12970                        receiver.asBinder().linkToDeath(rl, 0);
12971                    } catch (RemoteException e) {
12972                        return sticky;
12973                    }
12974                    rl.linkedToDeath = true;
12975                }
12976                mRegisteredReceivers.put(receiver.asBinder(), rl);
12977            } else if (rl.uid != callingUid) {
12978                throw new IllegalArgumentException(
12979                        "Receiver requested to register for uid " + callingUid
12980                        + " was previously registered for uid " + rl.uid);
12981            } else if (rl.pid != callingPid) {
12982                throw new IllegalArgumentException(
12983                        "Receiver requested to register for pid " + callingPid
12984                        + " was previously registered for pid " + rl.pid);
12985            } else if (rl.userId != userId) {
12986                throw new IllegalArgumentException(
12987                        "Receiver requested to register for user " + userId
12988                        + " was previously registered for user " + rl.userId);
12989            }
12990            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
12991                    permission, callingUid, userId);
12992            rl.add(bf);
12993            if (!bf.debugCheck()) {
12994                Slog.w(TAG, "==> For Dynamic broadast");
12995            }
12996            mReceiverResolver.addFilter(bf);
12997
12998            // Enqueue broadcasts for all existing stickies that match
12999            // this filter.
13000            if (allSticky != null) {
13001                ArrayList receivers = new ArrayList();
13002                receivers.add(bf);
13003
13004                int N = allSticky.size();
13005                for (int i=0; i<N; i++) {
13006                    Intent intent = (Intent)allSticky.get(i);
13007                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13008                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13009                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13010                            null, null, false, true, true, -1);
13011                    queue.enqueueParallelBroadcastLocked(r);
13012                    queue.scheduleBroadcastsLocked();
13013                }
13014            }
13015
13016            return sticky;
13017        }
13018    }
13019
13020    public void unregisterReceiver(IIntentReceiver receiver) {
13021        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13022
13023        final long origId = Binder.clearCallingIdentity();
13024        try {
13025            boolean doTrim = false;
13026
13027            synchronized(this) {
13028                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13029                if (rl != null) {
13030                    if (rl.curBroadcast != null) {
13031                        BroadcastRecord r = rl.curBroadcast;
13032                        final boolean doNext = finishReceiverLocked(
13033                                receiver.asBinder(), r.resultCode, r.resultData,
13034                                r.resultExtras, r.resultAbort);
13035                        if (doNext) {
13036                            doTrim = true;
13037                            r.queue.processNextBroadcast(false);
13038                        }
13039                    }
13040
13041                    if (rl.app != null) {
13042                        rl.app.receivers.remove(rl);
13043                    }
13044                    removeReceiverLocked(rl);
13045                    if (rl.linkedToDeath) {
13046                        rl.linkedToDeath = false;
13047                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13048                    }
13049                }
13050            }
13051
13052            // If we actually concluded any broadcasts, we might now be able
13053            // to trim the recipients' apps from our working set
13054            if (doTrim) {
13055                trimApplications();
13056                return;
13057            }
13058
13059        } finally {
13060            Binder.restoreCallingIdentity(origId);
13061        }
13062    }
13063
13064    void removeReceiverLocked(ReceiverList rl) {
13065        mRegisteredReceivers.remove(rl.receiver.asBinder());
13066        int N = rl.size();
13067        for (int i=0; i<N; i++) {
13068            mReceiverResolver.removeFilter(rl.get(i));
13069        }
13070    }
13071
13072    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13073        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13074            ProcessRecord r = mLruProcesses.get(i);
13075            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13076                try {
13077                    r.thread.dispatchPackageBroadcast(cmd, packages);
13078                } catch (RemoteException ex) {
13079                }
13080            }
13081        }
13082    }
13083
13084    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13085            int[] users) {
13086        List<ResolveInfo> receivers = null;
13087        try {
13088            HashSet<ComponentName> singleUserReceivers = null;
13089            boolean scannedFirstReceivers = false;
13090            for (int user : users) {
13091                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13092                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13093                if (user != 0 && newReceivers != null) {
13094                    // If this is not the primary user, we need to check for
13095                    // any receivers that should be filtered out.
13096                    for (int i=0; i<newReceivers.size(); i++) {
13097                        ResolveInfo ri = newReceivers.get(i);
13098                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13099                            newReceivers.remove(i);
13100                            i--;
13101                        }
13102                    }
13103                }
13104                if (newReceivers != null && newReceivers.size() == 0) {
13105                    newReceivers = null;
13106                }
13107                if (receivers == null) {
13108                    receivers = newReceivers;
13109                } else if (newReceivers != null) {
13110                    // We need to concatenate the additional receivers
13111                    // found with what we have do far.  This would be easy,
13112                    // but we also need to de-dup any receivers that are
13113                    // singleUser.
13114                    if (!scannedFirstReceivers) {
13115                        // Collect any single user receivers we had already retrieved.
13116                        scannedFirstReceivers = true;
13117                        for (int i=0; i<receivers.size(); i++) {
13118                            ResolveInfo ri = receivers.get(i);
13119                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13120                                ComponentName cn = new ComponentName(
13121                                        ri.activityInfo.packageName, ri.activityInfo.name);
13122                                if (singleUserReceivers == null) {
13123                                    singleUserReceivers = new HashSet<ComponentName>();
13124                                }
13125                                singleUserReceivers.add(cn);
13126                            }
13127                        }
13128                    }
13129                    // Add the new results to the existing results, tracking
13130                    // and de-dupping single user receivers.
13131                    for (int i=0; i<newReceivers.size(); i++) {
13132                        ResolveInfo ri = newReceivers.get(i);
13133                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13134                            ComponentName cn = new ComponentName(
13135                                    ri.activityInfo.packageName, ri.activityInfo.name);
13136                            if (singleUserReceivers == null) {
13137                                singleUserReceivers = new HashSet<ComponentName>();
13138                            }
13139                            if (!singleUserReceivers.contains(cn)) {
13140                                singleUserReceivers.add(cn);
13141                                receivers.add(ri);
13142                            }
13143                        } else {
13144                            receivers.add(ri);
13145                        }
13146                    }
13147                }
13148            }
13149        } catch (RemoteException ex) {
13150            // pm is in same process, this will never happen.
13151        }
13152        return receivers;
13153    }
13154
13155    private final int broadcastIntentLocked(ProcessRecord callerApp,
13156            String callerPackage, Intent intent, String resolvedType,
13157            IIntentReceiver resultTo, int resultCode, String resultData,
13158            Bundle map, String requiredPermission, int appOp,
13159            boolean ordered, boolean sticky, int callingPid, int callingUid,
13160            int userId) {
13161        intent = new Intent(intent);
13162
13163        // By default broadcasts do not go to stopped apps.
13164        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13165
13166        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13167            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13168            + " ordered=" + ordered + " userid=" + userId);
13169        if ((resultTo != null) && !ordered) {
13170            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13171        }
13172
13173        userId = handleIncomingUser(callingPid, callingUid, userId,
13174                true, false, "broadcast", callerPackage);
13175
13176        // Make sure that the user who is receiving this broadcast is started.
13177        // If not, we will just skip it.
13178        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13179            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13180                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13181                Slog.w(TAG, "Skipping broadcast of " + intent
13182                        + ": user " + userId + " is stopped");
13183                return ActivityManager.BROADCAST_SUCCESS;
13184            }
13185        }
13186
13187        /*
13188         * Prevent non-system code (defined here to be non-persistent
13189         * processes) from sending protected broadcasts.
13190         */
13191        int callingAppId = UserHandle.getAppId(callingUid);
13192        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13193            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13194            callingUid == 0) {
13195            // Always okay.
13196        } else if (callerApp == null || !callerApp.persistent) {
13197            try {
13198                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13199                        intent.getAction())) {
13200                    String msg = "Permission Denial: not allowed to send broadcast "
13201                            + intent.getAction() + " from pid="
13202                            + callingPid + ", uid=" + callingUid;
13203                    Slog.w(TAG, msg);
13204                    throw new SecurityException(msg);
13205                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13206                    // Special case for compatibility: we don't want apps to send this,
13207                    // but historically it has not been protected and apps may be using it
13208                    // to poke their own app widget.  So, instead of making it protected,
13209                    // just limit it to the caller.
13210                    if (callerApp == null) {
13211                        String msg = "Permission Denial: not allowed to send broadcast "
13212                                + intent.getAction() + " from unknown caller.";
13213                        Slog.w(TAG, msg);
13214                        throw new SecurityException(msg);
13215                    } else if (intent.getComponent() != null) {
13216                        // They are good enough to send to an explicit component...  verify
13217                        // it is being sent to the calling app.
13218                        if (!intent.getComponent().getPackageName().equals(
13219                                callerApp.info.packageName)) {
13220                            String msg = "Permission Denial: not allowed to send broadcast "
13221                                    + intent.getAction() + " to "
13222                                    + intent.getComponent().getPackageName() + " from "
13223                                    + callerApp.info.packageName;
13224                            Slog.w(TAG, msg);
13225                            throw new SecurityException(msg);
13226                        }
13227                    } else {
13228                        // Limit broadcast to their own package.
13229                        intent.setPackage(callerApp.info.packageName);
13230                    }
13231                }
13232            } catch (RemoteException e) {
13233                Slog.w(TAG, "Remote exception", e);
13234                return ActivityManager.BROADCAST_SUCCESS;
13235            }
13236        }
13237
13238        // Handle special intents: if this broadcast is from the package
13239        // manager about a package being removed, we need to remove all of
13240        // its activities from the history stack.
13241        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13242                intent.getAction());
13243        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13244                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13245                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13246                || uidRemoved) {
13247            if (checkComponentPermission(
13248                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13249                    callingPid, callingUid, -1, true)
13250                    == PackageManager.PERMISSION_GRANTED) {
13251                if (uidRemoved) {
13252                    final Bundle intentExtras = intent.getExtras();
13253                    final int uid = intentExtras != null
13254                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13255                    if (uid >= 0) {
13256                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13257                        synchronized (bs) {
13258                            bs.removeUidStatsLocked(uid);
13259                        }
13260                        mAppOpsService.uidRemoved(uid);
13261                    }
13262                } else {
13263                    // If resources are unavailable just force stop all
13264                    // those packages and flush the attribute cache as well.
13265                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13266                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13267                        if (list != null && (list.length > 0)) {
13268                            for (String pkg : list) {
13269                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
13270                                        "storage unmount");
13271                            }
13272                            sendPackageBroadcastLocked(
13273                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13274                        }
13275                    } else {
13276                        Uri data = intent.getData();
13277                        String ssp;
13278                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13279                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13280                                    intent.getAction());
13281                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13282                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13283                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13284                                        false, userId, removed ? "pkg removed" : "pkg changed");
13285                            }
13286                            if (removed) {
13287                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13288                                        new String[] {ssp}, userId);
13289                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13290                                    mAppOpsService.packageRemoved(
13291                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13292
13293                                    // Remove all permissions granted from/to this package
13294                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13295                                }
13296                            }
13297                        }
13298                    }
13299                }
13300            } else {
13301                String msg = "Permission Denial: " + intent.getAction()
13302                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13303                        + ", uid=" + callingUid + ")"
13304                        + " requires "
13305                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13306                Slog.w(TAG, msg);
13307                throw new SecurityException(msg);
13308            }
13309
13310        // Special case for adding a package: by default turn on compatibility
13311        // mode.
13312        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13313            Uri data = intent.getData();
13314            String ssp;
13315            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13316                mCompatModePackages.handlePackageAddedLocked(ssp,
13317                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13318            }
13319        }
13320
13321        /*
13322         * If this is the time zone changed action, queue up a message that will reset the timezone
13323         * of all currently running processes. This message will get queued up before the broadcast
13324         * happens.
13325         */
13326        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13327            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13328        }
13329
13330        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13331            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13332        }
13333
13334        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13335            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13336            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13337        }
13338
13339        // Add to the sticky list if requested.
13340        if (sticky) {
13341            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13342                    callingPid, callingUid)
13343                    != PackageManager.PERMISSION_GRANTED) {
13344                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13345                        + callingPid + ", uid=" + callingUid
13346                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13347                Slog.w(TAG, msg);
13348                throw new SecurityException(msg);
13349            }
13350            if (requiredPermission != null) {
13351                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13352                        + " and enforce permission " + requiredPermission);
13353                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13354            }
13355            if (intent.getComponent() != null) {
13356                throw new SecurityException(
13357                        "Sticky broadcasts can't target a specific component");
13358            }
13359            // We use userId directly here, since the "all" target is maintained
13360            // as a separate set of sticky broadcasts.
13361            if (userId != UserHandle.USER_ALL) {
13362                // But first, if this is not a broadcast to all users, then
13363                // make sure it doesn't conflict with an existing broadcast to
13364                // all users.
13365                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13366                        UserHandle.USER_ALL);
13367                if (stickies != null) {
13368                    ArrayList<Intent> list = stickies.get(intent.getAction());
13369                    if (list != null) {
13370                        int N = list.size();
13371                        int i;
13372                        for (i=0; i<N; i++) {
13373                            if (intent.filterEquals(list.get(i))) {
13374                                throw new IllegalArgumentException(
13375                                        "Sticky broadcast " + intent + " for user "
13376                                        + userId + " conflicts with existing global broadcast");
13377                            }
13378                        }
13379                    }
13380                }
13381            }
13382            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13383            if (stickies == null) {
13384                stickies = new ArrayMap<String, ArrayList<Intent>>();
13385                mStickyBroadcasts.put(userId, stickies);
13386            }
13387            ArrayList<Intent> list = stickies.get(intent.getAction());
13388            if (list == null) {
13389                list = new ArrayList<Intent>();
13390                stickies.put(intent.getAction(), list);
13391            }
13392            int N = list.size();
13393            int i;
13394            for (i=0; i<N; i++) {
13395                if (intent.filterEquals(list.get(i))) {
13396                    // This sticky already exists, replace it.
13397                    list.set(i, new Intent(intent));
13398                    break;
13399                }
13400            }
13401            if (i >= N) {
13402                list.add(new Intent(intent));
13403            }
13404        }
13405
13406        int[] users;
13407        if (userId == UserHandle.USER_ALL) {
13408            // Caller wants broadcast to go to all started users.
13409            users = mStartedUserArray;
13410        } else {
13411            // Caller wants broadcast to go to one specific user.
13412            users = new int[] {userId};
13413        }
13414
13415        // Figure out who all will receive this broadcast.
13416        List receivers = null;
13417        List<BroadcastFilter> registeredReceivers = null;
13418        // Need to resolve the intent to interested receivers...
13419        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13420                 == 0) {
13421            receivers = collectReceiverComponents(intent, resolvedType, users);
13422        }
13423        if (intent.getComponent() == null) {
13424            registeredReceivers = mReceiverResolver.queryIntent(intent,
13425                    resolvedType, false, userId);
13426        }
13427
13428        final boolean replacePending =
13429                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13430
13431        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13432                + " replacePending=" + replacePending);
13433
13434        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13435        if (!ordered && NR > 0) {
13436            // If we are not serializing this broadcast, then send the
13437            // registered receivers separately so they don't wait for the
13438            // components to be launched.
13439            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13440            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13441                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13442                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13443                    ordered, sticky, false, userId);
13444            if (DEBUG_BROADCAST) Slog.v(
13445                    TAG, "Enqueueing parallel broadcast " + r);
13446            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13447            if (!replaced) {
13448                queue.enqueueParallelBroadcastLocked(r);
13449                queue.scheduleBroadcastsLocked();
13450            }
13451            registeredReceivers = null;
13452            NR = 0;
13453        }
13454
13455        // Merge into one list.
13456        int ir = 0;
13457        if (receivers != null) {
13458            // A special case for PACKAGE_ADDED: do not allow the package
13459            // being added to see this broadcast.  This prevents them from
13460            // using this as a back door to get run as soon as they are
13461            // installed.  Maybe in the future we want to have a special install
13462            // broadcast or such for apps, but we'd like to deliberately make
13463            // this decision.
13464            String skipPackages[] = null;
13465            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13466                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13467                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13468                Uri data = intent.getData();
13469                if (data != null) {
13470                    String pkgName = data.getSchemeSpecificPart();
13471                    if (pkgName != null) {
13472                        skipPackages = new String[] { pkgName };
13473                    }
13474                }
13475            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13476                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13477            }
13478            if (skipPackages != null && (skipPackages.length > 0)) {
13479                for (String skipPackage : skipPackages) {
13480                    if (skipPackage != null) {
13481                        int NT = receivers.size();
13482                        for (int it=0; it<NT; it++) {
13483                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13484                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13485                                receivers.remove(it);
13486                                it--;
13487                                NT--;
13488                            }
13489                        }
13490                    }
13491                }
13492            }
13493
13494            int NT = receivers != null ? receivers.size() : 0;
13495            int it = 0;
13496            ResolveInfo curt = null;
13497            BroadcastFilter curr = null;
13498            while (it < NT && ir < NR) {
13499                if (curt == null) {
13500                    curt = (ResolveInfo)receivers.get(it);
13501                }
13502                if (curr == null) {
13503                    curr = registeredReceivers.get(ir);
13504                }
13505                if (curr.getPriority() >= curt.priority) {
13506                    // Insert this broadcast record into the final list.
13507                    receivers.add(it, curr);
13508                    ir++;
13509                    curr = null;
13510                    it++;
13511                    NT++;
13512                } else {
13513                    // Skip to the next ResolveInfo in the final list.
13514                    it++;
13515                    curt = null;
13516                }
13517            }
13518        }
13519        while (ir < NR) {
13520            if (receivers == null) {
13521                receivers = new ArrayList();
13522            }
13523            receivers.add(registeredReceivers.get(ir));
13524            ir++;
13525        }
13526
13527        if ((receivers != null && receivers.size() > 0)
13528                || resultTo != null) {
13529            BroadcastQueue queue = broadcastQueueForIntent(intent);
13530            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13531                    callerPackage, callingPid, callingUid, resolvedType,
13532                    requiredPermission, appOp, receivers, resultTo, resultCode,
13533                    resultData, map, ordered, sticky, false, userId);
13534            if (DEBUG_BROADCAST) Slog.v(
13535                    TAG, "Enqueueing ordered broadcast " + r
13536                    + ": prev had " + queue.mOrderedBroadcasts.size());
13537            if (DEBUG_BROADCAST) {
13538                int seq = r.intent.getIntExtra("seq", -1);
13539                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13540            }
13541            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13542            if (!replaced) {
13543                queue.enqueueOrderedBroadcastLocked(r);
13544                queue.scheduleBroadcastsLocked();
13545            }
13546        }
13547
13548        return ActivityManager.BROADCAST_SUCCESS;
13549    }
13550
13551    final Intent verifyBroadcastLocked(Intent intent) {
13552        // Refuse possible leaked file descriptors
13553        if (intent != null && intent.hasFileDescriptors() == true) {
13554            throw new IllegalArgumentException("File descriptors passed in Intent");
13555        }
13556
13557        int flags = intent.getFlags();
13558
13559        if (!mProcessesReady) {
13560            // if the caller really truly claims to know what they're doing, go
13561            // ahead and allow the broadcast without launching any receivers
13562            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13563                intent = new Intent(intent);
13564                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13565            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13566                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13567                        + " before boot completion");
13568                throw new IllegalStateException("Cannot broadcast before boot completed");
13569            }
13570        }
13571
13572        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13573            throw new IllegalArgumentException(
13574                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13575        }
13576
13577        return intent;
13578    }
13579
13580    public final int broadcastIntent(IApplicationThread caller,
13581            Intent intent, String resolvedType, IIntentReceiver resultTo,
13582            int resultCode, String resultData, Bundle map,
13583            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13584        enforceNotIsolatedCaller("broadcastIntent");
13585        synchronized(this) {
13586            intent = verifyBroadcastLocked(intent);
13587
13588            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13589            final int callingPid = Binder.getCallingPid();
13590            final int callingUid = Binder.getCallingUid();
13591            final long origId = Binder.clearCallingIdentity();
13592            int res = broadcastIntentLocked(callerApp,
13593                    callerApp != null ? callerApp.info.packageName : null,
13594                    intent, resolvedType, resultTo,
13595                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13596                    callingPid, callingUid, userId);
13597            Binder.restoreCallingIdentity(origId);
13598            return res;
13599        }
13600    }
13601
13602    int broadcastIntentInPackage(String packageName, int uid,
13603            Intent intent, String resolvedType, IIntentReceiver resultTo,
13604            int resultCode, String resultData, Bundle map,
13605            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13606        synchronized(this) {
13607            intent = verifyBroadcastLocked(intent);
13608
13609            final long origId = Binder.clearCallingIdentity();
13610            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13611                    resultTo, resultCode, resultData, map, requiredPermission,
13612                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13613            Binder.restoreCallingIdentity(origId);
13614            return res;
13615        }
13616    }
13617
13618    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13619        // Refuse possible leaked file descriptors
13620        if (intent != null && intent.hasFileDescriptors() == true) {
13621            throw new IllegalArgumentException("File descriptors passed in Intent");
13622        }
13623
13624        userId = handleIncomingUser(Binder.getCallingPid(),
13625                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13626
13627        synchronized(this) {
13628            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13629                    != PackageManager.PERMISSION_GRANTED) {
13630                String msg = "Permission Denial: unbroadcastIntent() from pid="
13631                        + Binder.getCallingPid()
13632                        + ", uid=" + Binder.getCallingUid()
13633                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13634                Slog.w(TAG, msg);
13635                throw new SecurityException(msg);
13636            }
13637            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13638            if (stickies != null) {
13639                ArrayList<Intent> list = stickies.get(intent.getAction());
13640                if (list != null) {
13641                    int N = list.size();
13642                    int i;
13643                    for (i=0; i<N; i++) {
13644                        if (intent.filterEquals(list.get(i))) {
13645                            list.remove(i);
13646                            break;
13647                        }
13648                    }
13649                    if (list.size() <= 0) {
13650                        stickies.remove(intent.getAction());
13651                    }
13652                }
13653                if (stickies.size() <= 0) {
13654                    mStickyBroadcasts.remove(userId);
13655                }
13656            }
13657        }
13658    }
13659
13660    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13661            String resultData, Bundle resultExtras, boolean resultAbort) {
13662        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13663        if (r == null) {
13664            Slog.w(TAG, "finishReceiver called but not found on queue");
13665            return false;
13666        }
13667
13668        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13669    }
13670
13671    void backgroundServicesFinishedLocked(int userId) {
13672        for (BroadcastQueue queue : mBroadcastQueues) {
13673            queue.backgroundServicesFinishedLocked(userId);
13674        }
13675    }
13676
13677    public void finishReceiver(IBinder who, int resultCode, String resultData,
13678            Bundle resultExtras, boolean resultAbort) {
13679        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13680
13681        // Refuse possible leaked file descriptors
13682        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13683            throw new IllegalArgumentException("File descriptors passed in Bundle");
13684        }
13685
13686        final long origId = Binder.clearCallingIdentity();
13687        try {
13688            boolean doNext = false;
13689            BroadcastRecord r;
13690
13691            synchronized(this) {
13692                r = broadcastRecordForReceiverLocked(who);
13693                if (r != null) {
13694                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13695                        resultData, resultExtras, resultAbort, true);
13696                }
13697            }
13698
13699            if (doNext) {
13700                r.queue.processNextBroadcast(false);
13701            }
13702            trimApplications();
13703        } finally {
13704            Binder.restoreCallingIdentity(origId);
13705        }
13706    }
13707
13708    // =========================================================
13709    // INSTRUMENTATION
13710    // =========================================================
13711
13712    public boolean startInstrumentation(ComponentName className,
13713            String profileFile, int flags, Bundle arguments,
13714            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13715            int userId) {
13716        enforceNotIsolatedCaller("startInstrumentation");
13717        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13718                userId, false, true, "startInstrumentation", null);
13719        // Refuse possible leaked file descriptors
13720        if (arguments != null && arguments.hasFileDescriptors()) {
13721            throw new IllegalArgumentException("File descriptors passed in Bundle");
13722        }
13723
13724        synchronized(this) {
13725            InstrumentationInfo ii = null;
13726            ApplicationInfo ai = null;
13727            try {
13728                ii = mContext.getPackageManager().getInstrumentationInfo(
13729                    className, STOCK_PM_FLAGS);
13730                ai = AppGlobals.getPackageManager().getApplicationInfo(
13731                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13732            } catch (PackageManager.NameNotFoundException e) {
13733            } catch (RemoteException e) {
13734            }
13735            if (ii == null) {
13736                reportStartInstrumentationFailure(watcher, className,
13737                        "Unable to find instrumentation info for: " + className);
13738                return false;
13739            }
13740            if (ai == null) {
13741                reportStartInstrumentationFailure(watcher, className,
13742                        "Unable to find instrumentation target package: " + ii.targetPackage);
13743                return false;
13744            }
13745
13746            int match = mContext.getPackageManager().checkSignatures(
13747                    ii.targetPackage, ii.packageName);
13748            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13749                String msg = "Permission Denial: starting instrumentation "
13750                        + className + " from pid="
13751                        + Binder.getCallingPid()
13752                        + ", uid=" + Binder.getCallingPid()
13753                        + " not allowed because package " + ii.packageName
13754                        + " does not have a signature matching the target "
13755                        + ii.targetPackage;
13756                reportStartInstrumentationFailure(watcher, className, msg);
13757                throw new SecurityException(msg);
13758            }
13759
13760            final long origId = Binder.clearCallingIdentity();
13761            // Instrumentation can kill and relaunch even persistent processes
13762            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
13763                    "start instr");
13764            ProcessRecord app = addAppLocked(ai, false);
13765            app.instrumentationClass = className;
13766            app.instrumentationInfo = ai;
13767            app.instrumentationProfileFile = profileFile;
13768            app.instrumentationArguments = arguments;
13769            app.instrumentationWatcher = watcher;
13770            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13771            app.instrumentationResultClass = className;
13772            Binder.restoreCallingIdentity(origId);
13773        }
13774
13775        return true;
13776    }
13777
13778    /**
13779     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13780     * error to the logs, but if somebody is watching, send the report there too.  This enables
13781     * the "am" command to report errors with more information.
13782     *
13783     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13784     * @param cn The component name of the instrumentation.
13785     * @param report The error report.
13786     */
13787    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13788            ComponentName cn, String report) {
13789        Slog.w(TAG, report);
13790        try {
13791            if (watcher != null) {
13792                Bundle results = new Bundle();
13793                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13794                results.putString("Error", report);
13795                watcher.instrumentationStatus(cn, -1, results);
13796            }
13797        } catch (RemoteException e) {
13798            Slog.w(TAG, e);
13799        }
13800    }
13801
13802    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13803        if (app.instrumentationWatcher != null) {
13804            try {
13805                // NOTE:  IInstrumentationWatcher *must* be oneway here
13806                app.instrumentationWatcher.instrumentationFinished(
13807                    app.instrumentationClass,
13808                    resultCode,
13809                    results);
13810            } catch (RemoteException e) {
13811            }
13812        }
13813        if (app.instrumentationUiAutomationConnection != null) {
13814            try {
13815                app.instrumentationUiAutomationConnection.shutdown();
13816            } catch (RemoteException re) {
13817                /* ignore */
13818            }
13819            // Only a UiAutomation can set this flag and now that
13820            // it is finished we make sure it is reset to its default.
13821            mUserIsMonkey = false;
13822        }
13823        app.instrumentationWatcher = null;
13824        app.instrumentationUiAutomationConnection = null;
13825        app.instrumentationClass = null;
13826        app.instrumentationInfo = null;
13827        app.instrumentationProfileFile = null;
13828        app.instrumentationArguments = null;
13829
13830        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
13831                "finished inst");
13832    }
13833
13834    public void finishInstrumentation(IApplicationThread target,
13835            int resultCode, Bundle results) {
13836        int userId = UserHandle.getCallingUserId();
13837        // Refuse possible leaked file descriptors
13838        if (results != null && results.hasFileDescriptors()) {
13839            throw new IllegalArgumentException("File descriptors passed in Intent");
13840        }
13841
13842        synchronized(this) {
13843            ProcessRecord app = getRecordForAppLocked(target);
13844            if (app == null) {
13845                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13846                return;
13847            }
13848            final long origId = Binder.clearCallingIdentity();
13849            finishInstrumentationLocked(app, resultCode, results);
13850            Binder.restoreCallingIdentity(origId);
13851        }
13852    }
13853
13854    // =========================================================
13855    // CONFIGURATION
13856    // =========================================================
13857
13858    public ConfigurationInfo getDeviceConfigurationInfo() {
13859        ConfigurationInfo config = new ConfigurationInfo();
13860        synchronized (this) {
13861            config.reqTouchScreen = mConfiguration.touchscreen;
13862            config.reqKeyboardType = mConfiguration.keyboard;
13863            config.reqNavigation = mConfiguration.navigation;
13864            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13865                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13866                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13867            }
13868            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13869                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13870                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13871            }
13872            config.reqGlEsVersion = GL_ES_VERSION;
13873        }
13874        return config;
13875    }
13876
13877    ActivityStack getFocusedStack() {
13878        return mStackSupervisor.getFocusedStack();
13879    }
13880
13881    public Configuration getConfiguration() {
13882        Configuration ci;
13883        synchronized(this) {
13884            ci = new Configuration(mConfiguration);
13885        }
13886        return ci;
13887    }
13888
13889    public void updatePersistentConfiguration(Configuration values) {
13890        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13891                "updateConfiguration()");
13892        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13893                "updateConfiguration()");
13894        if (values == null) {
13895            throw new NullPointerException("Configuration must not be null");
13896        }
13897
13898        synchronized(this) {
13899            final long origId = Binder.clearCallingIdentity();
13900            updateConfigurationLocked(values, null, true, false);
13901            Binder.restoreCallingIdentity(origId);
13902        }
13903    }
13904
13905    public void updateConfiguration(Configuration values) {
13906        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13907                "updateConfiguration()");
13908
13909        synchronized(this) {
13910            if (values == null && mWindowManager != null) {
13911                // sentinel: fetch the current configuration from the window manager
13912                values = mWindowManager.computeNewConfiguration();
13913            }
13914
13915            if (mWindowManager != null) {
13916                mProcessList.applyDisplaySize(mWindowManager);
13917            }
13918
13919            final long origId = Binder.clearCallingIdentity();
13920            if (values != null) {
13921                Settings.System.clearConfiguration(values);
13922            }
13923            updateConfigurationLocked(values, null, false, false);
13924            Binder.restoreCallingIdentity(origId);
13925        }
13926    }
13927
13928    /**
13929     * Do either or both things: (1) change the current configuration, and (2)
13930     * make sure the given activity is running with the (now) current
13931     * configuration.  Returns true if the activity has been left running, or
13932     * false if <var>starting</var> is being destroyed to match the new
13933     * configuration.
13934     * @param persistent TODO
13935     */
13936    boolean updateConfigurationLocked(Configuration values,
13937            ActivityRecord starting, boolean persistent, boolean initLocale) {
13938        int changes = 0;
13939
13940        if (values != null) {
13941            Configuration newConfig = new Configuration(mConfiguration);
13942            changes = newConfig.updateFrom(values);
13943            if (changes != 0) {
13944                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13945                    Slog.i(TAG, "Updating configuration to: " + values);
13946                }
13947
13948                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13949
13950                if (values.locale != null && !initLocale) {
13951                    saveLocaleLocked(values.locale,
13952                                     !values.locale.equals(mConfiguration.locale),
13953                                     values.userSetLocale);
13954                }
13955
13956                mConfigurationSeq++;
13957                if (mConfigurationSeq <= 0) {
13958                    mConfigurationSeq = 1;
13959                }
13960                newConfig.seq = mConfigurationSeq;
13961                mConfiguration = newConfig;
13962                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
13963
13964                final Configuration configCopy = new Configuration(mConfiguration);
13965
13966                // TODO: If our config changes, should we auto dismiss any currently
13967                // showing dialogs?
13968                mShowDialogs = shouldShowDialogs(newConfig);
13969
13970                AttributeCache ac = AttributeCache.instance();
13971                if (ac != null) {
13972                    ac.updateConfiguration(configCopy);
13973                }
13974
13975                // Make sure all resources in our process are updated
13976                // right now, so that anyone who is going to retrieve
13977                // resource values after we return will be sure to get
13978                // the new ones.  This is especially important during
13979                // boot, where the first config change needs to guarantee
13980                // all resources have that config before following boot
13981                // code is executed.
13982                mSystemThread.applyConfigurationToResources(configCopy);
13983
13984                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
13985                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
13986                    msg.obj = new Configuration(configCopy);
13987                    mHandler.sendMessage(msg);
13988                }
13989
13990                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13991                    ProcessRecord app = mLruProcesses.get(i);
13992                    try {
13993                        if (app.thread != null) {
13994                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
13995                                    + app.processName + " new config " + mConfiguration);
13996                            app.thread.scheduleConfigurationChanged(configCopy);
13997                        }
13998                    } catch (Exception e) {
13999                    }
14000                }
14001                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14002                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14003                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14004                        | Intent.FLAG_RECEIVER_FOREGROUND);
14005                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14006                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14007                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14008                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14009                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14010                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14011                    broadcastIntentLocked(null, null, intent,
14012                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14013                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14014                }
14015            }
14016        }
14017
14018        boolean kept = true;
14019        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14020        // mainStack is null during startup.
14021        if (mainStack != null) {
14022            if (changes != 0 && starting == null) {
14023                // If the configuration changed, and the caller is not already
14024                // in the process of starting an activity, then find the top
14025                // activity to check if its configuration needs to change.
14026                starting = mainStack.topRunningActivityLocked(null);
14027            }
14028
14029            if (starting != null) {
14030                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14031                // And we need to make sure at this point that all other activities
14032                // are made visible with the correct configuration.
14033                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14034            }
14035        }
14036
14037        if (values != null && mWindowManager != null) {
14038            mWindowManager.setNewConfiguration(mConfiguration);
14039        }
14040
14041        return kept;
14042    }
14043
14044    /**
14045     * Decide based on the configuration whether we should shouw the ANR,
14046     * crash, etc dialogs.  The idea is that if there is no affordnace to
14047     * press the on-screen buttons, we shouldn't show the dialog.
14048     *
14049     * A thought: SystemUI might also want to get told about this, the Power
14050     * dialog / global actions also might want different behaviors.
14051     */
14052    private static final boolean shouldShowDialogs(Configuration config) {
14053        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14054                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14055    }
14056
14057    /**
14058     * Save the locale.  You must be inside a synchronized (this) block.
14059     */
14060    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14061        if(isDiff) {
14062            SystemProperties.set("user.language", l.getLanguage());
14063            SystemProperties.set("user.region", l.getCountry());
14064        }
14065
14066        if(isPersist) {
14067            SystemProperties.set("persist.sys.language", l.getLanguage());
14068            SystemProperties.set("persist.sys.country", l.getCountry());
14069            SystemProperties.set("persist.sys.localevar", l.getVariant());
14070        }
14071    }
14072
14073    @Override
14074    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14075        ActivityRecord srec = ActivityRecord.forToken(token);
14076        return srec != null && srec.task.affinity != null &&
14077                srec.task.affinity.equals(destAffinity);
14078    }
14079
14080    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14081            Intent resultData) {
14082
14083        synchronized (this) {
14084            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14085            if (stack != null) {
14086                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14087            }
14088            return false;
14089        }
14090    }
14091
14092    public int getLaunchedFromUid(IBinder activityToken) {
14093        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14094        if (srec == null) {
14095            return -1;
14096        }
14097        return srec.launchedFromUid;
14098    }
14099
14100    public String getLaunchedFromPackage(IBinder activityToken) {
14101        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14102        if (srec == null) {
14103            return null;
14104        }
14105        return srec.launchedFromPackage;
14106    }
14107
14108    // =========================================================
14109    // LIFETIME MANAGEMENT
14110    // =========================================================
14111
14112    // Returns which broadcast queue the app is the current [or imminent] receiver
14113    // on, or 'null' if the app is not an active broadcast recipient.
14114    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14115        BroadcastRecord r = app.curReceiver;
14116        if (r != null) {
14117            return r.queue;
14118        }
14119
14120        // It's not the current receiver, but it might be starting up to become one
14121        synchronized (this) {
14122            for (BroadcastQueue queue : mBroadcastQueues) {
14123                r = queue.mPendingBroadcast;
14124                if (r != null && r.curApp == app) {
14125                    // found it; report which queue it's in
14126                    return queue;
14127                }
14128            }
14129        }
14130
14131        return null;
14132    }
14133
14134    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14135            boolean doingAll, long now) {
14136        if (mAdjSeq == app.adjSeq) {
14137            // This adjustment has already been computed.
14138            return app.curRawAdj;
14139        }
14140
14141        if (app.thread == null) {
14142            app.adjSeq = mAdjSeq;
14143            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14144            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14145            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14146        }
14147
14148        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14149        app.adjSource = null;
14150        app.adjTarget = null;
14151        app.empty = false;
14152        app.cached = false;
14153
14154        final int activitiesSize = app.activities.size();
14155
14156        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14157            // The max adjustment doesn't allow this app to be anything
14158            // below foreground, so it is not worth doing work for it.
14159            app.adjType = "fixed";
14160            app.adjSeq = mAdjSeq;
14161            app.curRawAdj = app.maxAdj;
14162            app.foregroundActivities = false;
14163            app.keeping = true;
14164            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14165            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14166            // System process can do UI, and when they do we want to have
14167            // them trim their memory after the user leaves the UI.  To
14168            // facilitate this, here we need to determine whether or not it
14169            // is currently showing UI.
14170            app.systemNoUi = true;
14171            if (app == TOP_APP) {
14172                app.systemNoUi = false;
14173            } else if (activitiesSize > 0) {
14174                for (int j = 0; j < activitiesSize; j++) {
14175                    final ActivityRecord r = app.activities.get(j);
14176                    if (r.visible) {
14177                        app.systemNoUi = false;
14178                    }
14179                }
14180            }
14181            if (!app.systemNoUi) {
14182                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14183            }
14184            return (app.curAdj=app.maxAdj);
14185        }
14186
14187        app.keeping = false;
14188        app.systemNoUi = false;
14189
14190        // Determine the importance of the process, starting with most
14191        // important to least, and assign an appropriate OOM adjustment.
14192        int adj;
14193        int schedGroup;
14194        int procState;
14195        boolean foregroundActivities = false;
14196        boolean interesting = false;
14197        BroadcastQueue queue;
14198        if (app == TOP_APP) {
14199            // The last app on the list is the foreground app.
14200            adj = ProcessList.FOREGROUND_APP_ADJ;
14201            schedGroup = Process.THREAD_GROUP_DEFAULT;
14202            app.adjType = "top-activity";
14203            foregroundActivities = true;
14204            interesting = true;
14205            procState = ActivityManager.PROCESS_STATE_TOP;
14206        } else if (app.instrumentationClass != null) {
14207            // Don't want to kill running instrumentation.
14208            adj = ProcessList.FOREGROUND_APP_ADJ;
14209            schedGroup = Process.THREAD_GROUP_DEFAULT;
14210            app.adjType = "instrumentation";
14211            interesting = true;
14212            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14213        } else if ((queue = isReceivingBroadcast(app)) != null) {
14214            // An app that is currently receiving a broadcast also
14215            // counts as being in the foreground for OOM killer purposes.
14216            // It's placed in a sched group based on the nature of the
14217            // broadcast as reflected by which queue it's active in.
14218            adj = ProcessList.FOREGROUND_APP_ADJ;
14219            schedGroup = (queue == mFgBroadcastQueue)
14220                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14221            app.adjType = "broadcast";
14222            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14223        } else if (app.executingServices.size() > 0) {
14224            // An app that is currently executing a service callback also
14225            // counts as being in the foreground.
14226            adj = ProcessList.FOREGROUND_APP_ADJ;
14227            schedGroup = app.execServicesFg ?
14228                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14229            app.adjType = "exec-service";
14230            procState = ActivityManager.PROCESS_STATE_SERVICE;
14231            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14232        } else {
14233            // As far as we know the process is empty.  We may change our mind later.
14234            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14235            // At this point we don't actually know the adjustment.  Use the cached adj
14236            // value that the caller wants us to.
14237            adj = cachedAdj;
14238            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14239            app.cached = true;
14240            app.empty = true;
14241            app.adjType = "cch-empty";
14242        }
14243
14244        // Examine all activities if not already foreground.
14245        if (!foregroundActivities && activitiesSize > 0) {
14246            for (int j = 0; j < activitiesSize; j++) {
14247                final ActivityRecord r = app.activities.get(j);
14248                if (r.app != app) {
14249                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14250                            + app + "?!?");
14251                    continue;
14252                }
14253                if (r.visible) {
14254                    // App has a visible activity; only upgrade adjustment.
14255                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14256                        adj = ProcessList.VISIBLE_APP_ADJ;
14257                        app.adjType = "visible";
14258                    }
14259                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14260                        procState = ActivityManager.PROCESS_STATE_TOP;
14261                    }
14262                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14263                    app.cached = false;
14264                    app.empty = false;
14265                    foregroundActivities = true;
14266                    break;
14267                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14268                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14269                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14270                        app.adjType = "pausing";
14271                    }
14272                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14273                        procState = ActivityManager.PROCESS_STATE_TOP;
14274                    }
14275                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14276                    app.cached = false;
14277                    app.empty = false;
14278                    foregroundActivities = true;
14279                } else if (r.state == ActivityState.STOPPING) {
14280                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14281                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14282                        app.adjType = "stopping";
14283                    }
14284                    // For the process state, we will at this point consider the
14285                    // process to be cached.  It will be cached either as an activity
14286                    // or empty depending on whether the activity is finishing.  We do
14287                    // this so that we can treat the process as cached for purposes of
14288                    // memory trimming (determing current memory level, trim command to
14289                    // send to process) since there can be an arbitrary number of stopping
14290                    // processes and they should soon all go into the cached state.
14291                    if (!r.finishing) {
14292                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14293                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14294                        }
14295                    }
14296                    app.cached = false;
14297                    app.empty = false;
14298                    foregroundActivities = true;
14299                } else {
14300                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14301                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14302                        app.adjType = "cch-act";
14303                    }
14304                }
14305            }
14306        }
14307
14308        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14309            if (app.foregroundServices) {
14310                // The user is aware of this app, so make it visible.
14311                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14312                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14313                app.cached = false;
14314                app.adjType = "fg-service";
14315                schedGroup = Process.THREAD_GROUP_DEFAULT;
14316            } else if (app.forcingToForeground != null) {
14317                // The user is aware of this app, so make it visible.
14318                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14319                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14320                app.cached = false;
14321                app.adjType = "force-fg";
14322                app.adjSource = app.forcingToForeground;
14323                schedGroup = Process.THREAD_GROUP_DEFAULT;
14324            }
14325        }
14326
14327        if (app.foregroundServices) {
14328            interesting = true;
14329        }
14330
14331        if (app == mHeavyWeightProcess) {
14332            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14333                // We don't want to kill the current heavy-weight process.
14334                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14335                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14336                app.cached = false;
14337                app.adjType = "heavy";
14338            }
14339            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14340                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14341            }
14342        }
14343
14344        if (app == mHomeProcess) {
14345            if (adj > ProcessList.HOME_APP_ADJ) {
14346                // This process is hosting what we currently consider to be the
14347                // home app, so we don't want to let it go into the background.
14348                adj = ProcessList.HOME_APP_ADJ;
14349                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14350                app.cached = false;
14351                app.adjType = "home";
14352            }
14353            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14354                procState = ActivityManager.PROCESS_STATE_HOME;
14355            }
14356        }
14357
14358        if (app == mPreviousProcess && app.activities.size() > 0) {
14359            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14360                // This was the previous process that showed UI to the user.
14361                // We want to try to keep it around more aggressively, to give
14362                // a good experience around switching between two apps.
14363                adj = ProcessList.PREVIOUS_APP_ADJ;
14364                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14365                app.cached = false;
14366                app.adjType = "previous";
14367            }
14368            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14369                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14370            }
14371        }
14372
14373        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14374                + " reason=" + app.adjType);
14375
14376        // By default, we use the computed adjustment.  It may be changed if
14377        // there are applications dependent on our services or providers, but
14378        // this gives us a baseline and makes sure we don't get into an
14379        // infinite recursion.
14380        app.adjSeq = mAdjSeq;
14381        app.curRawAdj = adj;
14382        app.hasStartedServices = false;
14383
14384        if (mBackupTarget != null && app == mBackupTarget.app) {
14385            // If possible we want to avoid killing apps while they're being backed up
14386            if (adj > ProcessList.BACKUP_APP_ADJ) {
14387                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14388                adj = ProcessList.BACKUP_APP_ADJ;
14389                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14390                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14391                }
14392                app.adjType = "backup";
14393                app.cached = false;
14394            }
14395            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14396                procState = ActivityManager.PROCESS_STATE_BACKUP;
14397            }
14398        }
14399
14400        boolean mayBeTop = false;
14401
14402        for (int is = app.services.size()-1;
14403                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14404                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14405                        || procState > ActivityManager.PROCESS_STATE_TOP);
14406                is--) {
14407            ServiceRecord s = app.services.valueAt(is);
14408            if (s.startRequested) {
14409                app.hasStartedServices = true;
14410                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14411                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14412                }
14413                if (app.hasShownUi && app != mHomeProcess) {
14414                    // If this process has shown some UI, let it immediately
14415                    // go to the LRU list because it may be pretty heavy with
14416                    // UI stuff.  We'll tag it with a label just to help
14417                    // debug and understand what is going on.
14418                    if (adj > ProcessList.SERVICE_ADJ) {
14419                        app.adjType = "cch-started-ui-services";
14420                    }
14421                } else {
14422                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14423                        // This service has seen some activity within
14424                        // recent memory, so we will keep its process ahead
14425                        // of the background processes.
14426                        if (adj > ProcessList.SERVICE_ADJ) {
14427                            adj = ProcessList.SERVICE_ADJ;
14428                            app.adjType = "started-services";
14429                            app.cached = false;
14430                        }
14431                    }
14432                    // If we have let the service slide into the background
14433                    // state, still have some text describing what it is doing
14434                    // even though the service no longer has an impact.
14435                    if (adj > ProcessList.SERVICE_ADJ) {
14436                        app.adjType = "cch-started-services";
14437                    }
14438                }
14439                // Don't kill this process because it is doing work; it
14440                // has said it is doing work.
14441                app.keeping = true;
14442            }
14443            for (int conni = s.connections.size()-1;
14444                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14445                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14446                            || procState > ActivityManager.PROCESS_STATE_TOP);
14447                    conni--) {
14448                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14449                for (int i = 0;
14450                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14451                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14452                                || procState > ActivityManager.PROCESS_STATE_TOP);
14453                        i++) {
14454                    // XXX should compute this based on the max of
14455                    // all connected clients.
14456                    ConnectionRecord cr = clist.get(i);
14457                    if (cr.binding.client == app) {
14458                        // Binding to ourself is not interesting.
14459                        continue;
14460                    }
14461                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14462                        ProcessRecord client = cr.binding.client;
14463                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14464                                TOP_APP, doingAll, now);
14465                        int clientProcState = client.curProcState;
14466                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14467                            // If the other app is cached for any reason, for purposes here
14468                            // we are going to consider it empty.  The specific cached state
14469                            // doesn't propagate except under certain conditions.
14470                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14471                        }
14472                        String adjType = null;
14473                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14474                            // Not doing bind OOM management, so treat
14475                            // this guy more like a started service.
14476                            if (app.hasShownUi && app != mHomeProcess) {
14477                                // If this process has shown some UI, let it immediately
14478                                // go to the LRU list because it may be pretty heavy with
14479                                // UI stuff.  We'll tag it with a label just to help
14480                                // debug and understand what is going on.
14481                                if (adj > clientAdj) {
14482                                    adjType = "cch-bound-ui-services";
14483                                }
14484                                app.cached = false;
14485                                clientAdj = adj;
14486                                clientProcState = procState;
14487                            } else {
14488                                if (now >= (s.lastActivity
14489                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14490                                    // This service has not seen activity within
14491                                    // recent memory, so allow it to drop to the
14492                                    // LRU list if there is no other reason to keep
14493                                    // it around.  We'll also tag it with a label just
14494                                    // to help debug and undertand what is going on.
14495                                    if (adj > clientAdj) {
14496                                        adjType = "cch-bound-services";
14497                                    }
14498                                    clientAdj = adj;
14499                                }
14500                            }
14501                        }
14502                        if (adj > clientAdj) {
14503                            // If this process has recently shown UI, and
14504                            // the process that is binding to it is less
14505                            // important than being visible, then we don't
14506                            // care about the binding as much as we care
14507                            // about letting this process get into the LRU
14508                            // list to be killed and restarted if needed for
14509                            // memory.
14510                            if (app.hasShownUi && app != mHomeProcess
14511                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14512                                adjType = "cch-bound-ui-services";
14513                            } else {
14514                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14515                                        |Context.BIND_IMPORTANT)) != 0) {
14516                                    adj = clientAdj;
14517                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14518                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14519                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14520                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14521                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14522                                    adj = clientAdj;
14523                                } else {
14524                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14525                                        adj = ProcessList.VISIBLE_APP_ADJ;
14526                                    }
14527                                }
14528                                if (!client.cached) {
14529                                    app.cached = false;
14530                                }
14531                                if (client.keeping) {
14532                                    app.keeping = true;
14533                                }
14534                                adjType = "service";
14535                            }
14536                        }
14537                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14538                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14539                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14540                            }
14541                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14542                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14543                                    // Special handling of clients who are in the top state.
14544                                    // We *may* want to consider this process to be in the
14545                                    // top state as well, but only if there is not another
14546                                    // reason for it to be running.  Being on the top is a
14547                                    // special state, meaning you are specifically running
14548                                    // for the current top app.  If the process is already
14549                                    // running in the background for some other reason, it
14550                                    // is more important to continue considering it to be
14551                                    // in the background state.
14552                                    mayBeTop = true;
14553                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14554                                } else {
14555                                    // Special handling for above-top states (persistent
14556                                    // processes).  These should not bring the current process
14557                                    // into the top state, since they are not on top.  Instead
14558                                    // give them the best state after that.
14559                                    clientProcState =
14560                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14561                                }
14562                            }
14563                        } else {
14564                            if (clientProcState <
14565                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14566                                clientProcState =
14567                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14568                            }
14569                        }
14570                        if (procState > clientProcState) {
14571                            procState = clientProcState;
14572                        }
14573                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14574                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14575                            app.pendingUiClean = true;
14576                        }
14577                        if (adjType != null) {
14578                            app.adjType = adjType;
14579                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14580                                    .REASON_SERVICE_IN_USE;
14581                            app.adjSource = cr.binding.client;
14582                            app.adjSourceOom = clientAdj;
14583                            app.adjTarget = s.name;
14584                        }
14585                    }
14586                    final ActivityRecord a = cr.activity;
14587                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14588                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14589                                (a.visible || a.state == ActivityState.RESUMED
14590                                 || a.state == ActivityState.PAUSING)) {
14591                            adj = ProcessList.FOREGROUND_APP_ADJ;
14592                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14593                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14594                            }
14595                            app.cached = false;
14596                            app.adjType = "service";
14597                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14598                                    .REASON_SERVICE_IN_USE;
14599                            app.adjSource = a;
14600                            app.adjSourceOom = adj;
14601                            app.adjTarget = s.name;
14602                        }
14603                    }
14604                }
14605            }
14606        }
14607
14608        for (int provi = app.pubProviders.size()-1;
14609                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14610                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14611                        || procState > ActivityManager.PROCESS_STATE_TOP);
14612                provi--) {
14613            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14614            for (int i = cpr.connections.size()-1;
14615                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14616                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14617                            || procState > ActivityManager.PROCESS_STATE_TOP);
14618                    i--) {
14619                ContentProviderConnection conn = cpr.connections.get(i);
14620                ProcessRecord client = conn.client;
14621                if (client == app) {
14622                    // Being our own client is not interesting.
14623                    continue;
14624                }
14625                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14626                int clientProcState = client.curProcState;
14627                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14628                    // If the other app is cached for any reason, for purposes here
14629                    // we are going to consider it empty.
14630                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14631                }
14632                if (adj > clientAdj) {
14633                    if (app.hasShownUi && app != mHomeProcess
14634                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14635                        app.adjType = "cch-ui-provider";
14636                    } else {
14637                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14638                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14639                        app.adjType = "provider";
14640                    }
14641                    app.cached &= client.cached;
14642                    app.keeping |= client.keeping;
14643                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14644                            .REASON_PROVIDER_IN_USE;
14645                    app.adjSource = client;
14646                    app.adjSourceOom = clientAdj;
14647                    app.adjTarget = cpr.name;
14648                }
14649                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14650                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14651                        // Special handling of clients who are in the top state.
14652                        // We *may* want to consider this process to be in the
14653                        // top state as well, but only if there is not another
14654                        // reason for it to be running.  Being on the top is a
14655                        // special state, meaning you are specifically running
14656                        // for the current top app.  If the process is already
14657                        // running in the background for some other reason, it
14658                        // is more important to continue considering it to be
14659                        // in the background state.
14660                        mayBeTop = true;
14661                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14662                    } else {
14663                        // Special handling for above-top states (persistent
14664                        // processes).  These should not bring the current process
14665                        // into the top state, since they are not on top.  Instead
14666                        // give them the best state after that.
14667                        clientProcState =
14668                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14669                    }
14670                }
14671                if (procState > clientProcState) {
14672                    procState = clientProcState;
14673                }
14674                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14675                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14676                }
14677            }
14678            // If the provider has external (non-framework) process
14679            // dependencies, ensure that its adjustment is at least
14680            // FOREGROUND_APP_ADJ.
14681            if (cpr.hasExternalProcessHandles()) {
14682                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14683                    adj = ProcessList.FOREGROUND_APP_ADJ;
14684                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14685                    app.cached = false;
14686                    app.keeping = true;
14687                    app.adjType = "provider";
14688                    app.adjTarget = cpr.name;
14689                }
14690                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14691                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14692                }
14693            }
14694        }
14695
14696        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14697            // A client of one of our services or providers is in the top state.  We
14698            // *may* want to be in the top state, but not if we are already running in
14699            // the background for some other reason.  For the decision here, we are going
14700            // to pick out a few specific states that we want to remain in when a client
14701            // is top (states that tend to be longer-term) and otherwise allow it to go
14702            // to the top state.
14703            switch (procState) {
14704                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14705                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14706                case ActivityManager.PROCESS_STATE_SERVICE:
14707                    // These all are longer-term states, so pull them up to the top
14708                    // of the background states, but not all the way to the top state.
14709                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14710                    break;
14711                default:
14712                    // Otherwise, top is a better choice, so take it.
14713                    procState = ActivityManager.PROCESS_STATE_TOP;
14714                    break;
14715            }
14716        }
14717
14718        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14719            // This is a cached process, but with client activities.  Mark it so.
14720            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14721            app.adjType = "cch-client-act";
14722        }
14723
14724        if (adj == ProcessList.SERVICE_ADJ) {
14725            if (doingAll) {
14726                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14727                mNewNumServiceProcs++;
14728                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14729                if (!app.serviceb) {
14730                    // This service isn't far enough down on the LRU list to
14731                    // normally be a B service, but if we are low on RAM and it
14732                    // is large we want to force it down since we would prefer to
14733                    // keep launcher over it.
14734                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14735                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14736                        app.serviceHighRam = true;
14737                        app.serviceb = true;
14738                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14739                    } else {
14740                        mNewNumAServiceProcs++;
14741                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14742                    }
14743                } else {
14744                    app.serviceHighRam = false;
14745                }
14746            }
14747            if (app.serviceb) {
14748                adj = ProcessList.SERVICE_B_ADJ;
14749            }
14750        }
14751
14752        app.curRawAdj = adj;
14753
14754        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14755        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14756        if (adj > app.maxAdj) {
14757            adj = app.maxAdj;
14758            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14759                schedGroup = Process.THREAD_GROUP_DEFAULT;
14760            }
14761        }
14762        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14763            app.keeping = true;
14764        }
14765
14766        // Do final modification to adj.  Everything we do between here and applying
14767        // the final setAdj must be done in this function, because we will also use
14768        // it when computing the final cached adj later.  Note that we don't need to
14769        // worry about this for max adj above, since max adj will always be used to
14770        // keep it out of the cached vaues.
14771        adj = app.modifyRawOomAdj(adj);
14772
14773        app.curProcState = procState;
14774
14775        int importance = app.memImportance;
14776        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14777            app.curAdj = adj;
14778            app.curSchedGroup = schedGroup;
14779            if (!interesting) {
14780                // For this reporting, if there is not something explicitly
14781                // interesting in this process then we will push it to the
14782                // background importance.
14783                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14784            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14785                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14786            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14787                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14788            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14789                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14790            } else if (adj >= ProcessList.SERVICE_ADJ) {
14791                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14792            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14793                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14794            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14795                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14796            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14797                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14798            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14799                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14800            } else {
14801                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14802            }
14803        }
14804
14805        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14806        if (foregroundActivities != app.foregroundActivities) {
14807            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14808        }
14809        if (changes != 0) {
14810            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14811            app.memImportance = importance;
14812            app.foregroundActivities = foregroundActivities;
14813            int i = mPendingProcessChanges.size()-1;
14814            ProcessChangeItem item = null;
14815            while (i >= 0) {
14816                item = mPendingProcessChanges.get(i);
14817                if (item.pid == app.pid) {
14818                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14819                    break;
14820                }
14821                i--;
14822            }
14823            if (i < 0) {
14824                // No existing item in pending changes; need a new one.
14825                final int NA = mAvailProcessChanges.size();
14826                if (NA > 0) {
14827                    item = mAvailProcessChanges.remove(NA-1);
14828                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14829                } else {
14830                    item = new ProcessChangeItem();
14831                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14832                }
14833                item.changes = 0;
14834                item.pid = app.pid;
14835                item.uid = app.info.uid;
14836                if (mPendingProcessChanges.size() == 0) {
14837                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14838                            "*** Enqueueing dispatch processes changed!");
14839                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14840                }
14841                mPendingProcessChanges.add(item);
14842            }
14843            item.changes |= changes;
14844            item.importance = importance;
14845            item.foregroundActivities = foregroundActivities;
14846            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14847                    + Integer.toHexString(System.identityHashCode(item))
14848                    + " " + app.toShortString() + ": changes=" + item.changes
14849                    + " importance=" + item.importance
14850                    + " foreground=" + item.foregroundActivities
14851                    + " type=" + app.adjType + " source=" + app.adjSource
14852                    + " target=" + app.adjTarget);
14853        }
14854
14855        return app.curRawAdj;
14856    }
14857
14858    /**
14859     * Schedule PSS collection of a process.
14860     */
14861    void requestPssLocked(ProcessRecord proc, int procState) {
14862        if (mPendingPssProcesses.contains(proc)) {
14863            return;
14864        }
14865        if (mPendingPssProcesses.size() == 0) {
14866            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14867        }
14868        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14869        proc.pssProcState = procState;
14870        mPendingPssProcesses.add(proc);
14871    }
14872
14873    /**
14874     * Schedule PSS collection of all processes.
14875     */
14876    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14877        if (!always) {
14878            if (now < (mLastFullPssTime +
14879                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14880                return;
14881            }
14882        }
14883        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14884        mLastFullPssTime = now;
14885        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14886        mPendingPssProcesses.clear();
14887        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14888            ProcessRecord app = mLruProcesses.get(i);
14889            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14890                app.pssProcState = app.setProcState;
14891                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14892                        mSleeping, now);
14893                mPendingPssProcesses.add(app);
14894            }
14895        }
14896        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14897    }
14898
14899    /**
14900     * Ask a given process to GC right now.
14901     */
14902    final void performAppGcLocked(ProcessRecord app) {
14903        try {
14904            app.lastRequestedGc = SystemClock.uptimeMillis();
14905            if (app.thread != null) {
14906                if (app.reportLowMemory) {
14907                    app.reportLowMemory = false;
14908                    app.thread.scheduleLowMemory();
14909                } else {
14910                    app.thread.processInBackground();
14911                }
14912            }
14913        } catch (Exception e) {
14914            // whatever.
14915        }
14916    }
14917
14918    /**
14919     * Returns true if things are idle enough to perform GCs.
14920     */
14921    private final boolean canGcNowLocked() {
14922        boolean processingBroadcasts = false;
14923        for (BroadcastQueue q : mBroadcastQueues) {
14924            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14925                processingBroadcasts = true;
14926            }
14927        }
14928        return !processingBroadcasts
14929                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14930    }
14931
14932    /**
14933     * Perform GCs on all processes that are waiting for it, but only
14934     * if things are idle.
14935     */
14936    final void performAppGcsLocked() {
14937        final int N = mProcessesToGc.size();
14938        if (N <= 0) {
14939            return;
14940        }
14941        if (canGcNowLocked()) {
14942            while (mProcessesToGc.size() > 0) {
14943                ProcessRecord proc = mProcessesToGc.remove(0);
14944                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14945                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14946                            <= SystemClock.uptimeMillis()) {
14947                        // To avoid spamming the system, we will GC processes one
14948                        // at a time, waiting a few seconds between each.
14949                        performAppGcLocked(proc);
14950                        scheduleAppGcsLocked();
14951                        return;
14952                    } else {
14953                        // It hasn't been long enough since we last GCed this
14954                        // process...  put it in the list to wait for its time.
14955                        addProcessToGcListLocked(proc);
14956                        break;
14957                    }
14958                }
14959            }
14960
14961            scheduleAppGcsLocked();
14962        }
14963    }
14964
14965    /**
14966     * If all looks good, perform GCs on all processes waiting for them.
14967     */
14968    final void performAppGcsIfAppropriateLocked() {
14969        if (canGcNowLocked()) {
14970            performAppGcsLocked();
14971            return;
14972        }
14973        // Still not idle, wait some more.
14974        scheduleAppGcsLocked();
14975    }
14976
14977    /**
14978     * Schedule the execution of all pending app GCs.
14979     */
14980    final void scheduleAppGcsLocked() {
14981        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
14982
14983        if (mProcessesToGc.size() > 0) {
14984            // Schedule a GC for the time to the next process.
14985            ProcessRecord proc = mProcessesToGc.get(0);
14986            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14987
14988            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
14989            long now = SystemClock.uptimeMillis();
14990            if (when < (now+GC_TIMEOUT)) {
14991                when = now + GC_TIMEOUT;
14992            }
14993            mHandler.sendMessageAtTime(msg, when);
14994        }
14995    }
14996
14997    /**
14998     * Add a process to the array of processes waiting to be GCed.  Keeps the
14999     * list in sorted order by the last GC time.  The process can't already be
15000     * on the list.
15001     */
15002    final void addProcessToGcListLocked(ProcessRecord proc) {
15003        boolean added = false;
15004        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15005            if (mProcessesToGc.get(i).lastRequestedGc <
15006                    proc.lastRequestedGc) {
15007                added = true;
15008                mProcessesToGc.add(i+1, proc);
15009                break;
15010            }
15011        }
15012        if (!added) {
15013            mProcessesToGc.add(0, proc);
15014        }
15015    }
15016
15017    /**
15018     * Set up to ask a process to GC itself.  This will either do it
15019     * immediately, or put it on the list of processes to gc the next
15020     * time things are idle.
15021     */
15022    final void scheduleAppGcLocked(ProcessRecord app) {
15023        long now = SystemClock.uptimeMillis();
15024        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15025            return;
15026        }
15027        if (!mProcessesToGc.contains(app)) {
15028            addProcessToGcListLocked(app);
15029            scheduleAppGcsLocked();
15030        }
15031    }
15032
15033    final void checkExcessivePowerUsageLocked(boolean doKills) {
15034        updateCpuStatsNow();
15035
15036        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15037        boolean doWakeKills = doKills;
15038        boolean doCpuKills = doKills;
15039        if (mLastPowerCheckRealtime == 0) {
15040            doWakeKills = false;
15041        }
15042        if (mLastPowerCheckUptime == 0) {
15043            doCpuKills = false;
15044        }
15045        if (stats.isScreenOn()) {
15046            doWakeKills = false;
15047        }
15048        final long curRealtime = SystemClock.elapsedRealtime();
15049        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15050        final long curUptime = SystemClock.uptimeMillis();
15051        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15052        mLastPowerCheckRealtime = curRealtime;
15053        mLastPowerCheckUptime = curUptime;
15054        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15055            doWakeKills = false;
15056        }
15057        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15058            doCpuKills = false;
15059        }
15060        int i = mLruProcesses.size();
15061        while (i > 0) {
15062            i--;
15063            ProcessRecord app = mLruProcesses.get(i);
15064            if (!app.keeping) {
15065                long wtime;
15066                synchronized (stats) {
15067                    wtime = stats.getProcessWakeTime(app.info.uid,
15068                            app.pid, curRealtime);
15069                }
15070                long wtimeUsed = wtime - app.lastWakeTime;
15071                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15072                if (DEBUG_POWER) {
15073                    StringBuilder sb = new StringBuilder(128);
15074                    sb.append("Wake for ");
15075                    app.toShortString(sb);
15076                    sb.append(": over ");
15077                    TimeUtils.formatDuration(realtimeSince, sb);
15078                    sb.append(" used ");
15079                    TimeUtils.formatDuration(wtimeUsed, sb);
15080                    sb.append(" (");
15081                    sb.append((wtimeUsed*100)/realtimeSince);
15082                    sb.append("%)");
15083                    Slog.i(TAG, sb.toString());
15084                    sb.setLength(0);
15085                    sb.append("CPU for ");
15086                    app.toShortString(sb);
15087                    sb.append(": over ");
15088                    TimeUtils.formatDuration(uptimeSince, sb);
15089                    sb.append(" used ");
15090                    TimeUtils.formatDuration(cputimeUsed, sb);
15091                    sb.append(" (");
15092                    sb.append((cputimeUsed*100)/uptimeSince);
15093                    sb.append("%)");
15094                    Slog.i(TAG, sb.toString());
15095                }
15096                // If a process has held a wake lock for more
15097                // than 50% of the time during this period,
15098                // that sounds bad.  Kill!
15099                if (doWakeKills && realtimeSince > 0
15100                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15101                    synchronized (stats) {
15102                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15103                                realtimeSince, wtimeUsed);
15104                    }
15105                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15106                            + " during " + realtimeSince);
15107                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15108                } else if (doCpuKills && uptimeSince > 0
15109                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15110                    synchronized (stats) {
15111                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15112                                uptimeSince, cputimeUsed);
15113                    }
15114                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15115                            + " during " + uptimeSince);
15116                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15117                } else {
15118                    app.lastWakeTime = wtime;
15119                    app.lastCpuTime = app.curCpuTime;
15120                }
15121            }
15122        }
15123    }
15124
15125    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15126            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15127        boolean success = true;
15128
15129        if (app.curRawAdj != app.setRawAdj) {
15130            if (wasKeeping && !app.keeping) {
15131                // This app is no longer something we want to keep.  Note
15132                // its current wake lock time to later know to kill it if
15133                // it is not behaving well.
15134                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15135                synchronized (stats) {
15136                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15137                            app.pid, SystemClock.elapsedRealtime());
15138                }
15139                app.lastCpuTime = app.curCpuTime;
15140            }
15141
15142            app.setRawAdj = app.curRawAdj;
15143        }
15144
15145        if (app.curAdj != app.setAdj) {
15146            ProcessList.setOomAdj(app.pid, app.curAdj);
15147            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15148                TAG, "Set " + app.pid + " " + app.processName +
15149                " adj " + app.curAdj + ": " + app.adjType);
15150            app.setAdj = app.curAdj;
15151        }
15152
15153        if (app.setSchedGroup != app.curSchedGroup) {
15154            app.setSchedGroup = app.curSchedGroup;
15155            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15156                    "Setting process group of " + app.processName
15157                    + " to " + app.curSchedGroup);
15158            if (app.waitingToKill != null &&
15159                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15160                killUnneededProcessLocked(app, app.waitingToKill);
15161                success = false;
15162            } else {
15163                if (true) {
15164                    long oldId = Binder.clearCallingIdentity();
15165                    try {
15166                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15167                    } catch (Exception e) {
15168                        Slog.w(TAG, "Failed setting process group of " + app.pid
15169                                + " to " + app.curSchedGroup);
15170                        e.printStackTrace();
15171                    } finally {
15172                        Binder.restoreCallingIdentity(oldId);
15173                    }
15174                } else {
15175                    if (app.thread != null) {
15176                        try {
15177                            app.thread.setSchedulingGroup(app.curSchedGroup);
15178                        } catch (RemoteException e) {
15179                        }
15180                    }
15181                }
15182                Process.setSwappiness(app.pid,
15183                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15184            }
15185        }
15186        if (app.repProcState != app.curProcState) {
15187            app.repProcState = app.curProcState;
15188            if (!reportingProcessState && app.thread != null) {
15189                try {
15190                    if (false) {
15191                        //RuntimeException h = new RuntimeException("here");
15192                        Slog.i(TAG, "Sending new process state " + app.repProcState
15193                                + " to " + app /*, h*/);
15194                    }
15195                    app.thread.setProcessState(app.repProcState);
15196                } catch (RemoteException e) {
15197                }
15198            }
15199        }
15200        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15201                app.setProcState)) {
15202            app.lastStateTime = now;
15203            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15204                    mSleeping, now);
15205            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15206                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15207                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15208                    + (app.nextPssTime-now) + ": " + app);
15209        } else {
15210            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15211                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15212                requestPssLocked(app, app.setProcState);
15213                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15214                        mSleeping, now);
15215            } else if (false && DEBUG_PSS) {
15216                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15217            }
15218        }
15219        if (app.setProcState != app.curProcState) {
15220            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15221                    "Proc state change of " + app.processName
15222                    + " to " + app.curProcState);
15223            app.setProcState = app.curProcState;
15224            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15225                app.notCachedSinceIdle = false;
15226            }
15227            if (!doingAll) {
15228                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15229            } else {
15230                app.procStateChanged = true;
15231            }
15232        }
15233        return success;
15234    }
15235
15236    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15237        if (proc.thread != null && proc.baseProcessTracker != null) {
15238            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15239        }
15240    }
15241
15242    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15243            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15244        if (app.thread == null) {
15245            return false;
15246        }
15247
15248        final boolean wasKeeping = app.keeping;
15249
15250        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15251
15252        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15253                reportingProcessState, now);
15254    }
15255
15256    private final ActivityRecord resumedAppLocked() {
15257        return mStackSupervisor.resumedAppLocked();
15258    }
15259
15260    final boolean updateOomAdjLocked(ProcessRecord app) {
15261        return updateOomAdjLocked(app, false);
15262    }
15263
15264    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15265        final ActivityRecord TOP_ACT = resumedAppLocked();
15266        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15267        final boolean wasCached = app.cached;
15268
15269        mAdjSeq++;
15270
15271        // This is the desired cached adjusment we want to tell it to use.
15272        // If our app is currently cached, we know it, and that is it.  Otherwise,
15273        // we don't know it yet, and it needs to now be cached we will then
15274        // need to do a complete oom adj.
15275        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15276                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15277        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15278                SystemClock.uptimeMillis());
15279        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15280            // Changed to/from cached state, so apps after it in the LRU
15281            // list may also be changed.
15282            updateOomAdjLocked();
15283        }
15284        return success;
15285    }
15286
15287    final void updateOomAdjLocked() {
15288        final ActivityRecord TOP_ACT = resumedAppLocked();
15289        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15290        final long now = SystemClock.uptimeMillis();
15291        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15292        final int N = mLruProcesses.size();
15293
15294        if (false) {
15295            RuntimeException e = new RuntimeException();
15296            e.fillInStackTrace();
15297            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15298        }
15299
15300        mAdjSeq++;
15301        mNewNumServiceProcs = 0;
15302        mNewNumAServiceProcs = 0;
15303
15304        final int emptyProcessLimit;
15305        final int cachedProcessLimit;
15306        if (mProcessLimit <= 0) {
15307            emptyProcessLimit = cachedProcessLimit = 0;
15308        } else if (mProcessLimit == 1) {
15309            emptyProcessLimit = 1;
15310            cachedProcessLimit = 0;
15311        } else {
15312            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15313            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15314        }
15315
15316        // Let's determine how many processes we have running vs.
15317        // how many slots we have for background processes; we may want
15318        // to put multiple processes in a slot of there are enough of
15319        // them.
15320        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15321                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15322        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15323        if (numEmptyProcs > cachedProcessLimit) {
15324            // If there are more empty processes than our limit on cached
15325            // processes, then use the cached process limit for the factor.
15326            // This ensures that the really old empty processes get pushed
15327            // down to the bottom, so if we are running low on memory we will
15328            // have a better chance at keeping around more cached processes
15329            // instead of a gazillion empty processes.
15330            numEmptyProcs = cachedProcessLimit;
15331        }
15332        int emptyFactor = numEmptyProcs/numSlots;
15333        if (emptyFactor < 1) emptyFactor = 1;
15334        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15335        if (cachedFactor < 1) cachedFactor = 1;
15336        int stepCached = 0;
15337        int stepEmpty = 0;
15338        int numCached = 0;
15339        int numEmpty = 0;
15340        int numTrimming = 0;
15341
15342        mNumNonCachedProcs = 0;
15343        mNumCachedHiddenProcs = 0;
15344
15345        // First update the OOM adjustment for each of the
15346        // application processes based on their current state.
15347        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15348        int nextCachedAdj = curCachedAdj+1;
15349        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15350        int nextEmptyAdj = curEmptyAdj+2;
15351        for (int i=N-1; i>=0; i--) {
15352            ProcessRecord app = mLruProcesses.get(i);
15353            if (!app.killedByAm && app.thread != null) {
15354                app.procStateChanged = false;
15355                final boolean wasKeeping = app.keeping;
15356                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15357
15358                // If we haven't yet assigned the final cached adj
15359                // to the process, do that now.
15360                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15361                    switch (app.curProcState) {
15362                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15363                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15364                            // This process is a cached process holding activities...
15365                            // assign it the next cached value for that type, and then
15366                            // step that cached level.
15367                            app.curRawAdj = curCachedAdj;
15368                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15369                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15370                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15371                                    + ")");
15372                            if (curCachedAdj != nextCachedAdj) {
15373                                stepCached++;
15374                                if (stepCached >= cachedFactor) {
15375                                    stepCached = 0;
15376                                    curCachedAdj = nextCachedAdj;
15377                                    nextCachedAdj += 2;
15378                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15379                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15380                                    }
15381                                }
15382                            }
15383                            break;
15384                        default:
15385                            // For everything else, assign next empty cached process
15386                            // level and bump that up.  Note that this means that
15387                            // long-running services that have dropped down to the
15388                            // cached level will be treated as empty (since their process
15389                            // state is still as a service), which is what we want.
15390                            app.curRawAdj = curEmptyAdj;
15391                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15392                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15393                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15394                                    + ")");
15395                            if (curEmptyAdj != nextEmptyAdj) {
15396                                stepEmpty++;
15397                                if (stepEmpty >= emptyFactor) {
15398                                    stepEmpty = 0;
15399                                    curEmptyAdj = nextEmptyAdj;
15400                                    nextEmptyAdj += 2;
15401                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15402                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15403                                    }
15404                                }
15405                            }
15406                            break;
15407                    }
15408                }
15409
15410                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15411
15412                // Count the number of process types.
15413                switch (app.curProcState) {
15414                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15415                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15416                        mNumCachedHiddenProcs++;
15417                        numCached++;
15418                        if (numCached > cachedProcessLimit) {
15419                            killUnneededProcessLocked(app, "cached #" + numCached);
15420                        }
15421                        break;
15422                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15423                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15424                                && app.lastActivityTime < oldTime) {
15425                            killUnneededProcessLocked(app, "empty for "
15426                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15427                                    / 1000) + "s");
15428                        } else {
15429                            numEmpty++;
15430                            if (numEmpty > emptyProcessLimit) {
15431                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15432                            }
15433                        }
15434                        break;
15435                    default:
15436                        mNumNonCachedProcs++;
15437                        break;
15438                }
15439
15440                if (app.isolated && app.services.size() <= 0) {
15441                    // If this is an isolated process, and there are no
15442                    // services running in it, then the process is no longer
15443                    // needed.  We agressively kill these because we can by
15444                    // definition not re-use the same process again, and it is
15445                    // good to avoid having whatever code was running in them
15446                    // left sitting around after no longer needed.
15447                    killUnneededProcessLocked(app, "isolated not needed");
15448                }
15449
15450                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15451                        && !app.killedByAm) {
15452                    numTrimming++;
15453                }
15454            }
15455        }
15456
15457        mNumServiceProcs = mNewNumServiceProcs;
15458
15459        // Now determine the memory trimming level of background processes.
15460        // Unfortunately we need to start at the back of the list to do this
15461        // properly.  We only do this if the number of background apps we
15462        // are managing to keep around is less than half the maximum we desire;
15463        // if we are keeping a good number around, we'll let them use whatever
15464        // memory they want.
15465        final int numCachedAndEmpty = numCached + numEmpty;
15466        int memFactor;
15467        if (numCached <= ProcessList.TRIM_CACHED_APPS
15468                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15469            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15470                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15471            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15472                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15473            } else {
15474                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15475            }
15476        } else {
15477            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15478        }
15479        // We always allow the memory level to go up (better).  We only allow it to go
15480        // down if we are in a state where that is allowed, *and* the total number of processes
15481        // has gone down since last time.
15482        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15483                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15484                + " last=" + mLastNumProcesses);
15485        if (memFactor > mLastMemoryLevel) {
15486            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15487                memFactor = mLastMemoryLevel;
15488                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15489            }
15490        }
15491        mLastMemoryLevel = memFactor;
15492        mLastNumProcesses = mLruProcesses.size();
15493        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15494        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15495        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15496            if (mLowRamStartTime == 0) {
15497                mLowRamStartTime = now;
15498            }
15499            int step = 0;
15500            int fgTrimLevel;
15501            switch (memFactor) {
15502                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15503                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15504                    break;
15505                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15506                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15507                    break;
15508                default:
15509                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15510                    break;
15511            }
15512            int factor = numTrimming/3;
15513            int minFactor = 2;
15514            if (mHomeProcess != null) minFactor++;
15515            if (mPreviousProcess != null) minFactor++;
15516            if (factor < minFactor) factor = minFactor;
15517            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15518            for (int i=N-1; i>=0; i--) {
15519                ProcessRecord app = mLruProcesses.get(i);
15520                if (allChanged || app.procStateChanged) {
15521                    setProcessTrackerState(app, trackerMemFactor, now);
15522                    app.procStateChanged = false;
15523                }
15524                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15525                        && !app.killedByAm) {
15526                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15527                        try {
15528                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15529                                    "Trimming memory of " + app.processName
15530                                    + " to " + curLevel);
15531                            app.thread.scheduleTrimMemory(curLevel);
15532                        } catch (RemoteException e) {
15533                        }
15534                        if (false) {
15535                            // For now we won't do this; our memory trimming seems
15536                            // to be good enough at this point that destroying
15537                            // activities causes more harm than good.
15538                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15539                                    && app != mHomeProcess && app != mPreviousProcess) {
15540                                // Need to do this on its own message because the stack may not
15541                                // be in a consistent state at this point.
15542                                // For these apps we will also finish their activities
15543                                // to help them free memory.
15544                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15545                            }
15546                        }
15547                    }
15548                    app.trimMemoryLevel = curLevel;
15549                    step++;
15550                    if (step >= factor) {
15551                        step = 0;
15552                        switch (curLevel) {
15553                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15554                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15555                                break;
15556                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15557                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15558                                break;
15559                        }
15560                    }
15561                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15562                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15563                            && app.thread != null) {
15564                        try {
15565                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15566                                    "Trimming memory of heavy-weight " + app.processName
15567                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15568                            app.thread.scheduleTrimMemory(
15569                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15570                        } catch (RemoteException e) {
15571                        }
15572                    }
15573                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15574                } else {
15575                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15576                            || app.systemNoUi) && app.pendingUiClean) {
15577                        // If this application is now in the background and it
15578                        // had done UI, then give it the special trim level to
15579                        // have it free UI resources.
15580                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15581                        if (app.trimMemoryLevel < level && app.thread != null) {
15582                            try {
15583                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15584                                        "Trimming memory of bg-ui " + app.processName
15585                                        + " to " + level);
15586                                app.thread.scheduleTrimMemory(level);
15587                            } catch (RemoteException e) {
15588                            }
15589                        }
15590                        app.pendingUiClean = false;
15591                    }
15592                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15593                        try {
15594                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15595                                    "Trimming memory of fg " + app.processName
15596                                    + " to " + fgTrimLevel);
15597                            app.thread.scheduleTrimMemory(fgTrimLevel);
15598                        } catch (RemoteException e) {
15599                        }
15600                    }
15601                    app.trimMemoryLevel = fgTrimLevel;
15602                }
15603            }
15604        } else {
15605            if (mLowRamStartTime != 0) {
15606                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15607                mLowRamStartTime = 0;
15608            }
15609            for (int i=N-1; i>=0; i--) {
15610                ProcessRecord app = mLruProcesses.get(i);
15611                if (allChanged || app.procStateChanged) {
15612                    setProcessTrackerState(app, trackerMemFactor, now);
15613                    app.procStateChanged = false;
15614                }
15615                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15616                        || app.systemNoUi) && app.pendingUiClean) {
15617                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15618                            && app.thread != null) {
15619                        try {
15620                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15621                                    "Trimming memory of ui hidden " + app.processName
15622                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15623                            app.thread.scheduleTrimMemory(
15624                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15625                        } catch (RemoteException e) {
15626                        }
15627                    }
15628                    app.pendingUiClean = false;
15629                }
15630                app.trimMemoryLevel = 0;
15631            }
15632        }
15633
15634        if (mAlwaysFinishActivities) {
15635            // Need to do this on its own message because the stack may not
15636            // be in a consistent state at this point.
15637            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15638        }
15639
15640        if (allChanged) {
15641            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15642        }
15643
15644        if (mProcessStats.shouldWriteNowLocked(now)) {
15645            mHandler.post(new Runnable() {
15646                @Override public void run() {
15647                    synchronized (ActivityManagerService.this) {
15648                        mProcessStats.writeStateAsyncLocked();
15649                    }
15650                }
15651            });
15652        }
15653
15654        if (DEBUG_OOM_ADJ) {
15655            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15656        }
15657    }
15658
15659    final void trimApplications() {
15660        synchronized (this) {
15661            int i;
15662
15663            // First remove any unused application processes whose package
15664            // has been removed.
15665            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15666                final ProcessRecord app = mRemovedProcesses.get(i);
15667                if (app.activities.size() == 0
15668                        && app.curReceiver == null && app.services.size() == 0) {
15669                    Slog.i(
15670                        TAG, "Exiting empty application process "
15671                        + app.processName + " ("
15672                        + (app.thread != null ? app.thread.asBinder() : null)
15673                        + ")\n");
15674                    if (app.pid > 0 && app.pid != MY_PID) {
15675                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15676                                app.processName, app.setAdj, "empty");
15677                        app.killedByAm = true;
15678                        Process.killProcessQuiet(app.pid);
15679                    } else {
15680                        try {
15681                            app.thread.scheduleExit();
15682                        } catch (Exception e) {
15683                            // Ignore exceptions.
15684                        }
15685                    }
15686                    cleanUpApplicationRecordLocked(app, false, true, -1);
15687                    mRemovedProcesses.remove(i);
15688
15689                    if (app.persistent) {
15690                        if (app.persistent) {
15691                            addAppLocked(app.info, false);
15692                        }
15693                    }
15694                }
15695            }
15696
15697            // Now update the oom adj for all processes.
15698            updateOomAdjLocked();
15699        }
15700    }
15701
15702    /** This method sends the specified signal to each of the persistent apps */
15703    public void signalPersistentProcesses(int sig) throws RemoteException {
15704        if (sig != Process.SIGNAL_USR1) {
15705            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15706        }
15707
15708        synchronized (this) {
15709            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15710                    != PackageManager.PERMISSION_GRANTED) {
15711                throw new SecurityException("Requires permission "
15712                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15713            }
15714
15715            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15716                ProcessRecord r = mLruProcesses.get(i);
15717                if (r.thread != null && r.persistent) {
15718                    Process.sendSignal(r.pid, sig);
15719                }
15720            }
15721        }
15722    }
15723
15724    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15725        if (proc == null || proc == mProfileProc) {
15726            proc = mProfileProc;
15727            path = mProfileFile;
15728            profileType = mProfileType;
15729            clearProfilerLocked();
15730        }
15731        if (proc == null) {
15732            return;
15733        }
15734        try {
15735            proc.thread.profilerControl(false, path, null, profileType);
15736        } catch (RemoteException e) {
15737            throw new IllegalStateException("Process disappeared");
15738        }
15739    }
15740
15741    private void clearProfilerLocked() {
15742        if (mProfileFd != null) {
15743            try {
15744                mProfileFd.close();
15745            } catch (IOException e) {
15746            }
15747        }
15748        mProfileApp = null;
15749        mProfileProc = null;
15750        mProfileFile = null;
15751        mProfileType = 0;
15752        mAutoStopProfiler = false;
15753    }
15754
15755    public boolean profileControl(String process, int userId, boolean start,
15756            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15757
15758        try {
15759            synchronized (this) {
15760                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15761                // its own permission.
15762                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15763                        != PackageManager.PERMISSION_GRANTED) {
15764                    throw new SecurityException("Requires permission "
15765                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15766                }
15767
15768                if (start && fd == null) {
15769                    throw new IllegalArgumentException("null fd");
15770                }
15771
15772                ProcessRecord proc = null;
15773                if (process != null) {
15774                    proc = findProcessLocked(process, userId, "profileControl");
15775                }
15776
15777                if (start && (proc == null || proc.thread == null)) {
15778                    throw new IllegalArgumentException("Unknown process: " + process);
15779                }
15780
15781                if (start) {
15782                    stopProfilerLocked(null, null, 0);
15783                    setProfileApp(proc.info, proc.processName, path, fd, false);
15784                    mProfileProc = proc;
15785                    mProfileType = profileType;
15786                    try {
15787                        fd = fd.dup();
15788                    } catch (IOException e) {
15789                        fd = null;
15790                    }
15791                    proc.thread.profilerControl(start, path, fd, profileType);
15792                    fd = null;
15793                    mProfileFd = null;
15794                } else {
15795                    stopProfilerLocked(proc, path, profileType);
15796                    if (fd != null) {
15797                        try {
15798                            fd.close();
15799                        } catch (IOException e) {
15800                        }
15801                    }
15802                }
15803
15804                return true;
15805            }
15806        } catch (RemoteException e) {
15807            throw new IllegalStateException("Process disappeared");
15808        } finally {
15809            if (fd != null) {
15810                try {
15811                    fd.close();
15812                } catch (IOException e) {
15813                }
15814            }
15815        }
15816    }
15817
15818    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15819        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15820                userId, true, true, callName, null);
15821        ProcessRecord proc = null;
15822        try {
15823            int pid = Integer.parseInt(process);
15824            synchronized (mPidsSelfLocked) {
15825                proc = mPidsSelfLocked.get(pid);
15826            }
15827        } catch (NumberFormatException e) {
15828        }
15829
15830        if (proc == null) {
15831            ArrayMap<String, SparseArray<ProcessRecord>> all
15832                    = mProcessNames.getMap();
15833            SparseArray<ProcessRecord> procs = all.get(process);
15834            if (procs != null && procs.size() > 0) {
15835                proc = procs.valueAt(0);
15836                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15837                    for (int i=1; i<procs.size(); i++) {
15838                        ProcessRecord thisProc = procs.valueAt(i);
15839                        if (thisProc.userId == userId) {
15840                            proc = thisProc;
15841                            break;
15842                        }
15843                    }
15844                }
15845            }
15846        }
15847
15848        return proc;
15849    }
15850
15851    public boolean dumpHeap(String process, int userId, boolean managed,
15852            String path, ParcelFileDescriptor fd) throws RemoteException {
15853
15854        try {
15855            synchronized (this) {
15856                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15857                // its own permission (same as profileControl).
15858                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15859                        != PackageManager.PERMISSION_GRANTED) {
15860                    throw new SecurityException("Requires permission "
15861                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15862                }
15863
15864                if (fd == null) {
15865                    throw new IllegalArgumentException("null fd");
15866                }
15867
15868                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15869                if (proc == null || proc.thread == null) {
15870                    throw new IllegalArgumentException("Unknown process: " + process);
15871                }
15872
15873                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15874                if (!isDebuggable) {
15875                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15876                        throw new SecurityException("Process not debuggable: " + proc);
15877                    }
15878                }
15879
15880                proc.thread.dumpHeap(managed, path, fd);
15881                fd = null;
15882                return true;
15883            }
15884        } catch (RemoteException e) {
15885            throw new IllegalStateException("Process disappeared");
15886        } finally {
15887            if (fd != null) {
15888                try {
15889                    fd.close();
15890                } catch (IOException e) {
15891                }
15892            }
15893        }
15894    }
15895
15896    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15897    public void monitor() {
15898        synchronized (this) { }
15899    }
15900
15901    void onCoreSettingsChange(Bundle settings) {
15902        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15903            ProcessRecord processRecord = mLruProcesses.get(i);
15904            try {
15905                if (processRecord.thread != null) {
15906                    processRecord.thread.setCoreSettings(settings);
15907                }
15908            } catch (RemoteException re) {
15909                /* ignore */
15910            }
15911        }
15912    }
15913
15914    // Multi-user methods
15915
15916    @Override
15917    public boolean switchUser(final int userId) {
15918        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15919                != PackageManager.PERMISSION_GRANTED) {
15920            String msg = "Permission Denial: switchUser() from pid="
15921                    + Binder.getCallingPid()
15922                    + ", uid=" + Binder.getCallingUid()
15923                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15924            Slog.w(TAG, msg);
15925            throw new SecurityException(msg);
15926        }
15927
15928        final long ident = Binder.clearCallingIdentity();
15929        try {
15930            synchronized (this) {
15931                final int oldUserId = mCurrentUserId;
15932                if (oldUserId == userId) {
15933                    return true;
15934                }
15935
15936                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15937                if (userInfo == null) {
15938                    Slog.w(TAG, "No user info for user #" + userId);
15939                    return false;
15940                }
15941
15942                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15943                        R.anim.screen_user_enter);
15944
15945                boolean needStart = false;
15946
15947                // If the user we are switching to is not currently started, then
15948                // we need to start it now.
15949                if (mStartedUsers.get(userId) == null) {
15950                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
15951                    updateStartedUserArrayLocked();
15952                    needStart = true;
15953                }
15954
15955                mCurrentUserId = userId;
15956                final Integer userIdInt = Integer.valueOf(userId);
15957                mUserLru.remove(userIdInt);
15958                mUserLru.add(userIdInt);
15959
15960                mWindowManager.setCurrentUser(userId);
15961
15962                // Once the internal notion of the active user has switched, we lock the device
15963                // with the option to show the user switcher on the keyguard.
15964                mWindowManager.lockNow(null);
15965
15966                final UserStartedState uss = mStartedUsers.get(userId);
15967
15968                // Make sure user is in the started state.  If it is currently
15969                // stopping, we need to knock that off.
15970                if (uss.mState == UserStartedState.STATE_STOPPING) {
15971                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
15972                    // so we can just fairly silently bring the user back from
15973                    // the almost-dead.
15974                    uss.mState = UserStartedState.STATE_RUNNING;
15975                    updateStartedUserArrayLocked();
15976                    needStart = true;
15977                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
15978                    // This means ACTION_SHUTDOWN has been sent, so we will
15979                    // need to treat this as a new boot of the user.
15980                    uss.mState = UserStartedState.STATE_BOOTING;
15981                    updateStartedUserArrayLocked();
15982                    needStart = true;
15983                }
15984
15985                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
15986                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
15987                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
15988                        oldUserId, userId, uss));
15989                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
15990                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
15991                if (needStart) {
15992                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
15993                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15994                            | Intent.FLAG_RECEIVER_FOREGROUND);
15995                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
15996                    broadcastIntentLocked(null, null, intent,
15997                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15998                            false, false, MY_PID, Process.SYSTEM_UID, userId);
15999                }
16000
16001                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16002                    if (userId != 0) {
16003                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16004                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16005                        broadcastIntentLocked(null, null, intent, null,
16006                                new IIntentReceiver.Stub() {
16007                                    public void performReceive(Intent intent, int resultCode,
16008                                            String data, Bundle extras, boolean ordered,
16009                                            boolean sticky, int sendingUser) {
16010                                        userInitialized(uss, userId);
16011                                    }
16012                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16013                                true, false, MY_PID, Process.SYSTEM_UID,
16014                                userId);
16015                        uss.initializing = true;
16016                    } else {
16017                        getUserManagerLocked().makeInitialized(userInfo.id);
16018                    }
16019                }
16020
16021                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16022                if (homeInFront) {
16023                    startHomeActivityLocked(userId);
16024                } else {
16025                    mStackSupervisor.resumeTopActivitiesLocked();
16026                }
16027
16028                EventLogTags.writeAmSwitchUser(userId);
16029                getUserManagerLocked().userForeground(userId);
16030                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16031                if (needStart) {
16032                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16033                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16034                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16035                    broadcastIntentLocked(null, null, intent,
16036                            null, new IIntentReceiver.Stub() {
16037                                @Override
16038                                public void performReceive(Intent intent, int resultCode, String data,
16039                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16040                                        throws RemoteException {
16041                                }
16042                            }, 0, null, null,
16043                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16044                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16045                }
16046            }
16047        } finally {
16048            Binder.restoreCallingIdentity(ident);
16049        }
16050
16051        return true;
16052    }
16053
16054    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16055        long ident = Binder.clearCallingIdentity();
16056        try {
16057            Intent intent;
16058            if (oldUserId >= 0) {
16059                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16060                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16061                        | Intent.FLAG_RECEIVER_FOREGROUND);
16062                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16063                broadcastIntentLocked(null, null, intent,
16064                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16065                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16066            }
16067            if (newUserId >= 0) {
16068                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16069                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16070                        | Intent.FLAG_RECEIVER_FOREGROUND);
16071                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16072                broadcastIntentLocked(null, null, intent,
16073                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16074                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16075                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16076                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16077                        | Intent.FLAG_RECEIVER_FOREGROUND);
16078                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16079                broadcastIntentLocked(null, null, intent,
16080                        null, null, 0, null, null,
16081                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16082                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16083            }
16084        } finally {
16085            Binder.restoreCallingIdentity(ident);
16086        }
16087    }
16088
16089    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16090            final int newUserId) {
16091        final int N = mUserSwitchObservers.beginBroadcast();
16092        if (N > 0) {
16093            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16094                int mCount = 0;
16095                @Override
16096                public void sendResult(Bundle data) throws RemoteException {
16097                    synchronized (ActivityManagerService.this) {
16098                        if (mCurUserSwitchCallback == this) {
16099                            mCount++;
16100                            if (mCount == N) {
16101                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16102                            }
16103                        }
16104                    }
16105                }
16106            };
16107            synchronized (this) {
16108                uss.switching = true;
16109                mCurUserSwitchCallback = callback;
16110            }
16111            for (int i=0; i<N; i++) {
16112                try {
16113                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16114                            newUserId, callback);
16115                } catch (RemoteException e) {
16116                }
16117            }
16118        } else {
16119            synchronized (this) {
16120                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16121            }
16122        }
16123        mUserSwitchObservers.finishBroadcast();
16124    }
16125
16126    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16127        synchronized (this) {
16128            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16129            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16130        }
16131    }
16132
16133    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16134        mCurUserSwitchCallback = null;
16135        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16136        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16137                oldUserId, newUserId, uss));
16138    }
16139
16140    void userInitialized(UserStartedState uss, int newUserId) {
16141        completeSwitchAndInitalize(uss, newUserId, true, false);
16142    }
16143
16144    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16145        completeSwitchAndInitalize(uss, newUserId, false, true);
16146    }
16147
16148    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16149            boolean clearInitializing, boolean clearSwitching) {
16150        boolean unfrozen = false;
16151        synchronized (this) {
16152            if (clearInitializing) {
16153                uss.initializing = false;
16154                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16155            }
16156            if (clearSwitching) {
16157                uss.switching = false;
16158            }
16159            if (!uss.switching && !uss.initializing) {
16160                mWindowManager.stopFreezingScreen();
16161                unfrozen = true;
16162            }
16163        }
16164        if (unfrozen) {
16165            final int N = mUserSwitchObservers.beginBroadcast();
16166            for (int i=0; i<N; i++) {
16167                try {
16168                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16169                } catch (RemoteException e) {
16170                }
16171            }
16172            mUserSwitchObservers.finishBroadcast();
16173        }
16174    }
16175
16176    void finishUserSwitch(UserStartedState uss) {
16177        synchronized (this) {
16178            if (uss.mState == UserStartedState.STATE_BOOTING
16179                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16180                uss.mState = UserStartedState.STATE_RUNNING;
16181                final int userId = uss.mHandle.getIdentifier();
16182                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16183                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16184                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16185                broadcastIntentLocked(null, null, intent,
16186                        null, null, 0, null, null,
16187                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16188                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16189            }
16190            int num = mUserLru.size();
16191            int i = 0;
16192            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16193                Integer oldUserId = mUserLru.get(i);
16194                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16195                if (oldUss == null) {
16196                    // Shouldn't happen, but be sane if it does.
16197                    mUserLru.remove(i);
16198                    num--;
16199                    continue;
16200                }
16201                if (oldUss.mState == UserStartedState.STATE_STOPPING
16202                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16203                    // This user is already stopping, doesn't count.
16204                    num--;
16205                    i++;
16206                    continue;
16207                }
16208                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16209                    // Owner and current can't be stopped, but count as running.
16210                    i++;
16211                    continue;
16212                }
16213                // This is a user to be stopped.
16214                stopUserLocked(oldUserId, null);
16215                num--;
16216                i++;
16217            }
16218        }
16219    }
16220
16221    @Override
16222    public int stopUser(final int userId, final IStopUserCallback callback) {
16223        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16224                != PackageManager.PERMISSION_GRANTED) {
16225            String msg = "Permission Denial: switchUser() from pid="
16226                    + Binder.getCallingPid()
16227                    + ", uid=" + Binder.getCallingUid()
16228                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16229            Slog.w(TAG, msg);
16230            throw new SecurityException(msg);
16231        }
16232        if (userId <= 0) {
16233            throw new IllegalArgumentException("Can't stop primary user " + userId);
16234        }
16235        synchronized (this) {
16236            return stopUserLocked(userId, callback);
16237        }
16238    }
16239
16240    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16241        if (mCurrentUserId == userId) {
16242            return ActivityManager.USER_OP_IS_CURRENT;
16243        }
16244
16245        final UserStartedState uss = mStartedUsers.get(userId);
16246        if (uss == null) {
16247            // User is not started, nothing to do...  but we do need to
16248            // callback if requested.
16249            if (callback != null) {
16250                mHandler.post(new Runnable() {
16251                    @Override
16252                    public void run() {
16253                        try {
16254                            callback.userStopped(userId);
16255                        } catch (RemoteException e) {
16256                        }
16257                    }
16258                });
16259            }
16260            return ActivityManager.USER_OP_SUCCESS;
16261        }
16262
16263        if (callback != null) {
16264            uss.mStopCallbacks.add(callback);
16265        }
16266
16267        if (uss.mState != UserStartedState.STATE_STOPPING
16268                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16269            uss.mState = UserStartedState.STATE_STOPPING;
16270            updateStartedUserArrayLocked();
16271
16272            long ident = Binder.clearCallingIdentity();
16273            try {
16274                // We are going to broadcast ACTION_USER_STOPPING and then
16275                // once that is done send a final ACTION_SHUTDOWN and then
16276                // stop the user.
16277                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16278                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16279                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16280                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16281                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16282                // This is the result receiver for the final shutdown broadcast.
16283                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16284                    @Override
16285                    public void performReceive(Intent intent, int resultCode, String data,
16286                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16287                        finishUserStop(uss);
16288                    }
16289                };
16290                // This is the result receiver for the initial stopping broadcast.
16291                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16292                    @Override
16293                    public void performReceive(Intent intent, int resultCode, String data,
16294                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16295                        // On to the next.
16296                        synchronized (ActivityManagerService.this) {
16297                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16298                                // Whoops, we are being started back up.  Abort, abort!
16299                                return;
16300                            }
16301                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16302                        }
16303                        broadcastIntentLocked(null, null, shutdownIntent,
16304                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16305                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16306                    }
16307                };
16308                // Kick things off.
16309                broadcastIntentLocked(null, null, stoppingIntent,
16310                        null, stoppingReceiver, 0, null, null,
16311                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16312                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16313            } finally {
16314                Binder.restoreCallingIdentity(ident);
16315            }
16316        }
16317
16318        return ActivityManager.USER_OP_SUCCESS;
16319    }
16320
16321    void finishUserStop(UserStartedState uss) {
16322        final int userId = uss.mHandle.getIdentifier();
16323        boolean stopped;
16324        ArrayList<IStopUserCallback> callbacks;
16325        synchronized (this) {
16326            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16327            if (mStartedUsers.get(userId) != uss) {
16328                stopped = false;
16329            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16330                stopped = false;
16331            } else {
16332                stopped = true;
16333                // User can no longer run.
16334                mStartedUsers.remove(userId);
16335                mUserLru.remove(Integer.valueOf(userId));
16336                updateStartedUserArrayLocked();
16337
16338                // Clean up all state and processes associated with the user.
16339                // Kill all the processes for the user.
16340                forceStopUserLocked(userId, "finish user");
16341            }
16342        }
16343
16344        for (int i=0; i<callbacks.size(); i++) {
16345            try {
16346                if (stopped) callbacks.get(i).userStopped(userId);
16347                else callbacks.get(i).userStopAborted(userId);
16348            } catch (RemoteException e) {
16349            }
16350        }
16351
16352        mStackSupervisor.removeUserLocked(userId);
16353    }
16354
16355    @Override
16356    public UserInfo getCurrentUser() {
16357        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16358                != PackageManager.PERMISSION_GRANTED) && (
16359                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16360                != PackageManager.PERMISSION_GRANTED)) {
16361            String msg = "Permission Denial: getCurrentUser() from pid="
16362                    + Binder.getCallingPid()
16363                    + ", uid=" + Binder.getCallingUid()
16364                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16365            Slog.w(TAG, msg);
16366            throw new SecurityException(msg);
16367        }
16368        synchronized (this) {
16369            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16370        }
16371    }
16372
16373    int getCurrentUserIdLocked() {
16374        return mCurrentUserId;
16375    }
16376
16377    @Override
16378    public boolean isUserRunning(int userId, boolean orStopped) {
16379        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16380                != PackageManager.PERMISSION_GRANTED) {
16381            String msg = "Permission Denial: isUserRunning() from pid="
16382                    + Binder.getCallingPid()
16383                    + ", uid=" + Binder.getCallingUid()
16384                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16385            Slog.w(TAG, msg);
16386            throw new SecurityException(msg);
16387        }
16388        synchronized (this) {
16389            return isUserRunningLocked(userId, orStopped);
16390        }
16391    }
16392
16393    boolean isUserRunningLocked(int userId, boolean orStopped) {
16394        UserStartedState state = mStartedUsers.get(userId);
16395        if (state == null) {
16396            return false;
16397        }
16398        if (orStopped) {
16399            return true;
16400        }
16401        return state.mState != UserStartedState.STATE_STOPPING
16402                && state.mState != UserStartedState.STATE_SHUTDOWN;
16403    }
16404
16405    @Override
16406    public int[] getRunningUserIds() {
16407        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16408                != PackageManager.PERMISSION_GRANTED) {
16409            String msg = "Permission Denial: isUserRunning() from pid="
16410                    + Binder.getCallingPid()
16411                    + ", uid=" + Binder.getCallingUid()
16412                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16413            Slog.w(TAG, msg);
16414            throw new SecurityException(msg);
16415        }
16416        synchronized (this) {
16417            return mStartedUserArray;
16418        }
16419    }
16420
16421    private void updateStartedUserArrayLocked() {
16422        int num = 0;
16423        for (int i=0; i<mStartedUsers.size();  i++) {
16424            UserStartedState uss = mStartedUsers.valueAt(i);
16425            // This list does not include stopping users.
16426            if (uss.mState != UserStartedState.STATE_STOPPING
16427                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16428                num++;
16429            }
16430        }
16431        mStartedUserArray = new int[num];
16432        num = 0;
16433        for (int i=0; i<mStartedUsers.size();  i++) {
16434            UserStartedState uss = mStartedUsers.valueAt(i);
16435            if (uss.mState != UserStartedState.STATE_STOPPING
16436                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16437                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16438                num++;
16439            }
16440        }
16441    }
16442
16443    @Override
16444    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16445        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16446                != PackageManager.PERMISSION_GRANTED) {
16447            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16448                    + Binder.getCallingPid()
16449                    + ", uid=" + Binder.getCallingUid()
16450                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16451            Slog.w(TAG, msg);
16452            throw new SecurityException(msg);
16453        }
16454
16455        mUserSwitchObservers.register(observer);
16456    }
16457
16458    @Override
16459    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16460        mUserSwitchObservers.unregister(observer);
16461    }
16462
16463    private boolean userExists(int userId) {
16464        if (userId == 0) {
16465            return true;
16466        }
16467        UserManagerService ums = getUserManagerLocked();
16468        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16469    }
16470
16471    int[] getUsersLocked() {
16472        UserManagerService ums = getUserManagerLocked();
16473        return ums != null ? ums.getUserIds() : new int[] { 0 };
16474    }
16475
16476    UserManagerService getUserManagerLocked() {
16477        if (mUserManager == null) {
16478            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16479            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16480        }
16481        return mUserManager;
16482    }
16483
16484    private int applyUserId(int uid, int userId) {
16485        return UserHandle.getUid(userId, uid);
16486    }
16487
16488    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16489        if (info == null) return null;
16490        ApplicationInfo newInfo = new ApplicationInfo(info);
16491        newInfo.uid = applyUserId(info.uid, userId);
16492        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16493                + info.packageName;
16494        return newInfo;
16495    }
16496
16497    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16498        if (aInfo == null
16499                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16500            return aInfo;
16501        }
16502
16503        ActivityInfo info = new ActivityInfo(aInfo);
16504        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16505        return info;
16506    }
16507
16508    private final class LocalService extends ActivityManagerInternal {
16509        @Override
16510        public void goingToSleep() {
16511            ActivityManagerService.this.goingToSleep();
16512        }
16513
16514        @Override
16515        public void wakingUp() {
16516            ActivityManagerService.this.wakingUp();
16517        }
16518    }
16519}
16520