ActivityManagerService.java revision 13014b5fe5967b3c7e232ffaf81581ed178e6df6
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    final ServiceThread mHandlerThread;
1078    final MainHandler mHandler;
1079
1080    final class MainHandler extends Handler {
1081        public MainHandler(Looper looper) {
1082            super(looper, null, true);
1083        }
1084
1085        @Override
1086        public void handleMessage(Message msg) {
1087            switch (msg.what) {
1088            case SHOW_ERROR_MSG: {
1089                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1090                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1091                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1092                synchronized (ActivityManagerService.this) {
1093                    ProcessRecord proc = (ProcessRecord)data.get("app");
1094                    AppErrorResult res = (AppErrorResult) data.get("result");
1095                    if (proc != null && proc.crashDialog != null) {
1096                        Slog.e(TAG, "App already has crash dialog: " + proc);
1097                        if (res != null) {
1098                            res.set(0);
1099                        }
1100                        return;
1101                    }
1102                    if (!showBackground && UserHandle.getAppId(proc.uid)
1103                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1104                            && proc.pid != MY_PID) {
1105                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1106                        if (res != null) {
1107                            res.set(0);
1108                        }
1109                        return;
1110                    }
1111                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1112                        Dialog d = new AppErrorDialog(mContext,
1113                                ActivityManagerService.this, res, proc);
1114                        d.show();
1115                        proc.crashDialog = d;
1116                    } else {
1117                        // The device is asleep, so just pretend that the user
1118                        // saw a crash dialog and hit "force quit".
1119                        if (res != null) {
1120                            res.set(0);
1121                        }
1122                    }
1123                }
1124
1125                ensureBootCompleted();
1126            } break;
1127            case SHOW_NOT_RESPONDING_MSG: {
1128                synchronized (ActivityManagerService.this) {
1129                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1130                    ProcessRecord proc = (ProcessRecord)data.get("app");
1131                    if (proc != null && proc.anrDialog != null) {
1132                        Slog.e(TAG, "App already has anr dialog: " + proc);
1133                        return;
1134                    }
1135
1136                    Intent intent = new Intent("android.intent.action.ANR");
1137                    if (!mProcessesReady) {
1138                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1139                                | Intent.FLAG_RECEIVER_FOREGROUND);
1140                    }
1141                    broadcastIntentLocked(null, null, intent,
1142                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1143                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1144
1145                    if (mShowDialogs) {
1146                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1147                                mContext, proc, (ActivityRecord)data.get("activity"),
1148                                msg.arg1 != 0);
1149                        d.show();
1150                        proc.anrDialog = d;
1151                    } else {
1152                        // Just kill the app if there is no dialog to be shown.
1153                        killAppAtUsersRequest(proc, null);
1154                    }
1155                }
1156
1157                ensureBootCompleted();
1158            } break;
1159            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1160                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1161                synchronized (ActivityManagerService.this) {
1162                    ProcessRecord proc = (ProcessRecord) data.get("app");
1163                    if (proc == null) {
1164                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1165                        break;
1166                    }
1167                    if (proc.crashDialog != null) {
1168                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1169                        return;
1170                    }
1171                    AppErrorResult res = (AppErrorResult) data.get("result");
1172                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1173                        Dialog d = new StrictModeViolationDialog(mContext,
1174                                ActivityManagerService.this, res, proc);
1175                        d.show();
1176                        proc.crashDialog = d;
1177                    } else {
1178                        // The device is asleep, so just pretend that the user
1179                        // saw a crash dialog and hit "force quit".
1180                        res.set(0);
1181                    }
1182                }
1183                ensureBootCompleted();
1184            } break;
1185            case SHOW_FACTORY_ERROR_MSG: {
1186                Dialog d = new FactoryErrorDialog(
1187                    mContext, msg.getData().getCharSequence("msg"));
1188                d.show();
1189                ensureBootCompleted();
1190            } break;
1191            case UPDATE_CONFIGURATION_MSG: {
1192                final ContentResolver resolver = mContext.getContentResolver();
1193                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1194            } break;
1195            case GC_BACKGROUND_PROCESSES_MSG: {
1196                synchronized (ActivityManagerService.this) {
1197                    performAppGcsIfAppropriateLocked();
1198                }
1199            } break;
1200            case WAIT_FOR_DEBUGGER_MSG: {
1201                synchronized (ActivityManagerService.this) {
1202                    ProcessRecord app = (ProcessRecord)msg.obj;
1203                    if (msg.arg1 != 0) {
1204                        if (!app.waitedForDebugger) {
1205                            Dialog d = new AppWaitingForDebuggerDialog(
1206                                    ActivityManagerService.this,
1207                                    mContext, app);
1208                            app.waitDialog = d;
1209                            app.waitedForDebugger = true;
1210                            d.show();
1211                        }
1212                    } else {
1213                        if (app.waitDialog != null) {
1214                            app.waitDialog.dismiss();
1215                            app.waitDialog = null;
1216                        }
1217                    }
1218                }
1219            } break;
1220            case SERVICE_TIMEOUT_MSG: {
1221                if (mDidDexOpt) {
1222                    mDidDexOpt = false;
1223                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1224                    nmsg.obj = msg.obj;
1225                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1226                    return;
1227                }
1228                mServices.serviceTimeout((ProcessRecord)msg.obj);
1229            } break;
1230            case UPDATE_TIME_ZONE: {
1231                synchronized (ActivityManagerService.this) {
1232                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1233                        ProcessRecord r = mLruProcesses.get(i);
1234                        if (r.thread != null) {
1235                            try {
1236                                r.thread.updateTimeZone();
1237                            } catch (RemoteException ex) {
1238                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1239                            }
1240                        }
1241                    }
1242                }
1243            } break;
1244            case CLEAR_DNS_CACHE_MSG: {
1245                synchronized (ActivityManagerService.this) {
1246                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1247                        ProcessRecord r = mLruProcesses.get(i);
1248                        if (r.thread != null) {
1249                            try {
1250                                r.thread.clearDnsCache();
1251                            } catch (RemoteException ex) {
1252                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1253                            }
1254                        }
1255                    }
1256                }
1257            } break;
1258            case UPDATE_HTTP_PROXY_MSG: {
1259                ProxyProperties proxy = (ProxyProperties)msg.obj;
1260                String host = "";
1261                String port = "";
1262                String exclList = "";
1263                String pacFileUrl = null;
1264                if (proxy != null) {
1265                    host = proxy.getHost();
1266                    port = Integer.toString(proxy.getPort());
1267                    exclList = proxy.getExclusionList();
1268                    pacFileUrl = proxy.getPacFileUrl();
1269                }
1270                synchronized (ActivityManagerService.this) {
1271                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1272                        ProcessRecord r = mLruProcesses.get(i);
1273                        if (r.thread != null) {
1274                            try {
1275                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1276                            } catch (RemoteException ex) {
1277                                Slog.w(TAG, "Failed to update http proxy for: " +
1278                                        r.info.processName);
1279                            }
1280                        }
1281                    }
1282                }
1283            } break;
1284            case SHOW_UID_ERROR_MSG: {
1285                String title = "System UIDs Inconsistent";
1286                String text = "UIDs on the system are inconsistent, you need to wipe your"
1287                        + " data partition or your device will be unstable.";
1288                Log.e(TAG, title + ": " + text);
1289                if (mShowDialogs) {
1290                    // XXX This is a temporary dialog, no need to localize.
1291                    AlertDialog d = new BaseErrorDialog(mContext);
1292                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1293                    d.setCancelable(false);
1294                    d.setTitle(title);
1295                    d.setMessage(text);
1296                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1297                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1298                    mUidAlert = d;
1299                    d.show();
1300                }
1301            } break;
1302            case IM_FEELING_LUCKY_MSG: {
1303                if (mUidAlert != null) {
1304                    mUidAlert.dismiss();
1305                    mUidAlert = null;
1306                }
1307            } break;
1308            case PROC_START_TIMEOUT_MSG: {
1309                if (mDidDexOpt) {
1310                    mDidDexOpt = false;
1311                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1312                    nmsg.obj = msg.obj;
1313                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1314                    return;
1315                }
1316                ProcessRecord app = (ProcessRecord)msg.obj;
1317                synchronized (ActivityManagerService.this) {
1318                    processStartTimedOutLocked(app);
1319                }
1320            } break;
1321            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1322                synchronized (ActivityManagerService.this) {
1323                    doPendingActivityLaunchesLocked(true);
1324                }
1325            } break;
1326            case KILL_APPLICATION_MSG: {
1327                synchronized (ActivityManagerService.this) {
1328                    int appid = msg.arg1;
1329                    boolean restart = (msg.arg2 == 1);
1330                    Bundle bundle = (Bundle)msg.obj;
1331                    String pkg = bundle.getString("pkg");
1332                    String reason = bundle.getString("reason");
1333                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1334                            UserHandle.USER_ALL, reason);
1335                }
1336            } break;
1337            case FINALIZE_PENDING_INTENT_MSG: {
1338                ((PendingIntentRecord)msg.obj).completeFinalize();
1339            } break;
1340            case POST_HEAVY_NOTIFICATION_MSG: {
1341                INotificationManager inm = NotificationManager.getService();
1342                if (inm == null) {
1343                    return;
1344                }
1345
1346                ActivityRecord root = (ActivityRecord)msg.obj;
1347                ProcessRecord process = root.app;
1348                if (process == null) {
1349                    return;
1350                }
1351
1352                try {
1353                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1354                    String text = mContext.getString(R.string.heavy_weight_notification,
1355                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1356                    Notification notification = new Notification();
1357                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1358                    notification.when = 0;
1359                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1360                    notification.tickerText = text;
1361                    notification.defaults = 0; // please be quiet
1362                    notification.sound = null;
1363                    notification.vibrate = null;
1364                    notification.setLatestEventInfo(context, text,
1365                            mContext.getText(R.string.heavy_weight_notification_detail),
1366                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1367                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1368                                    new UserHandle(root.userId)));
1369
1370                    try {
1371                        int[] outId = new int[1];
1372                        inm.enqueueNotificationWithTag("android", "android", null,
1373                                R.string.heavy_weight_notification,
1374                                notification, outId, root.userId);
1375                    } catch (RuntimeException e) {
1376                        Slog.w(ActivityManagerService.TAG,
1377                                "Error showing notification for heavy-weight app", e);
1378                    } catch (RemoteException e) {
1379                    }
1380                } catch (NameNotFoundException e) {
1381                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1382                }
1383            } break;
1384            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1385                INotificationManager inm = NotificationManager.getService();
1386                if (inm == null) {
1387                    return;
1388                }
1389                try {
1390                    inm.cancelNotificationWithTag("android", null,
1391                            R.string.heavy_weight_notification,  msg.arg1);
1392                } catch (RuntimeException e) {
1393                    Slog.w(ActivityManagerService.TAG,
1394                            "Error canceling notification for service", e);
1395                } catch (RemoteException e) {
1396                }
1397            } break;
1398            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1399                synchronized (ActivityManagerService.this) {
1400                    checkExcessivePowerUsageLocked(true);
1401                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1402                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1403                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1404                }
1405            } break;
1406            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1407                synchronized (ActivityManagerService.this) {
1408                    ActivityRecord ar = (ActivityRecord)msg.obj;
1409                    if (mCompatModeDialog != null) {
1410                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1411                                ar.info.applicationInfo.packageName)) {
1412                            return;
1413                        }
1414                        mCompatModeDialog.dismiss();
1415                        mCompatModeDialog = null;
1416                    }
1417                    if (ar != null && false) {
1418                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1419                                ar.packageName)) {
1420                            int mode = mCompatModePackages.computeCompatModeLocked(
1421                                    ar.info.applicationInfo);
1422                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1423                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1424                                mCompatModeDialog = new CompatModeDialog(
1425                                        ActivityManagerService.this, mContext,
1426                                        ar.info.applicationInfo);
1427                                mCompatModeDialog.show();
1428                            }
1429                        }
1430                    }
1431                }
1432                break;
1433            }
1434            case DISPATCH_PROCESSES_CHANGED: {
1435                dispatchProcessesChanged();
1436                break;
1437            }
1438            case DISPATCH_PROCESS_DIED: {
1439                final int pid = msg.arg1;
1440                final int uid = msg.arg2;
1441                dispatchProcessDied(pid, uid);
1442                break;
1443            }
1444            case REPORT_MEM_USAGE_MSG: {
1445                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1446                Thread thread = new Thread() {
1447                    @Override public void run() {
1448                        final SparseArray<ProcessMemInfo> infoMap
1449                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1450                        for (int i=0, N=memInfos.size(); i<N; i++) {
1451                            ProcessMemInfo mi = memInfos.get(i);
1452                            infoMap.put(mi.pid, mi);
1453                        }
1454                        updateCpuStatsNow();
1455                        synchronized (mProcessCpuThread) {
1456                            final int N = mProcessCpuTracker.countStats();
1457                            for (int i=0; i<N; i++) {
1458                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1459                                if (st.vsize > 0) {
1460                                    long pss = Debug.getPss(st.pid, null);
1461                                    if (pss > 0) {
1462                                        if (infoMap.indexOfKey(st.pid) < 0) {
1463                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1464                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1465                                            mi.pss = pss;
1466                                            memInfos.add(mi);
1467                                        }
1468                                    }
1469                                }
1470                            }
1471                        }
1472
1473                        long totalPss = 0;
1474                        for (int i=0, N=memInfos.size(); i<N; i++) {
1475                            ProcessMemInfo mi = memInfos.get(i);
1476                            if (mi.pss == 0) {
1477                                mi.pss = Debug.getPss(mi.pid, null);
1478                            }
1479                            totalPss += mi.pss;
1480                        }
1481                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1482                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1483                                if (lhs.oomAdj != rhs.oomAdj) {
1484                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1485                                }
1486                                if (lhs.pss != rhs.pss) {
1487                                    return lhs.pss < rhs.pss ? 1 : -1;
1488                                }
1489                                return 0;
1490                            }
1491                        });
1492
1493                        StringBuilder tag = new StringBuilder(128);
1494                        StringBuilder stack = new StringBuilder(128);
1495                        tag.append("Low on memory -- ");
1496                        appendMemBucket(tag, totalPss, "total", false);
1497                        appendMemBucket(stack, totalPss, "total", true);
1498
1499                        StringBuilder logBuilder = new StringBuilder(1024);
1500                        logBuilder.append("Low on memory:\n");
1501
1502                        boolean firstLine = true;
1503                        int lastOomAdj = Integer.MIN_VALUE;
1504                        for (int i=0, N=memInfos.size(); i<N; i++) {
1505                            ProcessMemInfo mi = memInfos.get(i);
1506
1507                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1508                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1509                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1510                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1511                                if (lastOomAdj != mi.oomAdj) {
1512                                    lastOomAdj = mi.oomAdj;
1513                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1514                                        tag.append(" / ");
1515                                    }
1516                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1517                                        if (firstLine) {
1518                                            stack.append(":");
1519                                            firstLine = false;
1520                                        }
1521                                        stack.append("\n\t at ");
1522                                    } else {
1523                                        stack.append("$");
1524                                    }
1525                                } else {
1526                                    tag.append(" ");
1527                                    stack.append("$");
1528                                }
1529                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1530                                    appendMemBucket(tag, mi.pss, mi.name, false);
1531                                }
1532                                appendMemBucket(stack, mi.pss, mi.name, true);
1533                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1534                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1535                                    stack.append("(");
1536                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1537                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1538                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1539                                            stack.append(":");
1540                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1541                                        }
1542                                    }
1543                                    stack.append(")");
1544                                }
1545                            }
1546
1547                            logBuilder.append("  ");
1548                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1549                            logBuilder.append(' ');
1550                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1551                            logBuilder.append(' ');
1552                            ProcessList.appendRamKb(logBuilder, mi.pss);
1553                            logBuilder.append(" kB: ");
1554                            logBuilder.append(mi.name);
1555                            logBuilder.append(" (");
1556                            logBuilder.append(mi.pid);
1557                            logBuilder.append(") ");
1558                            logBuilder.append(mi.adjType);
1559                            logBuilder.append('\n');
1560                            if (mi.adjReason != null) {
1561                                logBuilder.append("                      ");
1562                                logBuilder.append(mi.adjReason);
1563                                logBuilder.append('\n');
1564                            }
1565                        }
1566
1567                        logBuilder.append("           ");
1568                        ProcessList.appendRamKb(logBuilder, totalPss);
1569                        logBuilder.append(" kB: TOTAL\n");
1570
1571                        long[] infos = new long[Debug.MEMINFO_COUNT];
1572                        Debug.getMemInfo(infos);
1573                        logBuilder.append("  MemInfo: ");
1574                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1575                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1576                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1577                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1578                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1579                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1580                            logBuilder.append("  ZRAM: ");
1581                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1582                            logBuilder.append(" kB RAM, ");
1583                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1584                            logBuilder.append(" kB swap total, ");
1585                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1586                            logBuilder.append(" kB swap free\n");
1587                        }
1588                        Slog.i(TAG, logBuilder.toString());
1589
1590                        StringBuilder dropBuilder = new StringBuilder(1024);
1591                        /*
1592                        StringWriter oomSw = new StringWriter();
1593                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1594                        StringWriter catSw = new StringWriter();
1595                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1596                        String[] emptyArgs = new String[] { };
1597                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1598                        oomPw.flush();
1599                        String oomString = oomSw.toString();
1600                        */
1601                        dropBuilder.append(stack);
1602                        dropBuilder.append('\n');
1603                        dropBuilder.append('\n');
1604                        dropBuilder.append(logBuilder);
1605                        dropBuilder.append('\n');
1606                        /*
1607                        dropBuilder.append(oomString);
1608                        dropBuilder.append('\n');
1609                        */
1610                        StringWriter catSw = new StringWriter();
1611                        synchronized (ActivityManagerService.this) {
1612                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1613                            String[] emptyArgs = new String[] { };
1614                            catPw.println();
1615                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1616                            catPw.println();
1617                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1618                                    false, false, null);
1619                            catPw.println();
1620                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1621                            catPw.flush();
1622                        }
1623                        dropBuilder.append(catSw.toString());
1624                        addErrorToDropBox("lowmem", null, "system_server", null,
1625                                null, tag.toString(), dropBuilder.toString(), null, null);
1626                        //Slog.i(TAG, "Sent to dropbox:");
1627                        //Slog.i(TAG, dropBuilder.toString());
1628                        synchronized (ActivityManagerService.this) {
1629                            long now = SystemClock.uptimeMillis();
1630                            if (mLastMemUsageReportTime < now) {
1631                                mLastMemUsageReportTime = now;
1632                            }
1633                        }
1634                    }
1635                };
1636                thread.start();
1637                break;
1638            }
1639            case REPORT_USER_SWITCH_MSG: {
1640                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1641                break;
1642            }
1643            case CONTINUE_USER_SWITCH_MSG: {
1644                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1645                break;
1646            }
1647            case USER_SWITCH_TIMEOUT_MSG: {
1648                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1649                break;
1650            }
1651            case IMMERSIVE_MODE_LOCK_MSG: {
1652                final boolean nextState = (msg.arg1 != 0);
1653                if (mUpdateLock.isHeld() != nextState) {
1654                    if (DEBUG_IMMERSIVE) {
1655                        final ActivityRecord r = (ActivityRecord) msg.obj;
1656                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1657                    }
1658                    if (nextState) {
1659                        mUpdateLock.acquire();
1660                    } else {
1661                        mUpdateLock.release();
1662                    }
1663                }
1664                break;
1665            }
1666            case PERSIST_URI_GRANTS_MSG: {
1667                writeGrantedUriPermissions();
1668                break;
1669            }
1670            case REQUEST_ALL_PSS_MSG: {
1671                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1672                break;
1673            }
1674            }
1675        }
1676    };
1677
1678    static final int COLLECT_PSS_BG_MSG = 1;
1679
1680    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1681        @Override
1682        public void handleMessage(Message msg) {
1683            switch (msg.what) {
1684            case COLLECT_PSS_BG_MSG: {
1685                int i=0, num=0;
1686                long start = SystemClock.uptimeMillis();
1687                long[] tmp = new long[1];
1688                do {
1689                    ProcessRecord proc;
1690                    int procState;
1691                    int pid;
1692                    synchronized (ActivityManagerService.this) {
1693                        if (i >= mPendingPssProcesses.size()) {
1694                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1695                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1696                            mPendingPssProcesses.clear();
1697                            return;
1698                        }
1699                        proc = mPendingPssProcesses.get(i);
1700                        procState = proc.pssProcState;
1701                        if (proc.thread != null && procState == proc.setProcState) {
1702                            pid = proc.pid;
1703                        } else {
1704                            proc = null;
1705                            pid = 0;
1706                        }
1707                        i++;
1708                    }
1709                    if (proc != null) {
1710                        long pss = Debug.getPss(pid, tmp);
1711                        synchronized (ActivityManagerService.this) {
1712                            if (proc.thread != null && proc.setProcState == procState
1713                                    && proc.pid == pid) {
1714                                num++;
1715                                proc.lastPssTime = SystemClock.uptimeMillis();
1716                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1717                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1718                                        + ": " + pss + " lastPss=" + proc.lastPss
1719                                        + " state=" + ProcessList.makeProcStateString(procState));
1720                                if (proc.initialIdlePss == 0) {
1721                                    proc.initialIdlePss = pss;
1722                                }
1723                                proc.lastPss = pss;
1724                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1725                                    proc.lastCachedPss = pss;
1726                                }
1727                            }
1728                        }
1729                    }
1730                } while (true);
1731            }
1732            }
1733        }
1734    };
1735
1736    public void setSystemProcess() {
1737        try {
1738            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1739            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1740            ServiceManager.addService("meminfo", new MemBinder(this));
1741            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1742            ServiceManager.addService("dbinfo", new DbBinder(this));
1743            if (MONITOR_CPU_USAGE) {
1744                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1745            }
1746            ServiceManager.addService("permission", new PermissionController(this));
1747
1748            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1749                    "android", STOCK_PM_FLAGS);
1750            mSystemThread.installSystemApplicationInfo(info);
1751
1752            synchronized (this) {
1753                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1754                app.persistent = true;
1755                app.pid = MY_PID;
1756                app.maxAdj = ProcessList.SYSTEM_ADJ;
1757                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1758                mProcessNames.put(app.processName, app.uid, app);
1759                synchronized (mPidsSelfLocked) {
1760                    mPidsSelfLocked.put(app.pid, app);
1761                }
1762                updateLruProcessLocked(app, false, null);
1763                updateOomAdjLocked();
1764            }
1765        } catch (PackageManager.NameNotFoundException e) {
1766            throw new RuntimeException(
1767                    "Unable to find android system package", e);
1768        }
1769    }
1770
1771    public void setWindowManager(WindowManagerService wm) {
1772        mWindowManager = wm;
1773        mStackSupervisor.setWindowManager(wm);
1774    }
1775
1776    public void startObservingNativeCrashes() {
1777        final NativeCrashListener ncl = new NativeCrashListener(this);
1778        ncl.start();
1779    }
1780
1781    public IAppOpsService getAppOpsService() {
1782        return mAppOpsService;
1783    }
1784
1785    static class MemBinder extends Binder {
1786        ActivityManagerService mActivityManagerService;
1787        MemBinder(ActivityManagerService activityManagerService) {
1788            mActivityManagerService = activityManagerService;
1789        }
1790
1791        @Override
1792        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1793            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1794                    != PackageManager.PERMISSION_GRANTED) {
1795                pw.println("Permission Denial: can't dump meminfo from from pid="
1796                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1797                        + " without permission " + android.Manifest.permission.DUMP);
1798                return;
1799            }
1800
1801            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1802        }
1803    }
1804
1805    static class GraphicsBinder extends Binder {
1806        ActivityManagerService mActivityManagerService;
1807        GraphicsBinder(ActivityManagerService activityManagerService) {
1808            mActivityManagerService = activityManagerService;
1809        }
1810
1811        @Override
1812        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1813            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1814                    != PackageManager.PERMISSION_GRANTED) {
1815                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1816                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1817                        + " without permission " + android.Manifest.permission.DUMP);
1818                return;
1819            }
1820
1821            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1822        }
1823    }
1824
1825    static class DbBinder extends Binder {
1826        ActivityManagerService mActivityManagerService;
1827        DbBinder(ActivityManagerService activityManagerService) {
1828            mActivityManagerService = activityManagerService;
1829        }
1830
1831        @Override
1832        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1833            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1834                    != PackageManager.PERMISSION_GRANTED) {
1835                pw.println("Permission Denial: can't dump dbinfo from from pid="
1836                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1837                        + " without permission " + android.Manifest.permission.DUMP);
1838                return;
1839            }
1840
1841            mActivityManagerService.dumpDbInfo(fd, pw, args);
1842        }
1843    }
1844
1845    static class CpuBinder extends Binder {
1846        ActivityManagerService mActivityManagerService;
1847        CpuBinder(ActivityManagerService activityManagerService) {
1848            mActivityManagerService = activityManagerService;
1849        }
1850
1851        @Override
1852        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1853            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1854                    != PackageManager.PERMISSION_GRANTED) {
1855                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1856                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1857                        + " without permission " + android.Manifest.permission.DUMP);
1858                return;
1859            }
1860
1861            synchronized (mActivityManagerService.mProcessCpuThread) {
1862                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1863                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1864                        SystemClock.uptimeMillis()));
1865            }
1866        }
1867    }
1868
1869    public static final class Lifecycle extends SystemService {
1870        private final ActivityManagerService mService;
1871
1872        public Lifecycle(Context context) {
1873            super(context);
1874            mService = new ActivityManagerService(context);
1875        }
1876
1877        @Override
1878        public void onStart() {
1879            mService.start();
1880        }
1881
1882        public ActivityManagerService getService() {
1883            return mService;
1884        }
1885    }
1886
1887    // Note: This method is invoked on the main thread but may need to attach various
1888    // handlers to other threads.  So take care to be explicit about the looper.
1889    public ActivityManagerService(Context systemContext) {
1890        mContext = systemContext;
1891        mFactoryTest = FactoryTest.getMode();
1892        mSystemThread = ActivityThread.currentActivityThread();
1893
1894        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1895
1896        mHandlerThread = new ServiceThread(TAG,
1897                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1898        mHandlerThread.start();
1899        mHandler = new MainHandler(mHandlerThread.getLooper());
1900
1901        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1902                "foreground", BROADCAST_FG_TIMEOUT, false);
1903        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1904                "background", BROADCAST_BG_TIMEOUT, true);
1905        mBroadcastQueues[0] = mFgBroadcastQueue;
1906        mBroadcastQueues[1] = mBgBroadcastQueue;
1907
1908        mServices = new ActiveServices(this);
1909        mProviderMap = new ProviderMap(this);
1910
1911        // TODO: Move creation of battery stats service outside of activity manager service.
1912        File dataDir = Environment.getDataDirectory();
1913        File systemDir = new File(dataDir, "system");
1914        systemDir.mkdirs();
1915        mBatteryStatsService = new BatteryStatsService(new File(
1916                systemDir, "batterystats.bin").toString(), mHandler);
1917        mBatteryStatsService.getActiveStatistics().readLocked();
1918        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1919        mOnBattery = DEBUG_POWER ? true
1920                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1921        mBatteryStatsService.getActiveStatistics().setCallback(this);
1922
1923        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1924
1925        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1926        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1927
1928        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1929
1930        // User 0 is the first and only user that runs at boot.
1931        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1932        mUserLru.add(Integer.valueOf(0));
1933        updateStartedUserArrayLocked();
1934
1935        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1936            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1937
1938        mConfiguration.setToDefaults();
1939        mConfiguration.setLocale(Locale.getDefault());
1940
1941        mConfigurationSeq = mConfiguration.seq = 1;
1942        mProcessCpuTracker.init();
1943
1944        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1945        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1946        mStackSupervisor = new ActivityStackSupervisor(this);
1947
1948        mProcessCpuThread = new Thread("CpuTracker") {
1949            @Override
1950            public void run() {
1951                while (true) {
1952                    try {
1953                        try {
1954                            synchronized(this) {
1955                                final long now = SystemClock.uptimeMillis();
1956                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1957                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1958                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1959                                //        + ", write delay=" + nextWriteDelay);
1960                                if (nextWriteDelay < nextCpuDelay) {
1961                                    nextCpuDelay = nextWriteDelay;
1962                                }
1963                                if (nextCpuDelay > 0) {
1964                                    mProcessCpuMutexFree.set(true);
1965                                    this.wait(nextCpuDelay);
1966                                }
1967                            }
1968                        } catch (InterruptedException e) {
1969                        }
1970                        updateCpuStatsNow();
1971                    } catch (Exception e) {
1972                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1973                    }
1974                }
1975            }
1976        };
1977
1978        Watchdog.getInstance().addMonitor(this);
1979        Watchdog.getInstance().addThread(mHandler);
1980    }
1981
1982    private void start() {
1983        mProcessCpuThread.start();
1984
1985        mBatteryStatsService.publish(mContext);
1986        mUsageStatsService.publish(mContext);
1987        mAppOpsService.publish(mContext);
1988
1989        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
1990    }
1991
1992    @Override
1993    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1994            throws RemoteException {
1995        if (code == SYSPROPS_TRANSACTION) {
1996            // We need to tell all apps about the system property change.
1997            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1998            synchronized(this) {
1999                final int NP = mProcessNames.getMap().size();
2000                for (int ip=0; ip<NP; ip++) {
2001                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2002                    final int NA = apps.size();
2003                    for (int ia=0; ia<NA; ia++) {
2004                        ProcessRecord app = apps.valueAt(ia);
2005                        if (app.thread != null) {
2006                            procs.add(app.thread.asBinder());
2007                        }
2008                    }
2009                }
2010            }
2011
2012            int N = procs.size();
2013            for (int i=0; i<N; i++) {
2014                Parcel data2 = Parcel.obtain();
2015                try {
2016                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2017                } catch (RemoteException e) {
2018                }
2019                data2.recycle();
2020            }
2021        }
2022        try {
2023            return super.onTransact(code, data, reply, flags);
2024        } catch (RuntimeException e) {
2025            // The activity manager only throws security exceptions, so let's
2026            // log all others.
2027            if (!(e instanceof SecurityException)) {
2028                Slog.wtf(TAG, "Activity Manager Crash", e);
2029            }
2030            throw e;
2031        }
2032    }
2033
2034    void updateCpuStats() {
2035        final long now = SystemClock.uptimeMillis();
2036        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2037            return;
2038        }
2039        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2040            synchronized (mProcessCpuThread) {
2041                mProcessCpuThread.notify();
2042            }
2043        }
2044    }
2045
2046    void updateCpuStatsNow() {
2047        synchronized (mProcessCpuThread) {
2048            mProcessCpuMutexFree.set(false);
2049            final long now = SystemClock.uptimeMillis();
2050            boolean haveNewCpuStats = false;
2051
2052            if (MONITOR_CPU_USAGE &&
2053                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2054                mLastCpuTime.set(now);
2055                haveNewCpuStats = true;
2056                mProcessCpuTracker.update();
2057                //Slog.i(TAG, mProcessCpu.printCurrentState());
2058                //Slog.i(TAG, "Total CPU usage: "
2059                //        + mProcessCpu.getTotalCpuPercent() + "%");
2060
2061                // Slog the cpu usage if the property is set.
2062                if ("true".equals(SystemProperties.get("events.cpu"))) {
2063                    int user = mProcessCpuTracker.getLastUserTime();
2064                    int system = mProcessCpuTracker.getLastSystemTime();
2065                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2066                    int irq = mProcessCpuTracker.getLastIrqTime();
2067                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2068                    int idle = mProcessCpuTracker.getLastIdleTime();
2069
2070                    int total = user + system + iowait + irq + softIrq + idle;
2071                    if (total == 0) total = 1;
2072
2073                    EventLog.writeEvent(EventLogTags.CPU,
2074                            ((user+system+iowait+irq+softIrq) * 100) / total,
2075                            (user * 100) / total,
2076                            (system * 100) / total,
2077                            (iowait * 100) / total,
2078                            (irq * 100) / total,
2079                            (softIrq * 100) / total);
2080                }
2081            }
2082
2083            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2084            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2085            synchronized(bstats) {
2086                synchronized(mPidsSelfLocked) {
2087                    if (haveNewCpuStats) {
2088                        if (mOnBattery) {
2089                            int perc = bstats.startAddingCpuLocked();
2090                            int totalUTime = 0;
2091                            int totalSTime = 0;
2092                            final int N = mProcessCpuTracker.countStats();
2093                            for (int i=0; i<N; i++) {
2094                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2095                                if (!st.working) {
2096                                    continue;
2097                                }
2098                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2099                                int otherUTime = (st.rel_utime*perc)/100;
2100                                int otherSTime = (st.rel_stime*perc)/100;
2101                                totalUTime += otherUTime;
2102                                totalSTime += otherSTime;
2103                                if (pr != null) {
2104                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
2105                                            st.name, st.pid);
2106                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2107                                            st.rel_stime-otherSTime);
2108                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2109                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2110                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
2111                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2112                                    if (ps == null) {
2113                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
2114                                                "(Unknown)");
2115                                    }
2116                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2117                                            st.rel_stime-otherSTime);
2118                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2119                                } else {
2120                                    BatteryStatsImpl.Uid.Proc ps =
2121                                            bstats.getProcessStatsLocked(st.name, st.pid);
2122                                    if (ps != null) {
2123                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2124                                                st.rel_stime-otherSTime);
2125                                        ps.addSpeedStepTimes(cpuSpeedTimes);
2126                                    }
2127                                }
2128                            }
2129                            bstats.finishAddingCpuLocked(perc, totalUTime,
2130                                    totalSTime, cpuSpeedTimes);
2131                        }
2132                    }
2133                }
2134
2135                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2136                    mLastWriteTime = now;
2137                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2138                }
2139            }
2140        }
2141    }
2142
2143    @Override
2144    public void batteryNeedsCpuUpdate() {
2145        updateCpuStatsNow();
2146    }
2147
2148    @Override
2149    public void batteryPowerChanged(boolean onBattery) {
2150        // When plugging in, update the CPU stats first before changing
2151        // the plug state.
2152        updateCpuStatsNow();
2153        synchronized (this) {
2154            synchronized(mPidsSelfLocked) {
2155                mOnBattery = DEBUG_POWER ? true : onBattery;
2156            }
2157        }
2158    }
2159
2160    /**
2161     * Initialize the application bind args. These are passed to each
2162     * process when the bindApplication() IPC is sent to the process. They're
2163     * lazily setup to make sure the services are running when they're asked for.
2164     */
2165    private HashMap<String, IBinder> getCommonServicesLocked() {
2166        if (mAppBindArgs == null) {
2167            mAppBindArgs = new HashMap<String, IBinder>();
2168
2169            // Setup the application init args
2170            mAppBindArgs.put("package", ServiceManager.getService("package"));
2171            mAppBindArgs.put("window", ServiceManager.getService("window"));
2172            mAppBindArgs.put(Context.ALARM_SERVICE,
2173                    ServiceManager.getService(Context.ALARM_SERVICE));
2174        }
2175        return mAppBindArgs;
2176    }
2177
2178    final void setFocusedActivityLocked(ActivityRecord r) {
2179        if (mFocusedActivity != r) {
2180            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2181            mFocusedActivity = r;
2182            mStackSupervisor.setFocusedStack(r);
2183            if (r != null) {
2184                mWindowManager.setFocusedApp(r.appToken, true);
2185            }
2186            applyUpdateLockStateLocked(r);
2187        }
2188    }
2189
2190    @Override
2191    public void setFocusedStack(int stackId) {
2192        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2193        synchronized (ActivityManagerService.this) {
2194            ActivityStack stack = mStackSupervisor.getStack(stackId);
2195            if (stack != null) {
2196                ActivityRecord r = stack.topRunningActivityLocked(null);
2197                if (r != null) {
2198                    setFocusedActivityLocked(r);
2199                }
2200            }
2201        }
2202    }
2203
2204    @Override
2205    public void notifyActivityDrawn(IBinder token) {
2206        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2207        synchronized (this) {
2208            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2209            if (r != null) {
2210                r.task.stack.notifyActivityDrawnLocked(r);
2211            }
2212        }
2213    }
2214
2215    final void applyUpdateLockStateLocked(ActivityRecord r) {
2216        // Modifications to the UpdateLock state are done on our handler, outside
2217        // the activity manager's locks.  The new state is determined based on the
2218        // state *now* of the relevant activity record.  The object is passed to
2219        // the handler solely for logging detail, not to be consulted/modified.
2220        final boolean nextState = r != null && r.immersive;
2221        mHandler.sendMessage(
2222                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2223    }
2224
2225    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2226        Message msg = Message.obtain();
2227        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2228        msg.obj = r.task.askedCompatMode ? null : r;
2229        mHandler.sendMessage(msg);
2230    }
2231
2232    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2233            String what, Object obj, ProcessRecord srcApp) {
2234        app.lastActivityTime = now;
2235
2236        if (app.activities.size() > 0) {
2237            // Don't want to touch dependent processes that are hosting activities.
2238            return index;
2239        }
2240
2241        int lrui = mLruProcesses.lastIndexOf(app);
2242        if (lrui < 0) {
2243            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2244                    + what + " " + obj + " from " + srcApp);
2245            return index;
2246        }
2247
2248        if (lrui >= index) {
2249            // Don't want to cause this to move dependent processes *back* in the
2250            // list as if they were less frequently used.
2251            return index;
2252        }
2253
2254        if (lrui >= mLruProcessActivityStart) {
2255            // Don't want to touch dependent processes that are hosting activities.
2256            return index;
2257        }
2258
2259        mLruProcesses.remove(lrui);
2260        if (index > 0) {
2261            index--;
2262        }
2263        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2264                + " in LRU list: " + app);
2265        mLruProcesses.add(index, app);
2266        return index;
2267    }
2268
2269    final void removeLruProcessLocked(ProcessRecord app) {
2270        int lrui = mLruProcesses.lastIndexOf(app);
2271        if (lrui >= 0) {
2272            if (lrui <= mLruProcessActivityStart) {
2273                mLruProcessActivityStart--;
2274            }
2275            if (lrui <= mLruProcessServiceStart) {
2276                mLruProcessServiceStart--;
2277            }
2278            mLruProcesses.remove(lrui);
2279        }
2280    }
2281
2282    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2283            ProcessRecord client) {
2284        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2285        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2286        if (!activityChange && hasActivity) {
2287            // The process has activties, so we are only going to allow activity-based
2288            // adjustments move it.  It should be kept in the front of the list with other
2289            // processes that have activities, and we don't want those to change their
2290            // order except due to activity operations.
2291            return;
2292        }
2293
2294        mLruSeq++;
2295        final long now = SystemClock.uptimeMillis();
2296        app.lastActivityTime = now;
2297
2298        // First a quick reject: if the app is already at the position we will
2299        // put it, then there is nothing to do.
2300        if (hasActivity) {
2301            final int N = mLruProcesses.size();
2302            if (N > 0 && mLruProcesses.get(N-1) == app) {
2303                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2304                return;
2305            }
2306        } else {
2307            if (mLruProcessServiceStart > 0
2308                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2309                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2310                return;
2311            }
2312        }
2313
2314        int lrui = mLruProcesses.lastIndexOf(app);
2315
2316        if (app.persistent && lrui >= 0) {
2317            // We don't care about the position of persistent processes, as long as
2318            // they are in the list.
2319            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2320            return;
2321        }
2322
2323        /* In progress: compute new position first, so we can avoid doing work
2324           if the process is not actually going to move.  Not yet working.
2325        int addIndex;
2326        int nextIndex;
2327        boolean inActivity = false, inService = false;
2328        if (hasActivity) {
2329            // Process has activities, put it at the very tipsy-top.
2330            addIndex = mLruProcesses.size();
2331            nextIndex = mLruProcessServiceStart;
2332            inActivity = true;
2333        } else if (hasService) {
2334            // Process has services, put it at the top of the service list.
2335            addIndex = mLruProcessActivityStart;
2336            nextIndex = mLruProcessServiceStart;
2337            inActivity = true;
2338            inService = true;
2339        } else  {
2340            // Process not otherwise of interest, it goes to the top of the non-service area.
2341            addIndex = mLruProcessServiceStart;
2342            if (client != null) {
2343                int clientIndex = mLruProcesses.lastIndexOf(client);
2344                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2345                        + app);
2346                if (clientIndex >= 0 && addIndex > clientIndex) {
2347                    addIndex = clientIndex;
2348                }
2349            }
2350            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2351        }
2352
2353        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2354                + mLruProcessActivityStart + "): " + app);
2355        */
2356
2357        if (lrui >= 0) {
2358            if (lrui < mLruProcessActivityStart) {
2359                mLruProcessActivityStart--;
2360            }
2361            if (lrui < mLruProcessServiceStart) {
2362                mLruProcessServiceStart--;
2363            }
2364            /*
2365            if (addIndex > lrui) {
2366                addIndex--;
2367            }
2368            if (nextIndex > lrui) {
2369                nextIndex--;
2370            }
2371            */
2372            mLruProcesses.remove(lrui);
2373        }
2374
2375        /*
2376        mLruProcesses.add(addIndex, app);
2377        if (inActivity) {
2378            mLruProcessActivityStart++;
2379        }
2380        if (inService) {
2381            mLruProcessActivityStart++;
2382        }
2383        */
2384
2385        int nextIndex;
2386        if (hasActivity) {
2387            final int N = mLruProcesses.size();
2388            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2389                // Process doesn't have activities, but has clients with
2390                // activities...  move it up, but one below the top (the top
2391                // should always have a real activity).
2392                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2393                mLruProcesses.add(N-1, app);
2394                // To keep it from spamming the LRU list (by making a bunch of clients),
2395                // we will push down any other entries owned by the app.
2396                final int uid = app.info.uid;
2397                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2398                    ProcessRecord subProc = mLruProcesses.get(i);
2399                    if (subProc.info.uid == uid) {
2400                        // We want to push this one down the list.  If the process after
2401                        // it is for the same uid, however, don't do so, because we don't
2402                        // want them internally to be re-ordered.
2403                        if (mLruProcesses.get(i-1).info.uid != uid) {
2404                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2405                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2406                            ProcessRecord tmp = mLruProcesses.get(i);
2407                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2408                            mLruProcesses.set(i-1, tmp);
2409                            i--;
2410                        }
2411                    } else {
2412                        // A gap, we can stop here.
2413                        break;
2414                    }
2415                }
2416            } else {
2417                // Process has activities, put it at the very tipsy-top.
2418                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2419                mLruProcesses.add(app);
2420            }
2421            nextIndex = mLruProcessServiceStart;
2422        } else if (hasService) {
2423            // Process has services, put it at the top of the service list.
2424            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2425            mLruProcesses.add(mLruProcessActivityStart, app);
2426            nextIndex = mLruProcessServiceStart;
2427            mLruProcessActivityStart++;
2428        } else  {
2429            // Process not otherwise of interest, it goes to the top of the non-service area.
2430            int index = mLruProcessServiceStart;
2431            if (client != null) {
2432                // If there is a client, don't allow the process to be moved up higher
2433                // in the list than that client.
2434                int clientIndex = mLruProcesses.lastIndexOf(client);
2435                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2436                        + " when updating " + app);
2437                if (clientIndex <= lrui) {
2438                    // Don't allow the client index restriction to push it down farther in the
2439                    // list than it already is.
2440                    clientIndex = lrui;
2441                }
2442                if (clientIndex >= 0 && index > clientIndex) {
2443                    index = clientIndex;
2444                }
2445            }
2446            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2447            mLruProcesses.add(index, app);
2448            nextIndex = index-1;
2449            mLruProcessActivityStart++;
2450            mLruProcessServiceStart++;
2451        }
2452
2453        // If the app is currently using a content provider or service,
2454        // bump those processes as well.
2455        for (int j=app.connections.size()-1; j>=0; j--) {
2456            ConnectionRecord cr = app.connections.valueAt(j);
2457            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2458                    && cr.binding.service.app != null
2459                    && cr.binding.service.app.lruSeq != mLruSeq
2460                    && !cr.binding.service.app.persistent) {
2461                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2462                        "service connection", cr, app);
2463            }
2464        }
2465        for (int j=app.conProviders.size()-1; j>=0; j--) {
2466            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2467            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2468                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2469                        "provider reference", cpr, app);
2470            }
2471        }
2472    }
2473
2474    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2475        if (uid == Process.SYSTEM_UID) {
2476            // The system gets to run in any process.  If there are multiple
2477            // processes with the same uid, just pick the first (this
2478            // should never happen).
2479            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2480            if (procs == null) return null;
2481            final int N = procs.size();
2482            for (int i = 0; i < N; i++) {
2483                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2484            }
2485        }
2486        ProcessRecord proc = mProcessNames.get(processName, uid);
2487        if (false && proc != null && !keepIfLarge
2488                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2489                && proc.lastCachedPss >= 4000) {
2490            // Turn this condition on to cause killing to happen regularly, for testing.
2491            if (proc.baseProcessTracker != null) {
2492                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2493            }
2494            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2495                    + "k from cached");
2496        } else if (proc != null && !keepIfLarge
2497                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2498                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2499            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2500            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2501                if (proc.baseProcessTracker != null) {
2502                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2503                }
2504                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2505                        + "k from cached");
2506            }
2507        }
2508        return proc;
2509    }
2510
2511    void ensurePackageDexOpt(String packageName) {
2512        IPackageManager pm = AppGlobals.getPackageManager();
2513        try {
2514            if (pm.performDexOpt(packageName)) {
2515                mDidDexOpt = true;
2516            }
2517        } catch (RemoteException e) {
2518        }
2519    }
2520
2521    boolean isNextTransitionForward() {
2522        int transit = mWindowManager.getPendingAppTransition();
2523        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2524                || transit == AppTransition.TRANSIT_TASK_OPEN
2525                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2526    }
2527
2528    final ProcessRecord startProcessLocked(String processName,
2529            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2530            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2531            boolean isolated, boolean keepIfLarge) {
2532        ProcessRecord app;
2533        if (!isolated) {
2534            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2535        } else {
2536            // If this is an isolated process, it can't re-use an existing process.
2537            app = null;
2538        }
2539        // We don't have to do anything more if:
2540        // (1) There is an existing application record; and
2541        // (2) The caller doesn't think it is dead, OR there is no thread
2542        //     object attached to it so we know it couldn't have crashed; and
2543        // (3) There is a pid assigned to it, so it is either starting or
2544        //     already running.
2545        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2546                + " app=" + app + " knownToBeDead=" + knownToBeDead
2547                + " thread=" + (app != null ? app.thread : null)
2548                + " pid=" + (app != null ? app.pid : -1));
2549        if (app != null && app.pid > 0) {
2550            if (!knownToBeDead || app.thread == null) {
2551                // We already have the app running, or are waiting for it to
2552                // come up (we have a pid but not yet its thread), so keep it.
2553                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2554                // If this is a new package in the process, add the package to the list
2555                app.addPackage(info.packageName, mProcessStats);
2556                return app;
2557            }
2558
2559            // An application record is attached to a previous process,
2560            // clean it up now.
2561            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2562            handleAppDiedLocked(app, true, true);
2563        }
2564
2565        String hostingNameStr = hostingName != null
2566                ? hostingName.flattenToShortString() : null;
2567
2568        if (!isolated) {
2569            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2570                // If we are in the background, then check to see if this process
2571                // is bad.  If so, we will just silently fail.
2572                if (mBadProcesses.get(info.processName, info.uid) != null) {
2573                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2574                            + "/" + info.processName);
2575                    return null;
2576                }
2577            } else {
2578                // When the user is explicitly starting a process, then clear its
2579                // crash count so that we won't make it bad until they see at
2580                // least one crash dialog again, and make the process good again
2581                // if it had been bad.
2582                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2583                        + "/" + info.processName);
2584                mProcessCrashTimes.remove(info.processName, info.uid);
2585                if (mBadProcesses.get(info.processName, info.uid) != null) {
2586                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2587                            UserHandle.getUserId(info.uid), info.uid,
2588                            info.processName);
2589                    mBadProcesses.remove(info.processName, info.uid);
2590                    if (app != null) {
2591                        app.bad = false;
2592                    }
2593                }
2594            }
2595        }
2596
2597        if (app == null) {
2598            app = newProcessRecordLocked(info, processName, isolated);
2599            if (app == null) {
2600                Slog.w(TAG, "Failed making new process record for "
2601                        + processName + "/" + info.uid + " isolated=" + isolated);
2602                return null;
2603            }
2604            mProcessNames.put(processName, app.uid, app);
2605            if (isolated) {
2606                mIsolatedProcesses.put(app.uid, app);
2607            }
2608        } else {
2609            // If this is a new package in the process, add the package to the list
2610            app.addPackage(info.packageName, mProcessStats);
2611        }
2612
2613        // If the system is not ready yet, then hold off on starting this
2614        // process until it is.
2615        if (!mProcessesReady
2616                && !isAllowedWhileBooting(info)
2617                && !allowWhileBooting) {
2618            if (!mProcessesOnHold.contains(app)) {
2619                mProcessesOnHold.add(app);
2620            }
2621            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2622            return app;
2623        }
2624
2625        startProcessLocked(app, hostingType, hostingNameStr);
2626        return (app.pid != 0) ? app : null;
2627    }
2628
2629    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2630        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2631    }
2632
2633    private final void startProcessLocked(ProcessRecord app,
2634            String hostingType, String hostingNameStr) {
2635        if (app.pid > 0 && app.pid != MY_PID) {
2636            synchronized (mPidsSelfLocked) {
2637                mPidsSelfLocked.remove(app.pid);
2638                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2639            }
2640            app.setPid(0);
2641        }
2642
2643        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2644                "startProcessLocked removing on hold: " + app);
2645        mProcessesOnHold.remove(app);
2646
2647        updateCpuStats();
2648
2649        try {
2650            int uid = app.uid;
2651
2652            int[] gids = null;
2653            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2654            if (!app.isolated) {
2655                int[] permGids = null;
2656                try {
2657                    final PackageManager pm = mContext.getPackageManager();
2658                    permGids = pm.getPackageGids(app.info.packageName);
2659
2660                    if (Environment.isExternalStorageEmulated()) {
2661                        if (pm.checkPermission(
2662                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2663                                app.info.packageName) == PERMISSION_GRANTED) {
2664                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2665                        } else {
2666                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2667                        }
2668                    }
2669                } catch (PackageManager.NameNotFoundException e) {
2670                    Slog.w(TAG, "Unable to retrieve gids", e);
2671                }
2672
2673                /*
2674                 * Add shared application GID so applications can share some
2675                 * resources like shared libraries
2676                 */
2677                if (permGids == null) {
2678                    gids = new int[1];
2679                } else {
2680                    gids = new int[permGids.length + 1];
2681                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2682                }
2683                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2684            }
2685            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2686                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2687                        && mTopComponent != null
2688                        && app.processName.equals(mTopComponent.getPackageName())) {
2689                    uid = 0;
2690                }
2691                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2692                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2693                    uid = 0;
2694                }
2695            }
2696            int debugFlags = 0;
2697            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2698                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2699                // Also turn on CheckJNI for debuggable apps. It's quite
2700                // awkward to turn on otherwise.
2701                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2702            }
2703            // Run the app in safe mode if its manifest requests so or the
2704            // system is booted in safe mode.
2705            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2706                Zygote.systemInSafeMode == true) {
2707                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2708            }
2709            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2710                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2711            }
2712            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2713                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2714            }
2715            if ("1".equals(SystemProperties.get("debug.assert"))) {
2716                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2717            }
2718
2719            // Start the process.  It will either succeed and return a result containing
2720            // the PID of the new process, or else throw a RuntimeException.
2721            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2722                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2723                    app.info.targetSdkVersion, app.info.seinfo, null);
2724
2725            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2726            synchronized (bs) {
2727                if (bs.isOnBattery()) {
2728                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2729                }
2730            }
2731
2732            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2733                    UserHandle.getUserId(uid), startResult.pid, uid,
2734                    app.processName, hostingType,
2735                    hostingNameStr != null ? hostingNameStr : "");
2736
2737            if (app.persistent) {
2738                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2739            }
2740
2741            StringBuilder buf = mStringBuilder;
2742            buf.setLength(0);
2743            buf.append("Start proc ");
2744            buf.append(app.processName);
2745            buf.append(" for ");
2746            buf.append(hostingType);
2747            if (hostingNameStr != null) {
2748                buf.append(" ");
2749                buf.append(hostingNameStr);
2750            }
2751            buf.append(": pid=");
2752            buf.append(startResult.pid);
2753            buf.append(" uid=");
2754            buf.append(uid);
2755            buf.append(" gids={");
2756            if (gids != null) {
2757                for (int gi=0; gi<gids.length; gi++) {
2758                    if (gi != 0) buf.append(", ");
2759                    buf.append(gids[gi]);
2760
2761                }
2762            }
2763            buf.append("}");
2764            Slog.i(TAG, buf.toString());
2765            app.setPid(startResult.pid);
2766            app.usingWrapper = startResult.usingWrapper;
2767            app.removed = false;
2768            synchronized (mPidsSelfLocked) {
2769                this.mPidsSelfLocked.put(startResult.pid, app);
2770                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2771                msg.obj = app;
2772                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2773                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2774            }
2775        } catch (RuntimeException e) {
2776            // XXX do better error recovery.
2777            app.setPid(0);
2778            Slog.e(TAG, "Failure starting process " + app.processName, e);
2779        }
2780    }
2781
2782    void updateUsageStats(ActivityRecord component, boolean resumed) {
2783        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2784        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2785        if (resumed) {
2786            mUsageStatsService.noteResumeComponent(component.realActivity);
2787            synchronized (stats) {
2788                stats.noteActivityResumedLocked(component.app.uid);
2789            }
2790        } else {
2791            mUsageStatsService.notePauseComponent(component.realActivity);
2792            synchronized (stats) {
2793                stats.noteActivityPausedLocked(component.app.uid);
2794            }
2795        }
2796    }
2797
2798    Intent getHomeIntent() {
2799        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2800        intent.setComponent(mTopComponent);
2801        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2802            intent.addCategory(Intent.CATEGORY_HOME);
2803        }
2804        return intent;
2805    }
2806
2807    boolean startHomeActivityLocked(int userId) {
2808        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2809                && mTopAction == null) {
2810            // We are running in factory test mode, but unable to find
2811            // the factory test app, so just sit around displaying the
2812            // error message and don't try to start anything.
2813            return false;
2814        }
2815        Intent intent = getHomeIntent();
2816        ActivityInfo aInfo =
2817            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2818        if (aInfo != null) {
2819            intent.setComponent(new ComponentName(
2820                    aInfo.applicationInfo.packageName, aInfo.name));
2821            // Don't do this if the home app is currently being
2822            // instrumented.
2823            aInfo = new ActivityInfo(aInfo);
2824            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2825            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2826                    aInfo.applicationInfo.uid, true);
2827            if (app == null || app.instrumentationClass == null) {
2828                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2829                mStackSupervisor.startHomeActivity(intent, aInfo);
2830            }
2831        }
2832
2833        return true;
2834    }
2835
2836    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2837        ActivityInfo ai = null;
2838        ComponentName comp = intent.getComponent();
2839        try {
2840            if (comp != null) {
2841                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2842            } else {
2843                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2844                        intent,
2845                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2846                            flags, userId);
2847
2848                if (info != null) {
2849                    ai = info.activityInfo;
2850                }
2851            }
2852        } catch (RemoteException e) {
2853            // ignore
2854        }
2855
2856        return ai;
2857    }
2858
2859    /**
2860     * Starts the "new version setup screen" if appropriate.
2861     */
2862    void startSetupActivityLocked() {
2863        // Only do this once per boot.
2864        if (mCheckedForSetup) {
2865            return;
2866        }
2867
2868        // We will show this screen if the current one is a different
2869        // version than the last one shown, and we are not running in
2870        // low-level factory test mode.
2871        final ContentResolver resolver = mContext.getContentResolver();
2872        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2873                Settings.Global.getInt(resolver,
2874                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2875            mCheckedForSetup = true;
2876
2877            // See if we should be showing the platform update setup UI.
2878            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2879            List<ResolveInfo> ris = mContext.getPackageManager()
2880                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2881
2882            // We don't allow third party apps to replace this.
2883            ResolveInfo ri = null;
2884            for (int i=0; ris != null && i<ris.size(); i++) {
2885                if ((ris.get(i).activityInfo.applicationInfo.flags
2886                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2887                    ri = ris.get(i);
2888                    break;
2889                }
2890            }
2891
2892            if (ri != null) {
2893                String vers = ri.activityInfo.metaData != null
2894                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2895                        : null;
2896                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2897                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2898                            Intent.METADATA_SETUP_VERSION);
2899                }
2900                String lastVers = Settings.Secure.getString(
2901                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2902                if (vers != null && !vers.equals(lastVers)) {
2903                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2904                    intent.setComponent(new ComponentName(
2905                            ri.activityInfo.packageName, ri.activityInfo.name));
2906                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2907                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2908                }
2909            }
2910        }
2911    }
2912
2913    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2914        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2915    }
2916
2917    void enforceNotIsolatedCaller(String caller) {
2918        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2919            throw new SecurityException("Isolated process not allowed to call " + caller);
2920        }
2921    }
2922
2923    @Override
2924    public int getFrontActivityScreenCompatMode() {
2925        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2926        synchronized (this) {
2927            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2928        }
2929    }
2930
2931    @Override
2932    public void setFrontActivityScreenCompatMode(int mode) {
2933        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2934                "setFrontActivityScreenCompatMode");
2935        synchronized (this) {
2936            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2937        }
2938    }
2939
2940    @Override
2941    public int getPackageScreenCompatMode(String packageName) {
2942        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2943        synchronized (this) {
2944            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2945        }
2946    }
2947
2948    @Override
2949    public void setPackageScreenCompatMode(String packageName, int mode) {
2950        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2951                "setPackageScreenCompatMode");
2952        synchronized (this) {
2953            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2954        }
2955    }
2956
2957    @Override
2958    public boolean getPackageAskScreenCompat(String packageName) {
2959        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2960        synchronized (this) {
2961            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2962        }
2963    }
2964
2965    @Override
2966    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2967        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2968                "setPackageAskScreenCompat");
2969        synchronized (this) {
2970            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2971        }
2972    }
2973
2974    private void dispatchProcessesChanged() {
2975        int N;
2976        synchronized (this) {
2977            N = mPendingProcessChanges.size();
2978            if (mActiveProcessChanges.length < N) {
2979                mActiveProcessChanges = new ProcessChangeItem[N];
2980            }
2981            mPendingProcessChanges.toArray(mActiveProcessChanges);
2982            mAvailProcessChanges.addAll(mPendingProcessChanges);
2983            mPendingProcessChanges.clear();
2984            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2985        }
2986
2987        int i = mProcessObservers.beginBroadcast();
2988        while (i > 0) {
2989            i--;
2990            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2991            if (observer != null) {
2992                try {
2993                    for (int j=0; j<N; j++) {
2994                        ProcessChangeItem item = mActiveProcessChanges[j];
2995                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2996                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2997                                    + item.pid + " uid=" + item.uid + ": "
2998                                    + item.foregroundActivities);
2999                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3000                                    item.foregroundActivities);
3001                        }
3002                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3003                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3004                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3005                            observer.onImportanceChanged(item.pid, item.uid,
3006                                    item.importance);
3007                        }
3008                    }
3009                } catch (RemoteException e) {
3010                }
3011            }
3012        }
3013        mProcessObservers.finishBroadcast();
3014    }
3015
3016    private void dispatchProcessDied(int pid, int uid) {
3017        int i = mProcessObservers.beginBroadcast();
3018        while (i > 0) {
3019            i--;
3020            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3021            if (observer != null) {
3022                try {
3023                    observer.onProcessDied(pid, uid);
3024                } catch (RemoteException e) {
3025                }
3026            }
3027        }
3028        mProcessObservers.finishBroadcast();
3029    }
3030
3031    final void doPendingActivityLaunchesLocked(boolean doResume) {
3032        final int N = mPendingActivityLaunches.size();
3033        if (N <= 0) {
3034            return;
3035        }
3036        for (int i=0; i<N; i++) {
3037            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3038            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3039                    doResume && i == (N-1), null);
3040        }
3041        mPendingActivityLaunches.clear();
3042    }
3043
3044    @Override
3045    public final int startActivity(IApplicationThread caller, String callingPackage,
3046            Intent intent, String resolvedType, IBinder resultTo,
3047            String resultWho, int requestCode, int startFlags,
3048            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3049        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3050                resultWho, requestCode,
3051                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3052    }
3053
3054    @Override
3055    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3056            Intent intent, String resolvedType, IBinder resultTo,
3057            String resultWho, int requestCode, int startFlags,
3058            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3059        enforceNotIsolatedCaller("startActivity");
3060        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3061                false, true, "startActivity", null);
3062        // TODO: Switch to user app stacks here.
3063        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3064                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3065                null, null, options, userId, null);
3066    }
3067
3068    @Override
3069    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3070            Intent intent, String resolvedType, IBinder resultTo,
3071            String resultWho, int requestCode, int startFlags, String profileFile,
3072            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3073        enforceNotIsolatedCaller("startActivityAndWait");
3074        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3075                false, true, "startActivityAndWait", null);
3076        WaitResult res = new WaitResult();
3077        // TODO: Switch to user app stacks here.
3078        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3079                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3080                res, null, options, UserHandle.getCallingUserId(), null);
3081        return res;
3082    }
3083
3084    @Override
3085    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3086            Intent intent, String resolvedType, IBinder resultTo,
3087            String resultWho, int requestCode, int startFlags, Configuration config,
3088            Bundle options, int userId) {
3089        enforceNotIsolatedCaller("startActivityWithConfig");
3090        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3091                false, true, "startActivityWithConfig", null);
3092        // TODO: Switch to user app stacks here.
3093        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3094                resolvedType, resultTo, resultWho, requestCode, startFlags,
3095                null, null, null, config, options, userId, null);
3096        return ret;
3097    }
3098
3099    @Override
3100    public int startActivityIntentSender(IApplicationThread caller,
3101            IntentSender intent, Intent fillInIntent, String resolvedType,
3102            IBinder resultTo, String resultWho, int requestCode,
3103            int flagsMask, int flagsValues, Bundle options) {
3104        enforceNotIsolatedCaller("startActivityIntentSender");
3105        // Refuse possible leaked file descriptors
3106        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3107            throw new IllegalArgumentException("File descriptors passed in Intent");
3108        }
3109
3110        IIntentSender sender = intent.getTarget();
3111        if (!(sender instanceof PendingIntentRecord)) {
3112            throw new IllegalArgumentException("Bad PendingIntent object");
3113        }
3114
3115        PendingIntentRecord pir = (PendingIntentRecord)sender;
3116
3117        synchronized (this) {
3118            // If this is coming from the currently resumed activity, it is
3119            // effectively saying that app switches are allowed at this point.
3120            final ActivityStack stack = getFocusedStack();
3121            if (stack.mResumedActivity != null &&
3122                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3123                mAppSwitchesAllowedTime = 0;
3124            }
3125        }
3126        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3127                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3128        return ret;
3129    }
3130
3131    @Override
3132    public boolean startNextMatchingActivity(IBinder callingActivity,
3133            Intent intent, Bundle options) {
3134        // Refuse possible leaked file descriptors
3135        if (intent != null && intent.hasFileDescriptors() == true) {
3136            throw new IllegalArgumentException("File descriptors passed in Intent");
3137        }
3138
3139        synchronized (this) {
3140            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3141            if (r == null) {
3142                ActivityOptions.abort(options);
3143                return false;
3144            }
3145            if (r.app == null || r.app.thread == null) {
3146                // The caller is not running...  d'oh!
3147                ActivityOptions.abort(options);
3148                return false;
3149            }
3150            intent = new Intent(intent);
3151            // The caller is not allowed to change the data.
3152            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3153            // And we are resetting to find the next component...
3154            intent.setComponent(null);
3155
3156            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3157
3158            ActivityInfo aInfo = null;
3159            try {
3160                List<ResolveInfo> resolves =
3161                    AppGlobals.getPackageManager().queryIntentActivities(
3162                            intent, r.resolvedType,
3163                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3164                            UserHandle.getCallingUserId());
3165
3166                // Look for the original activity in the list...
3167                final int N = resolves != null ? resolves.size() : 0;
3168                for (int i=0; i<N; i++) {
3169                    ResolveInfo rInfo = resolves.get(i);
3170                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3171                            && rInfo.activityInfo.name.equals(r.info.name)) {
3172                        // We found the current one...  the next matching is
3173                        // after it.
3174                        i++;
3175                        if (i<N) {
3176                            aInfo = resolves.get(i).activityInfo;
3177                        }
3178                        if (debug) {
3179                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3180                                    + "/" + r.info.name);
3181                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3182                                    + "/" + aInfo.name);
3183                        }
3184                        break;
3185                    }
3186                }
3187            } catch (RemoteException e) {
3188            }
3189
3190            if (aInfo == null) {
3191                // Nobody who is next!
3192                ActivityOptions.abort(options);
3193                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3194                return false;
3195            }
3196
3197            intent.setComponent(new ComponentName(
3198                    aInfo.applicationInfo.packageName, aInfo.name));
3199            intent.setFlags(intent.getFlags()&~(
3200                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3201                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3202                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3203                    Intent.FLAG_ACTIVITY_NEW_TASK));
3204
3205            // Okay now we need to start the new activity, replacing the
3206            // currently running activity.  This is a little tricky because
3207            // we want to start the new one as if the current one is finished,
3208            // but not finish the current one first so that there is no flicker.
3209            // And thus...
3210            final boolean wasFinishing = r.finishing;
3211            r.finishing = true;
3212
3213            // Propagate reply information over to the new activity.
3214            final ActivityRecord resultTo = r.resultTo;
3215            final String resultWho = r.resultWho;
3216            final int requestCode = r.requestCode;
3217            r.resultTo = null;
3218            if (resultTo != null) {
3219                resultTo.removeResultsLocked(r, resultWho, requestCode);
3220            }
3221
3222            final long origId = Binder.clearCallingIdentity();
3223            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3224                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3225                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3226                    options, false, null, null);
3227            Binder.restoreCallingIdentity(origId);
3228
3229            r.finishing = wasFinishing;
3230            if (res != ActivityManager.START_SUCCESS) {
3231                return false;
3232            }
3233            return true;
3234        }
3235    }
3236
3237    final int startActivityInPackage(int uid, String callingPackage,
3238            Intent intent, String resolvedType, IBinder resultTo,
3239            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3240                    IActivityContainer container) {
3241
3242        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3243                false, true, "startActivityInPackage", null);
3244
3245        // TODO: Switch to user app stacks here.
3246        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3247                resultTo, resultWho, requestCode, startFlags,
3248                null, null, null, null, options, userId, container);
3249        return ret;
3250    }
3251
3252    @Override
3253    public final int startActivities(IApplicationThread caller, String callingPackage,
3254            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3255            int userId) {
3256        enforceNotIsolatedCaller("startActivities");
3257        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3258                false, true, "startActivity", null);
3259        // TODO: Switch to user app stacks here.
3260        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3261                resolvedTypes, resultTo, options, userId);
3262        return ret;
3263    }
3264
3265    final int startActivitiesInPackage(int uid, String callingPackage,
3266            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3267            Bundle options, int userId) {
3268
3269        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3270                false, true, "startActivityInPackage", null);
3271        // TODO: Switch to user app stacks here.
3272        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3273                resultTo, options, userId);
3274        return ret;
3275    }
3276
3277    final void addRecentTaskLocked(TaskRecord task) {
3278        int N = mRecentTasks.size();
3279        // Quick case: check if the top-most recent task is the same.
3280        if (N > 0 && mRecentTasks.get(0) == task) {
3281            return;
3282        }
3283        // Remove any existing entries that are the same kind of task.
3284        for (int i=0; i<N; i++) {
3285            TaskRecord tr = mRecentTasks.get(i);
3286            if (task.userId == tr.userId
3287                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3288                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3289                tr.disposeThumbnail();
3290                mRecentTasks.remove(i);
3291                i--;
3292                N--;
3293                if (task.intent == null) {
3294                    // If the new recent task we are adding is not fully
3295                    // specified, then replace it with the existing recent task.
3296                    task = tr;
3297                }
3298            }
3299        }
3300        if (N >= MAX_RECENT_TASKS) {
3301            mRecentTasks.remove(N-1).disposeThumbnail();
3302        }
3303        mRecentTasks.add(0, task);
3304    }
3305
3306    @Override
3307    public void reportActivityFullyDrawn(IBinder token) {
3308        synchronized (this) {
3309            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3310            if (r == null) {
3311                return;
3312            }
3313            r.reportFullyDrawnLocked();
3314        }
3315    }
3316
3317    @Override
3318    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3319        synchronized (this) {
3320            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3321            if (r == null) {
3322                return;
3323            }
3324            final long origId = Binder.clearCallingIdentity();
3325            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3326            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3327                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3328            if (config != null) {
3329                r.frozenBeforeDestroy = true;
3330                if (!updateConfigurationLocked(config, r, false, false)) {
3331                    mStackSupervisor.resumeTopActivitiesLocked();
3332                }
3333            }
3334            Binder.restoreCallingIdentity(origId);
3335        }
3336    }
3337
3338    @Override
3339    public int getRequestedOrientation(IBinder token) {
3340        synchronized (this) {
3341            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3342            if (r == null) {
3343                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3344            }
3345            return mWindowManager.getAppOrientation(r.appToken);
3346        }
3347    }
3348
3349    /**
3350     * This is the internal entry point for handling Activity.finish().
3351     *
3352     * @param token The Binder token referencing the Activity we want to finish.
3353     * @param resultCode Result code, if any, from this Activity.
3354     * @param resultData Result data (Intent), if any, from this Activity.
3355     *
3356     * @return Returns true if the activity successfully finished, or false if it is still running.
3357     */
3358    @Override
3359    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3360        // Refuse possible leaked file descriptors
3361        if (resultData != null && resultData.hasFileDescriptors() == true) {
3362            throw new IllegalArgumentException("File descriptors passed in Intent");
3363        }
3364
3365        synchronized(this) {
3366            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3367            if (r == null) {
3368                return true;
3369            }
3370            if (mController != null) {
3371                // Find the first activity that is not finishing.
3372                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3373                if (next != null) {
3374                    // ask watcher if this is allowed
3375                    boolean resumeOK = true;
3376                    try {
3377                        resumeOK = mController.activityResuming(next.packageName);
3378                    } catch (RemoteException e) {
3379                        mController = null;
3380                        Watchdog.getInstance().setActivityController(null);
3381                    }
3382
3383                    if (!resumeOK) {
3384                        return false;
3385                    }
3386                }
3387            }
3388            final long origId = Binder.clearCallingIdentity();
3389            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3390                    resultData, "app-request", true);
3391            Binder.restoreCallingIdentity(origId);
3392            return res;
3393        }
3394    }
3395
3396    @Override
3397    public final void finishHeavyWeightApp() {
3398        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3399                != PackageManager.PERMISSION_GRANTED) {
3400            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3401                    + Binder.getCallingPid()
3402                    + ", uid=" + Binder.getCallingUid()
3403                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3404            Slog.w(TAG, msg);
3405            throw new SecurityException(msg);
3406        }
3407
3408        synchronized(this) {
3409            if (mHeavyWeightProcess == null) {
3410                return;
3411            }
3412
3413            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3414                    mHeavyWeightProcess.activities);
3415            for (int i=0; i<activities.size(); i++) {
3416                ActivityRecord r = activities.get(i);
3417                if (!r.finishing) {
3418                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3419                            null, "finish-heavy", true);
3420                }
3421            }
3422
3423            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3424                    mHeavyWeightProcess.userId, 0));
3425            mHeavyWeightProcess = null;
3426        }
3427    }
3428
3429    @Override
3430    public void crashApplication(int uid, int initialPid, String packageName,
3431            String message) {
3432        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3433                != PackageManager.PERMISSION_GRANTED) {
3434            String msg = "Permission Denial: crashApplication() from pid="
3435                    + Binder.getCallingPid()
3436                    + ", uid=" + Binder.getCallingUid()
3437                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3438            Slog.w(TAG, msg);
3439            throw new SecurityException(msg);
3440        }
3441
3442        synchronized(this) {
3443            ProcessRecord proc = null;
3444
3445            // Figure out which process to kill.  We don't trust that initialPid
3446            // still has any relation to current pids, so must scan through the
3447            // list.
3448            synchronized (mPidsSelfLocked) {
3449                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3450                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3451                    if (p.uid != uid) {
3452                        continue;
3453                    }
3454                    if (p.pid == initialPid) {
3455                        proc = p;
3456                        break;
3457                    }
3458                    if (p.pkgList.containsKey(packageName)) {
3459                        proc = p;
3460                    }
3461                }
3462            }
3463
3464            if (proc == null) {
3465                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3466                        + " initialPid=" + initialPid
3467                        + " packageName=" + packageName);
3468                return;
3469            }
3470
3471            if (proc.thread != null) {
3472                if (proc.pid == Process.myPid()) {
3473                    Log.w(TAG, "crashApplication: trying to crash self!");
3474                    return;
3475                }
3476                long ident = Binder.clearCallingIdentity();
3477                try {
3478                    proc.thread.scheduleCrash(message);
3479                } catch (RemoteException e) {
3480                }
3481                Binder.restoreCallingIdentity(ident);
3482            }
3483        }
3484    }
3485
3486    @Override
3487    public final void finishSubActivity(IBinder token, String resultWho,
3488            int requestCode) {
3489        synchronized(this) {
3490            final long origId = Binder.clearCallingIdentity();
3491            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3492            if (r != null) {
3493                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3494            }
3495            Binder.restoreCallingIdentity(origId);
3496        }
3497    }
3498
3499    @Override
3500    public boolean finishActivityAffinity(IBinder token) {
3501        synchronized(this) {
3502            final long origId = Binder.clearCallingIdentity();
3503            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3504            boolean res = false;
3505            if (r != null) {
3506                res = r.task.stack.finishActivityAffinityLocked(r);
3507            }
3508            Binder.restoreCallingIdentity(origId);
3509            return res;
3510        }
3511    }
3512
3513    @Override
3514    public boolean willActivityBeVisible(IBinder token) {
3515        synchronized(this) {
3516            ActivityStack stack = ActivityRecord.getStackLocked(token);
3517            if (stack != null) {
3518                return stack.willActivityBeVisibleLocked(token);
3519            }
3520            return false;
3521        }
3522    }
3523
3524    @Override
3525    public void overridePendingTransition(IBinder token, String packageName,
3526            int enterAnim, int exitAnim) {
3527        synchronized(this) {
3528            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3529            if (self == null) {
3530                return;
3531            }
3532
3533            final long origId = Binder.clearCallingIdentity();
3534
3535            if (self.state == ActivityState.RESUMED
3536                    || self.state == ActivityState.PAUSING) {
3537                mWindowManager.overridePendingAppTransition(packageName,
3538                        enterAnim, exitAnim, null);
3539            }
3540
3541            Binder.restoreCallingIdentity(origId);
3542        }
3543    }
3544
3545    /**
3546     * Main function for removing an existing process from the activity manager
3547     * as a result of that process going away.  Clears out all connections
3548     * to the process.
3549     */
3550    private final void handleAppDiedLocked(ProcessRecord app,
3551            boolean restarting, boolean allowRestart) {
3552        int pid = app.pid;
3553        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3554        if (!restarting) {
3555            removeLruProcessLocked(app);
3556            if (pid > 0) {
3557                ProcessList.remove(pid);
3558            }
3559        }
3560
3561        if (mProfileProc == app) {
3562            clearProfilerLocked();
3563        }
3564
3565        // Remove this application's activities from active lists.
3566        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3567
3568        app.activities.clear();
3569
3570        if (app.instrumentationClass != null) {
3571            Slog.w(TAG, "Crash of app " + app.processName
3572                  + " running instrumentation " + app.instrumentationClass);
3573            Bundle info = new Bundle();
3574            info.putString("shortMsg", "Process crashed.");
3575            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3576        }
3577
3578        if (!restarting) {
3579            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3580                // If there was nothing to resume, and we are not already
3581                // restarting this process, but there is a visible activity that
3582                // is hosted by the process...  then make sure all visible
3583                // activities are running, taking care of restarting this
3584                // process.
3585                if (hasVisibleActivities) {
3586                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3587                }
3588            }
3589        }
3590    }
3591
3592    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3593        IBinder threadBinder = thread.asBinder();
3594        // Find the application record.
3595        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3596            ProcessRecord rec = mLruProcesses.get(i);
3597            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3598                return i;
3599            }
3600        }
3601        return -1;
3602    }
3603
3604    final ProcessRecord getRecordForAppLocked(
3605            IApplicationThread thread) {
3606        if (thread == null) {
3607            return null;
3608        }
3609
3610        int appIndex = getLRURecordIndexForAppLocked(thread);
3611        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3612    }
3613
3614    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3615        // If there are no longer any background processes running,
3616        // and the app that died was not running instrumentation,
3617        // then tell everyone we are now low on memory.
3618        boolean haveBg = false;
3619        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3620            ProcessRecord rec = mLruProcesses.get(i);
3621            if (rec.thread != null
3622                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3623                haveBg = true;
3624                break;
3625            }
3626        }
3627
3628        if (!haveBg) {
3629            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3630            if (doReport) {
3631                long now = SystemClock.uptimeMillis();
3632                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3633                    doReport = false;
3634                } else {
3635                    mLastMemUsageReportTime = now;
3636                }
3637            }
3638            final ArrayList<ProcessMemInfo> memInfos
3639                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3640            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3641            long now = SystemClock.uptimeMillis();
3642            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3643                ProcessRecord rec = mLruProcesses.get(i);
3644                if (rec == dyingProc || rec.thread == null) {
3645                    continue;
3646                }
3647                if (doReport) {
3648                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3649                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3650                }
3651                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3652                    // The low memory report is overriding any current
3653                    // state for a GC request.  Make sure to do
3654                    // heavy/important/visible/foreground processes first.
3655                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3656                        rec.lastRequestedGc = 0;
3657                    } else {
3658                        rec.lastRequestedGc = rec.lastLowMemory;
3659                    }
3660                    rec.reportLowMemory = true;
3661                    rec.lastLowMemory = now;
3662                    mProcessesToGc.remove(rec);
3663                    addProcessToGcListLocked(rec);
3664                }
3665            }
3666            if (doReport) {
3667                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3668                mHandler.sendMessage(msg);
3669            }
3670            scheduleAppGcsLocked();
3671        }
3672    }
3673
3674    final void appDiedLocked(ProcessRecord app, int pid,
3675            IApplicationThread thread) {
3676
3677        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3678        synchronized (stats) {
3679            stats.noteProcessDiedLocked(app.info.uid, pid);
3680        }
3681
3682        // Clean up already done if the process has been re-started.
3683        if (app.pid == pid && app.thread != null &&
3684                app.thread.asBinder() == thread.asBinder()) {
3685            boolean doLowMem = app.instrumentationClass == null;
3686            boolean doOomAdj = doLowMem;
3687            if (!app.killedByAm) {
3688                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3689                        + ") has died.");
3690                mAllowLowerMemLevel = true;
3691            } else {
3692                // Note that we always want to do oom adj to update our state with the
3693                // new number of procs.
3694                mAllowLowerMemLevel = false;
3695                doLowMem = false;
3696            }
3697            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3698            if (DEBUG_CLEANUP) Slog.v(
3699                TAG, "Dying app: " + app + ", pid: " + pid
3700                + ", thread: " + thread.asBinder());
3701            handleAppDiedLocked(app, false, true);
3702
3703            if (doOomAdj) {
3704                updateOomAdjLocked();
3705            }
3706            if (doLowMem) {
3707                doLowMemReportIfNeededLocked(app);
3708            }
3709        } else if (app.pid != pid) {
3710            // A new process has already been started.
3711            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3712                    + ") has died and restarted (pid " + app.pid + ").");
3713            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3714        } else if (DEBUG_PROCESSES) {
3715            Slog.d(TAG, "Received spurious death notification for thread "
3716                    + thread.asBinder());
3717        }
3718    }
3719
3720    /**
3721     * If a stack trace dump file is configured, dump process stack traces.
3722     * @param clearTraces causes the dump file to be erased prior to the new
3723     *    traces being written, if true; when false, the new traces will be
3724     *    appended to any existing file content.
3725     * @param firstPids of dalvik VM processes to dump stack traces for first
3726     * @param lastPids of dalvik VM processes to dump stack traces for last
3727     * @param nativeProcs optional list of native process names to dump stack crawls
3728     * @return file containing stack traces, or null if no dump file is configured
3729     */
3730    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3731            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3732        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3733        if (tracesPath == null || tracesPath.length() == 0) {
3734            return null;
3735        }
3736
3737        File tracesFile = new File(tracesPath);
3738        try {
3739            File tracesDir = tracesFile.getParentFile();
3740            if (!tracesDir.exists()) {
3741                tracesFile.mkdirs();
3742                if (!SELinux.restorecon(tracesDir)) {
3743                    return null;
3744                }
3745            }
3746            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3747
3748            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3749            tracesFile.createNewFile();
3750            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3751        } catch (IOException e) {
3752            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3753            return null;
3754        }
3755
3756        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3757        return tracesFile;
3758    }
3759
3760    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3761            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3762        // Use a FileObserver to detect when traces finish writing.
3763        // The order of traces is considered important to maintain for legibility.
3764        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3765            @Override
3766            public synchronized void onEvent(int event, String path) { notify(); }
3767        };
3768
3769        try {
3770            observer.startWatching();
3771
3772            // First collect all of the stacks of the most important pids.
3773            if (firstPids != null) {
3774                try {
3775                    int num = firstPids.size();
3776                    for (int i = 0; i < num; i++) {
3777                        synchronized (observer) {
3778                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3779                            observer.wait(200);  // Wait for write-close, give up after 200msec
3780                        }
3781                    }
3782                } catch (InterruptedException e) {
3783                    Log.wtf(TAG, e);
3784                }
3785            }
3786
3787            // Next collect the stacks of the native pids
3788            if (nativeProcs != null) {
3789                int[] pids = Process.getPidsForCommands(nativeProcs);
3790                if (pids != null) {
3791                    for (int pid : pids) {
3792                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3793                    }
3794                }
3795            }
3796
3797            // Lastly, measure CPU usage.
3798            if (processCpuTracker != null) {
3799                processCpuTracker.init();
3800                System.gc();
3801                processCpuTracker.update();
3802                try {
3803                    synchronized (processCpuTracker) {
3804                        processCpuTracker.wait(500); // measure over 1/2 second.
3805                    }
3806                } catch (InterruptedException e) {
3807                }
3808                processCpuTracker.update();
3809
3810                // We'll take the stack crawls of just the top apps using CPU.
3811                final int N = processCpuTracker.countWorkingStats();
3812                int numProcs = 0;
3813                for (int i=0; i<N && numProcs<5; i++) {
3814                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3815                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3816                        numProcs++;
3817                        try {
3818                            synchronized (observer) {
3819                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3820                                observer.wait(200);  // Wait for write-close, give up after 200msec
3821                            }
3822                        } catch (InterruptedException e) {
3823                            Log.wtf(TAG, e);
3824                        }
3825
3826                    }
3827                }
3828            }
3829        } finally {
3830            observer.stopWatching();
3831        }
3832    }
3833
3834    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3835        if (true || IS_USER_BUILD) {
3836            return;
3837        }
3838        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3839        if (tracesPath == null || tracesPath.length() == 0) {
3840            return;
3841        }
3842
3843        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3844        StrictMode.allowThreadDiskWrites();
3845        try {
3846            final File tracesFile = new File(tracesPath);
3847            final File tracesDir = tracesFile.getParentFile();
3848            final File tracesTmp = new File(tracesDir, "__tmp__");
3849            try {
3850                if (!tracesDir.exists()) {
3851                    tracesFile.mkdirs();
3852                    if (!SELinux.restorecon(tracesDir.getPath())) {
3853                        return;
3854                    }
3855                }
3856                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3857
3858                if (tracesFile.exists()) {
3859                    tracesTmp.delete();
3860                    tracesFile.renameTo(tracesTmp);
3861                }
3862                StringBuilder sb = new StringBuilder();
3863                Time tobj = new Time();
3864                tobj.set(System.currentTimeMillis());
3865                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3866                sb.append(": ");
3867                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3868                sb.append(" since ");
3869                sb.append(msg);
3870                FileOutputStream fos = new FileOutputStream(tracesFile);
3871                fos.write(sb.toString().getBytes());
3872                if (app == null) {
3873                    fos.write("\n*** No application process!".getBytes());
3874                }
3875                fos.close();
3876                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3877            } catch (IOException e) {
3878                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3879                return;
3880            }
3881
3882            if (app != null) {
3883                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3884                firstPids.add(app.pid);
3885                dumpStackTraces(tracesPath, firstPids, null, null, null);
3886            }
3887
3888            File lastTracesFile = null;
3889            File curTracesFile = null;
3890            for (int i=9; i>=0; i--) {
3891                String name = String.format(Locale.US, "slow%02d.txt", i);
3892                curTracesFile = new File(tracesDir, name);
3893                if (curTracesFile.exists()) {
3894                    if (lastTracesFile != null) {
3895                        curTracesFile.renameTo(lastTracesFile);
3896                    } else {
3897                        curTracesFile.delete();
3898                    }
3899                }
3900                lastTracesFile = curTracesFile;
3901            }
3902            tracesFile.renameTo(curTracesFile);
3903            if (tracesTmp.exists()) {
3904                tracesTmp.renameTo(tracesFile);
3905            }
3906        } finally {
3907            StrictMode.setThreadPolicy(oldPolicy);
3908        }
3909    }
3910
3911    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3912            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3913        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3914        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3915
3916        if (mController != null) {
3917            try {
3918                // 0 == continue, -1 = kill process immediately
3919                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3920                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3921            } catch (RemoteException e) {
3922                mController = null;
3923                Watchdog.getInstance().setActivityController(null);
3924            }
3925        }
3926
3927        long anrTime = SystemClock.uptimeMillis();
3928        if (MONITOR_CPU_USAGE) {
3929            updateCpuStatsNow();
3930        }
3931
3932        synchronized (this) {
3933            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3934            if (mShuttingDown) {
3935                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3936                return;
3937            } else if (app.notResponding) {
3938                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3939                return;
3940            } else if (app.crashing) {
3941                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3942                return;
3943            }
3944
3945            // In case we come through here for the same app before completing
3946            // this one, mark as anring now so we will bail out.
3947            app.notResponding = true;
3948
3949            // Log the ANR to the event log.
3950            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3951                    app.processName, app.info.flags, annotation);
3952
3953            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3954            firstPids.add(app.pid);
3955
3956            int parentPid = app.pid;
3957            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3958            if (parentPid != app.pid) firstPids.add(parentPid);
3959
3960            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3961
3962            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3963                ProcessRecord r = mLruProcesses.get(i);
3964                if (r != null && r.thread != null) {
3965                    int pid = r.pid;
3966                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3967                        if (r.persistent) {
3968                            firstPids.add(pid);
3969                        } else {
3970                            lastPids.put(pid, Boolean.TRUE);
3971                        }
3972                    }
3973                }
3974            }
3975        }
3976
3977        // Log the ANR to the main log.
3978        StringBuilder info = new StringBuilder();
3979        info.setLength(0);
3980        info.append("ANR in ").append(app.processName);
3981        if (activity != null && activity.shortComponentName != null) {
3982            info.append(" (").append(activity.shortComponentName).append(")");
3983        }
3984        info.append("\n");
3985        info.append("PID: ").append(app.pid).append("\n");
3986        if (annotation != null) {
3987            info.append("Reason: ").append(annotation).append("\n");
3988        }
3989        if (parent != null && parent != activity) {
3990            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3991        }
3992
3993        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
3994
3995        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
3996                NATIVE_STACKS_OF_INTEREST);
3997
3998        String cpuInfo = null;
3999        if (MONITOR_CPU_USAGE) {
4000            updateCpuStatsNow();
4001            synchronized (mProcessCpuThread) {
4002                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4003            }
4004            info.append(processCpuTracker.printCurrentLoad());
4005            info.append(cpuInfo);
4006        }
4007
4008        info.append(processCpuTracker.printCurrentState(anrTime));
4009
4010        Slog.e(TAG, info.toString());
4011        if (tracesFile == null) {
4012            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4013            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4014        }
4015
4016        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4017                cpuInfo, tracesFile, null);
4018
4019        if (mController != null) {
4020            try {
4021                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4022                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4023                if (res != 0) {
4024                    if (res < 0 && app.pid != MY_PID) {
4025                        Process.killProcess(app.pid);
4026                    } else {
4027                        synchronized (this) {
4028                            mServices.scheduleServiceTimeoutLocked(app);
4029                        }
4030                    }
4031                    return;
4032                }
4033            } catch (RemoteException e) {
4034                mController = null;
4035                Watchdog.getInstance().setActivityController(null);
4036            }
4037        }
4038
4039        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4040        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4041                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4042
4043        synchronized (this) {
4044            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4045                killUnneededProcessLocked(app, "background ANR");
4046                return;
4047            }
4048
4049            // Set the app's notResponding state, and look up the errorReportReceiver
4050            makeAppNotRespondingLocked(app,
4051                    activity != null ? activity.shortComponentName : null,
4052                    annotation != null ? "ANR " + annotation : "ANR",
4053                    info.toString());
4054
4055            // Bring up the infamous App Not Responding dialog
4056            Message msg = Message.obtain();
4057            HashMap<String, Object> map = new HashMap<String, Object>();
4058            msg.what = SHOW_NOT_RESPONDING_MSG;
4059            msg.obj = map;
4060            msg.arg1 = aboveSystem ? 1 : 0;
4061            map.put("app", app);
4062            if (activity != null) {
4063                map.put("activity", activity);
4064            }
4065
4066            mHandler.sendMessage(msg);
4067        }
4068    }
4069
4070    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4071        if (!mLaunchWarningShown) {
4072            mLaunchWarningShown = true;
4073            mHandler.post(new Runnable() {
4074                @Override
4075                public void run() {
4076                    synchronized (ActivityManagerService.this) {
4077                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4078                        d.show();
4079                        mHandler.postDelayed(new Runnable() {
4080                            @Override
4081                            public void run() {
4082                                synchronized (ActivityManagerService.this) {
4083                                    d.dismiss();
4084                                    mLaunchWarningShown = false;
4085                                }
4086                            }
4087                        }, 4000);
4088                    }
4089                }
4090            });
4091        }
4092    }
4093
4094    @Override
4095    public boolean clearApplicationUserData(final String packageName,
4096            final IPackageDataObserver observer, int userId) {
4097        enforceNotIsolatedCaller("clearApplicationUserData");
4098        int uid = Binder.getCallingUid();
4099        int pid = Binder.getCallingPid();
4100        userId = handleIncomingUser(pid, uid,
4101                userId, false, true, "clearApplicationUserData", null);
4102        long callingId = Binder.clearCallingIdentity();
4103        try {
4104            IPackageManager pm = AppGlobals.getPackageManager();
4105            int pkgUid = -1;
4106            synchronized(this) {
4107                try {
4108                    pkgUid = pm.getPackageUid(packageName, userId);
4109                } catch (RemoteException e) {
4110                }
4111                if (pkgUid == -1) {
4112                    Slog.w(TAG, "Invalid packageName: " + packageName);
4113                    if (observer != null) {
4114                        try {
4115                            observer.onRemoveCompleted(packageName, false);
4116                        } catch (RemoteException e) {
4117                            Slog.i(TAG, "Observer no longer exists.");
4118                        }
4119                    }
4120                    return false;
4121                }
4122                if (uid == pkgUid || checkComponentPermission(
4123                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4124                        pid, uid, -1, true)
4125                        == PackageManager.PERMISSION_GRANTED) {
4126                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4127                } else {
4128                    throw new SecurityException("PID " + pid + " does not have permission "
4129                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4130                                    + " of package " + packageName);
4131                }
4132            }
4133
4134            try {
4135                // Clear application user data
4136                pm.clearApplicationUserData(packageName, observer, userId);
4137
4138                // Remove all permissions granted from/to this package
4139                removeUriPermissionsForPackageLocked(packageName, userId, true);
4140
4141                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4142                        Uri.fromParts("package", packageName, null));
4143                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4144                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4145                        null, null, 0, null, null, null, false, false, userId);
4146            } catch (RemoteException e) {
4147            }
4148        } finally {
4149            Binder.restoreCallingIdentity(callingId);
4150        }
4151        return true;
4152    }
4153
4154    @Override
4155    public void killBackgroundProcesses(final String packageName, int userId) {
4156        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4157                != PackageManager.PERMISSION_GRANTED &&
4158                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4159                        != PackageManager.PERMISSION_GRANTED) {
4160            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4161                    + Binder.getCallingPid()
4162                    + ", uid=" + Binder.getCallingUid()
4163                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4164            Slog.w(TAG, msg);
4165            throw new SecurityException(msg);
4166        }
4167
4168        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4169                userId, true, true, "killBackgroundProcesses", null);
4170        long callingId = Binder.clearCallingIdentity();
4171        try {
4172            IPackageManager pm = AppGlobals.getPackageManager();
4173            synchronized(this) {
4174                int appId = -1;
4175                try {
4176                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4177                } catch (RemoteException e) {
4178                }
4179                if (appId == -1) {
4180                    Slog.w(TAG, "Invalid packageName: " + packageName);
4181                    return;
4182                }
4183                killPackageProcessesLocked(packageName, appId, userId,
4184                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4185            }
4186        } finally {
4187            Binder.restoreCallingIdentity(callingId);
4188        }
4189    }
4190
4191    @Override
4192    public void killAllBackgroundProcesses() {
4193        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4194                != PackageManager.PERMISSION_GRANTED) {
4195            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4196                    + Binder.getCallingPid()
4197                    + ", uid=" + Binder.getCallingUid()
4198                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4199            Slog.w(TAG, msg);
4200            throw new SecurityException(msg);
4201        }
4202
4203        long callingId = Binder.clearCallingIdentity();
4204        try {
4205            synchronized(this) {
4206                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4207                final int NP = mProcessNames.getMap().size();
4208                for (int ip=0; ip<NP; ip++) {
4209                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4210                    final int NA = apps.size();
4211                    for (int ia=0; ia<NA; ia++) {
4212                        ProcessRecord app = apps.valueAt(ia);
4213                        if (app.persistent) {
4214                            // we don't kill persistent processes
4215                            continue;
4216                        }
4217                        if (app.removed) {
4218                            procs.add(app);
4219                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4220                            app.removed = true;
4221                            procs.add(app);
4222                        }
4223                    }
4224                }
4225
4226                int N = procs.size();
4227                for (int i=0; i<N; i++) {
4228                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4229                }
4230                mAllowLowerMemLevel = true;
4231                updateOomAdjLocked();
4232                doLowMemReportIfNeededLocked(null);
4233            }
4234        } finally {
4235            Binder.restoreCallingIdentity(callingId);
4236        }
4237    }
4238
4239    @Override
4240    public void forceStopPackage(final String packageName, int userId) {
4241        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4242                != PackageManager.PERMISSION_GRANTED) {
4243            String msg = "Permission Denial: forceStopPackage() from pid="
4244                    + Binder.getCallingPid()
4245                    + ", uid=" + Binder.getCallingUid()
4246                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4247            Slog.w(TAG, msg);
4248            throw new SecurityException(msg);
4249        }
4250        final int callingPid = Binder.getCallingPid();
4251        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4252                userId, true, true, "forceStopPackage", null);
4253        long callingId = Binder.clearCallingIdentity();
4254        try {
4255            IPackageManager pm = AppGlobals.getPackageManager();
4256            synchronized(this) {
4257                int[] users = userId == UserHandle.USER_ALL
4258                        ? getUsersLocked() : new int[] { userId };
4259                for (int user : users) {
4260                    int pkgUid = -1;
4261                    try {
4262                        pkgUid = pm.getPackageUid(packageName, user);
4263                    } catch (RemoteException e) {
4264                    }
4265                    if (pkgUid == -1) {
4266                        Slog.w(TAG, "Invalid packageName: " + packageName);
4267                        continue;
4268                    }
4269                    try {
4270                        pm.setPackageStoppedState(packageName, true, user);
4271                    } catch (RemoteException e) {
4272                    } catch (IllegalArgumentException e) {
4273                        Slog.w(TAG, "Failed trying to unstop package "
4274                                + packageName + ": " + e);
4275                    }
4276                    if (isUserRunningLocked(user, false)) {
4277                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4278                    }
4279                }
4280            }
4281        } finally {
4282            Binder.restoreCallingIdentity(callingId);
4283        }
4284    }
4285
4286    /*
4287     * The pkg name and app id have to be specified.
4288     */
4289    @Override
4290    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4291        if (pkg == null) {
4292            return;
4293        }
4294        // Make sure the uid is valid.
4295        if (appid < 0) {
4296            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4297            return;
4298        }
4299        int callerUid = Binder.getCallingUid();
4300        // Only the system server can kill an application
4301        if (callerUid == Process.SYSTEM_UID) {
4302            // Post an aysnc message to kill the application
4303            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4304            msg.arg1 = appid;
4305            msg.arg2 = 0;
4306            Bundle bundle = new Bundle();
4307            bundle.putString("pkg", pkg);
4308            bundle.putString("reason", reason);
4309            msg.obj = bundle;
4310            mHandler.sendMessage(msg);
4311        } else {
4312            throw new SecurityException(callerUid + " cannot kill pkg: " +
4313                    pkg);
4314        }
4315    }
4316
4317    @Override
4318    public void closeSystemDialogs(String reason) {
4319        enforceNotIsolatedCaller("closeSystemDialogs");
4320
4321        final int pid = Binder.getCallingPid();
4322        final int uid = Binder.getCallingUid();
4323        final long origId = Binder.clearCallingIdentity();
4324        try {
4325            synchronized (this) {
4326                // Only allow this from foreground processes, so that background
4327                // applications can't abuse it to prevent system UI from being shown.
4328                if (uid >= Process.FIRST_APPLICATION_UID) {
4329                    ProcessRecord proc;
4330                    synchronized (mPidsSelfLocked) {
4331                        proc = mPidsSelfLocked.get(pid);
4332                    }
4333                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4334                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4335                                + " from background process " + proc);
4336                        return;
4337                    }
4338                }
4339                closeSystemDialogsLocked(reason);
4340            }
4341        } finally {
4342            Binder.restoreCallingIdentity(origId);
4343        }
4344    }
4345
4346    void closeSystemDialogsLocked(String reason) {
4347        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4348        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4349                | Intent.FLAG_RECEIVER_FOREGROUND);
4350        if (reason != null) {
4351            intent.putExtra("reason", reason);
4352        }
4353        mWindowManager.closeSystemDialogs(reason);
4354
4355        mStackSupervisor.closeSystemDialogsLocked();
4356
4357        broadcastIntentLocked(null, null, intent, null,
4358                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4359                Process.SYSTEM_UID, UserHandle.USER_ALL);
4360    }
4361
4362    @Override
4363    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4364        enforceNotIsolatedCaller("getProcessMemoryInfo");
4365        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4366        for (int i=pids.length-1; i>=0; i--) {
4367            ProcessRecord proc;
4368            int oomAdj;
4369            synchronized (this) {
4370                synchronized (mPidsSelfLocked) {
4371                    proc = mPidsSelfLocked.get(pids[i]);
4372                    oomAdj = proc != null ? proc.setAdj : 0;
4373                }
4374            }
4375            infos[i] = new Debug.MemoryInfo();
4376            Debug.getMemoryInfo(pids[i], infos[i]);
4377            if (proc != null) {
4378                synchronized (this) {
4379                    if (proc.thread != null && proc.setAdj == oomAdj) {
4380                        // Record this for posterity if the process has been stable.
4381                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4382                                infos[i].getTotalUss(), false, proc.pkgList);
4383                    }
4384                }
4385            }
4386        }
4387        return infos;
4388    }
4389
4390    @Override
4391    public long[] getProcessPss(int[] pids) {
4392        enforceNotIsolatedCaller("getProcessPss");
4393        long[] pss = new long[pids.length];
4394        for (int i=pids.length-1; i>=0; i--) {
4395            ProcessRecord proc;
4396            int oomAdj;
4397            synchronized (this) {
4398                synchronized (mPidsSelfLocked) {
4399                    proc = mPidsSelfLocked.get(pids[i]);
4400                    oomAdj = proc != null ? proc.setAdj : 0;
4401                }
4402            }
4403            long[] tmpUss = new long[1];
4404            pss[i] = Debug.getPss(pids[i], tmpUss);
4405            if (proc != null) {
4406                synchronized (this) {
4407                    if (proc.thread != null && proc.setAdj == oomAdj) {
4408                        // Record this for posterity if the process has been stable.
4409                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4410                    }
4411                }
4412            }
4413        }
4414        return pss;
4415    }
4416
4417    @Override
4418    public void killApplicationProcess(String processName, int uid) {
4419        if (processName == null) {
4420            return;
4421        }
4422
4423        int callerUid = Binder.getCallingUid();
4424        // Only the system server can kill an application
4425        if (callerUid == Process.SYSTEM_UID) {
4426            synchronized (this) {
4427                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4428                if (app != null && app.thread != null) {
4429                    try {
4430                        app.thread.scheduleSuicide();
4431                    } catch (RemoteException e) {
4432                        // If the other end already died, then our work here is done.
4433                    }
4434                } else {
4435                    Slog.w(TAG, "Process/uid not found attempting kill of "
4436                            + processName + " / " + uid);
4437                }
4438            }
4439        } else {
4440            throw new SecurityException(callerUid + " cannot kill app process: " +
4441                    processName);
4442        }
4443    }
4444
4445    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4446        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4447                false, true, false, UserHandle.getUserId(uid), reason);
4448        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4449                Uri.fromParts("package", packageName, null));
4450        if (!mProcessesReady) {
4451            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4452                    | Intent.FLAG_RECEIVER_FOREGROUND);
4453        }
4454        intent.putExtra(Intent.EXTRA_UID, uid);
4455        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4456        broadcastIntentLocked(null, null, intent,
4457                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4458                false, false,
4459                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4460    }
4461
4462    private void forceStopUserLocked(int userId, String reason) {
4463        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
4464        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4465        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4466                | Intent.FLAG_RECEIVER_FOREGROUND);
4467        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4468        broadcastIntentLocked(null, null, intent,
4469                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4470                false, false,
4471                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4472    }
4473
4474    private final boolean killPackageProcessesLocked(String packageName, int appId,
4475            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4476            boolean doit, boolean evenPersistent, String reason) {
4477        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4478
4479        // Remove all processes this package may have touched: all with the
4480        // same UID (except for the system or root user), and all whose name
4481        // matches the package name.
4482        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4483        final int NP = mProcessNames.getMap().size();
4484        for (int ip=0; ip<NP; ip++) {
4485            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4486            final int NA = apps.size();
4487            for (int ia=0; ia<NA; ia++) {
4488                ProcessRecord app = apps.valueAt(ia);
4489                if (app.persistent && !evenPersistent) {
4490                    // we don't kill persistent processes
4491                    continue;
4492                }
4493                if (app.removed) {
4494                    if (doit) {
4495                        procs.add(app);
4496                    }
4497                    continue;
4498                }
4499
4500                // Skip process if it doesn't meet our oom adj requirement.
4501                if (app.setAdj < minOomAdj) {
4502                    continue;
4503                }
4504
4505                // If no package is specified, we call all processes under the
4506                // give user id.
4507                if (packageName == null) {
4508                    if (app.userId != userId) {
4509                        continue;
4510                    }
4511                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4512                        continue;
4513                    }
4514                // Package has been specified, we want to hit all processes
4515                // that match it.  We need to qualify this by the processes
4516                // that are running under the specified app and user ID.
4517                } else {
4518                    if (UserHandle.getAppId(app.uid) != appId) {
4519                        continue;
4520                    }
4521                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4522                        continue;
4523                    }
4524                    if (!app.pkgList.containsKey(packageName)) {
4525                        continue;
4526                    }
4527                }
4528
4529                // Process has passed all conditions, kill it!
4530                if (!doit) {
4531                    return true;
4532                }
4533                app.removed = true;
4534                procs.add(app);
4535            }
4536        }
4537
4538        int N = procs.size();
4539        for (int i=0; i<N; i++) {
4540            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4541        }
4542        updateOomAdjLocked();
4543        return N > 0;
4544    }
4545
4546    private final boolean forceStopPackageLocked(String name, int appId,
4547            boolean callerWillRestart, boolean purgeCache, boolean doit,
4548            boolean evenPersistent, int userId, String reason) {
4549        int i;
4550        int N;
4551
4552        if (userId == UserHandle.USER_ALL && name == null) {
4553            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4554        }
4555
4556        if (appId < 0 && name != null) {
4557            try {
4558                appId = UserHandle.getAppId(
4559                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4560            } catch (RemoteException e) {
4561            }
4562        }
4563
4564        if (doit) {
4565            if (name != null) {
4566                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4567                        + " user=" + userId + ": " + reason);
4568            } else {
4569                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4570            }
4571
4572            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4573            for (int ip=pmap.size()-1; ip>=0; ip--) {
4574                SparseArray<Long> ba = pmap.valueAt(ip);
4575                for (i=ba.size()-1; i>=0; i--) {
4576                    boolean remove = false;
4577                    final int entUid = ba.keyAt(i);
4578                    if (name != null) {
4579                        if (userId == UserHandle.USER_ALL) {
4580                            if (UserHandle.getAppId(entUid) == appId) {
4581                                remove = true;
4582                            }
4583                        } else {
4584                            if (entUid == UserHandle.getUid(userId, appId)) {
4585                                remove = true;
4586                            }
4587                        }
4588                    } else if (UserHandle.getUserId(entUid) == userId) {
4589                        remove = true;
4590                    }
4591                    if (remove) {
4592                        ba.removeAt(i);
4593                    }
4594                }
4595                if (ba.size() == 0) {
4596                    pmap.removeAt(ip);
4597                }
4598            }
4599        }
4600
4601        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4602                -100, callerWillRestart, true, doit, evenPersistent,
4603                name == null ? ("stop user " + userId) : ("stop " + name));
4604
4605        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4606            if (!doit) {
4607                return true;
4608            }
4609            didSomething = true;
4610        }
4611
4612        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4613            if (!doit) {
4614                return true;
4615            }
4616            didSomething = true;
4617        }
4618
4619        if (name == null) {
4620            // Remove all sticky broadcasts from this user.
4621            mStickyBroadcasts.remove(userId);
4622        }
4623
4624        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4625        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4626                userId, providers)) {
4627            if (!doit) {
4628                return true;
4629            }
4630            didSomething = true;
4631        }
4632        N = providers.size();
4633        for (i=0; i<N; i++) {
4634            removeDyingProviderLocked(null, providers.get(i), true);
4635        }
4636
4637        // Remove transient permissions granted from/to this package/user
4638        removeUriPermissionsForPackageLocked(name, userId, false);
4639
4640        if (name == null) {
4641            // Remove pending intents.  For now we only do this when force
4642            // stopping users, because we have some problems when doing this
4643            // for packages -- app widgets are not currently cleaned up for
4644            // such packages, so they can be left with bad pending intents.
4645            if (mIntentSenderRecords.size() > 0) {
4646                Iterator<WeakReference<PendingIntentRecord>> it
4647                        = mIntentSenderRecords.values().iterator();
4648                while (it.hasNext()) {
4649                    WeakReference<PendingIntentRecord> wpir = it.next();
4650                    if (wpir == null) {
4651                        it.remove();
4652                        continue;
4653                    }
4654                    PendingIntentRecord pir = wpir.get();
4655                    if (pir == null) {
4656                        it.remove();
4657                        continue;
4658                    }
4659                    if (name == null) {
4660                        // Stopping user, remove all objects for the user.
4661                        if (pir.key.userId != userId) {
4662                            // Not the same user, skip it.
4663                            continue;
4664                        }
4665                    } else {
4666                        if (UserHandle.getAppId(pir.uid) != appId) {
4667                            // Different app id, skip it.
4668                            continue;
4669                        }
4670                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4671                            // Different user, skip it.
4672                            continue;
4673                        }
4674                        if (!pir.key.packageName.equals(name)) {
4675                            // Different package, skip it.
4676                            continue;
4677                        }
4678                    }
4679                    if (!doit) {
4680                        return true;
4681                    }
4682                    didSomething = true;
4683                    it.remove();
4684                    pir.canceled = true;
4685                    if (pir.key.activity != null) {
4686                        pir.key.activity.pendingResults.remove(pir.ref);
4687                    }
4688                }
4689            }
4690        }
4691
4692        if (doit) {
4693            if (purgeCache && name != null) {
4694                AttributeCache ac = AttributeCache.instance();
4695                if (ac != null) {
4696                    ac.removePackage(name);
4697                }
4698            }
4699            if (mBooted) {
4700                mStackSupervisor.resumeTopActivitiesLocked();
4701                mStackSupervisor.scheduleIdleLocked();
4702            }
4703        }
4704
4705        return didSomething;
4706    }
4707
4708    private final boolean removeProcessLocked(ProcessRecord app,
4709            boolean callerWillRestart, boolean allowRestart, String reason) {
4710        final String name = app.processName;
4711        final int uid = app.uid;
4712        if (DEBUG_PROCESSES) Slog.d(
4713            TAG, "Force removing proc " + app.toShortString() + " (" + name
4714            + "/" + uid + ")");
4715
4716        mProcessNames.remove(name, uid);
4717        mIsolatedProcesses.remove(app.uid);
4718        if (mHeavyWeightProcess == app) {
4719            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4720                    mHeavyWeightProcess.userId, 0));
4721            mHeavyWeightProcess = null;
4722        }
4723        boolean needRestart = false;
4724        if (app.pid > 0 && app.pid != MY_PID) {
4725            int pid = app.pid;
4726            synchronized (mPidsSelfLocked) {
4727                mPidsSelfLocked.remove(pid);
4728                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4729            }
4730            killUnneededProcessLocked(app, reason);
4731            handleAppDiedLocked(app, true, allowRestart);
4732            removeLruProcessLocked(app);
4733
4734            if (app.persistent && !app.isolated) {
4735                if (!callerWillRestart) {
4736                    addAppLocked(app.info, false);
4737                } else {
4738                    needRestart = true;
4739                }
4740            }
4741        } else {
4742            mRemovedProcesses.add(app);
4743        }
4744
4745        return needRestart;
4746    }
4747
4748    private final void processStartTimedOutLocked(ProcessRecord app) {
4749        final int pid = app.pid;
4750        boolean gone = false;
4751        synchronized (mPidsSelfLocked) {
4752            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4753            if (knownApp != null && knownApp.thread == null) {
4754                mPidsSelfLocked.remove(pid);
4755                gone = true;
4756            }
4757        }
4758
4759        if (gone) {
4760            Slog.w(TAG, "Process " + app + " failed to attach");
4761            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4762                    pid, app.uid, app.processName);
4763            mProcessNames.remove(app.processName, app.uid);
4764            mIsolatedProcesses.remove(app.uid);
4765            if (mHeavyWeightProcess == app) {
4766                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4767                        mHeavyWeightProcess.userId, 0));
4768                mHeavyWeightProcess = null;
4769            }
4770            // Take care of any launching providers waiting for this process.
4771            checkAppInLaunchingProvidersLocked(app, true);
4772            // Take care of any services that are waiting for the process.
4773            mServices.processStartTimedOutLocked(app);
4774            killUnneededProcessLocked(app, "start timeout");
4775            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4776                Slog.w(TAG, "Unattached app died before backup, skipping");
4777                try {
4778                    IBackupManager bm = IBackupManager.Stub.asInterface(
4779                            ServiceManager.getService(Context.BACKUP_SERVICE));
4780                    bm.agentDisconnected(app.info.packageName);
4781                } catch (RemoteException e) {
4782                    // Can't happen; the backup manager is local
4783                }
4784            }
4785            if (isPendingBroadcastProcessLocked(pid)) {
4786                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4787                skipPendingBroadcastLocked(pid);
4788            }
4789        } else {
4790            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4791        }
4792    }
4793
4794    private final boolean attachApplicationLocked(IApplicationThread thread,
4795            int pid) {
4796
4797        // Find the application record that is being attached...  either via
4798        // the pid if we are running in multiple processes, or just pull the
4799        // next app record if we are emulating process with anonymous threads.
4800        ProcessRecord app;
4801        if (pid != MY_PID && pid >= 0) {
4802            synchronized (mPidsSelfLocked) {
4803                app = mPidsSelfLocked.get(pid);
4804            }
4805        } else {
4806            app = null;
4807        }
4808
4809        if (app == null) {
4810            Slog.w(TAG, "No pending application record for pid " + pid
4811                    + " (IApplicationThread " + thread + "); dropping process");
4812            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4813            if (pid > 0 && pid != MY_PID) {
4814                Process.killProcessQuiet(pid);
4815            } else {
4816                try {
4817                    thread.scheduleExit();
4818                } catch (Exception e) {
4819                    // Ignore exceptions.
4820                }
4821            }
4822            return false;
4823        }
4824
4825        // If this application record is still attached to a previous
4826        // process, clean it up now.
4827        if (app.thread != null) {
4828            handleAppDiedLocked(app, true, true);
4829        }
4830
4831        // Tell the process all about itself.
4832
4833        if (localLOGV) Slog.v(
4834                TAG, "Binding process pid " + pid + " to record " + app);
4835
4836        final String processName = app.processName;
4837        try {
4838            AppDeathRecipient adr = new AppDeathRecipient(
4839                    app, pid, thread);
4840            thread.asBinder().linkToDeath(adr, 0);
4841            app.deathRecipient = adr;
4842        } catch (RemoteException e) {
4843            app.resetPackageList(mProcessStats);
4844            startProcessLocked(app, "link fail", processName);
4845            return false;
4846        }
4847
4848        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4849
4850        app.makeActive(thread, mProcessStats);
4851        app.curAdj = app.setAdj = -100;
4852        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4853        app.forcingToForeground = null;
4854        app.foregroundServices = false;
4855        app.hasShownUi = false;
4856        app.debugging = false;
4857        app.cached = false;
4858
4859        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4860
4861        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4862        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4863
4864        if (!normalMode) {
4865            Slog.i(TAG, "Launching preboot mode app: " + app);
4866        }
4867
4868        if (localLOGV) Slog.v(
4869            TAG, "New app record " + app
4870            + " thread=" + thread.asBinder() + " pid=" + pid);
4871        try {
4872            int testMode = IApplicationThread.DEBUG_OFF;
4873            if (mDebugApp != null && mDebugApp.equals(processName)) {
4874                testMode = mWaitForDebugger
4875                    ? IApplicationThread.DEBUG_WAIT
4876                    : IApplicationThread.DEBUG_ON;
4877                app.debugging = true;
4878                if (mDebugTransient) {
4879                    mDebugApp = mOrigDebugApp;
4880                    mWaitForDebugger = mOrigWaitForDebugger;
4881                }
4882            }
4883            String profileFile = app.instrumentationProfileFile;
4884            ParcelFileDescriptor profileFd = null;
4885            boolean profileAutoStop = false;
4886            if (mProfileApp != null && mProfileApp.equals(processName)) {
4887                mProfileProc = app;
4888                profileFile = mProfileFile;
4889                profileFd = mProfileFd;
4890                profileAutoStop = mAutoStopProfiler;
4891            }
4892            boolean enableOpenGlTrace = false;
4893            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4894                enableOpenGlTrace = true;
4895                mOpenGlTraceApp = null;
4896            }
4897
4898            // If the app is being launched for restore or full backup, set it up specially
4899            boolean isRestrictedBackupMode = false;
4900            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4901                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4902                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4903                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4904            }
4905
4906            ensurePackageDexOpt(app.instrumentationInfo != null
4907                    ? app.instrumentationInfo.packageName
4908                    : app.info.packageName);
4909            if (app.instrumentationClass != null) {
4910                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4911            }
4912            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4913                    + processName + " with config " + mConfiguration);
4914            ApplicationInfo appInfo = app.instrumentationInfo != null
4915                    ? app.instrumentationInfo : app.info;
4916            app.compat = compatibilityInfoForPackageLocked(appInfo);
4917            if (profileFd != null) {
4918                profileFd = profileFd.dup();
4919            }
4920            thread.bindApplication(processName, appInfo, providers,
4921                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4922                    app.instrumentationArguments, app.instrumentationWatcher,
4923                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4924                    isRestrictedBackupMode || !normalMode, app.persistent,
4925                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4926                    mCoreSettingsObserver.getCoreSettingsLocked());
4927            updateLruProcessLocked(app, false, null);
4928            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4929        } catch (Exception e) {
4930            // todo: Yikes!  What should we do?  For now we will try to
4931            // start another process, but that could easily get us in
4932            // an infinite loop of restarting processes...
4933            Slog.w(TAG, "Exception thrown during bind!", e);
4934
4935            app.resetPackageList(mProcessStats);
4936            app.unlinkDeathRecipient();
4937            startProcessLocked(app, "bind fail", processName);
4938            return false;
4939        }
4940
4941        // Remove this record from the list of starting applications.
4942        mPersistentStartingProcesses.remove(app);
4943        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4944                "Attach application locked removing on hold: " + app);
4945        mProcessesOnHold.remove(app);
4946
4947        boolean badApp = false;
4948        boolean didSomething = false;
4949
4950        // See if the top visible activity is waiting to run in this process...
4951        if (normalMode) {
4952            try {
4953                if (mStackSupervisor.attachApplicationLocked(app)) {
4954                    didSomething = true;
4955                }
4956            } catch (Exception e) {
4957                badApp = true;
4958            }
4959        }
4960
4961        // Find any services that should be running in this process...
4962        if (!badApp) {
4963            try {
4964                didSomething |= mServices.attachApplicationLocked(app, processName);
4965            } catch (Exception e) {
4966                badApp = true;
4967            }
4968        }
4969
4970        // Check if a next-broadcast receiver is in this process...
4971        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4972            try {
4973                didSomething |= sendPendingBroadcastsLocked(app);
4974            } catch (Exception e) {
4975                // If the app died trying to launch the receiver we declare it 'bad'
4976                badApp = true;
4977            }
4978        }
4979
4980        // Check whether the next backup agent is in this process...
4981        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4982            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4983            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4984            try {
4985                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4986                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4987                        mBackupTarget.backupMode);
4988            } catch (Exception e) {
4989                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4990                e.printStackTrace();
4991            }
4992        }
4993
4994        if (badApp) {
4995            // todo: Also need to kill application to deal with all
4996            // kinds of exceptions.
4997            handleAppDiedLocked(app, false, true);
4998            return false;
4999        }
5000
5001        if (!didSomething) {
5002            updateOomAdjLocked();
5003        }
5004
5005        return true;
5006    }
5007
5008    @Override
5009    public final void attachApplication(IApplicationThread thread) {
5010        synchronized (this) {
5011            int callingPid = Binder.getCallingPid();
5012            final long origId = Binder.clearCallingIdentity();
5013            attachApplicationLocked(thread, callingPid);
5014            Binder.restoreCallingIdentity(origId);
5015        }
5016    }
5017
5018    @Override
5019    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5020        final long origId = Binder.clearCallingIdentity();
5021        synchronized (this) {
5022            ActivityStack stack = ActivityRecord.getStackLocked(token);
5023            if (stack != null) {
5024                ActivityRecord r =
5025                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5026                if (stopProfiling) {
5027                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5028                        try {
5029                            mProfileFd.close();
5030                        } catch (IOException e) {
5031                        }
5032                        clearProfilerLocked();
5033                    }
5034                }
5035            }
5036        }
5037        Binder.restoreCallingIdentity(origId);
5038    }
5039
5040    void enableScreenAfterBoot() {
5041        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5042                SystemClock.uptimeMillis());
5043        mWindowManager.enableScreenAfterBoot();
5044
5045        synchronized (this) {
5046            updateEventDispatchingLocked();
5047        }
5048    }
5049
5050    @Override
5051    public void showBootMessage(final CharSequence msg, final boolean always) {
5052        enforceNotIsolatedCaller("showBootMessage");
5053        mWindowManager.showBootMessage(msg, always);
5054    }
5055
5056    @Override
5057    public void dismissKeyguardOnNextActivity() {
5058        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5059        final long token = Binder.clearCallingIdentity();
5060        try {
5061            synchronized (this) {
5062                if (DEBUG_LOCKSCREEN) logLockScreen("");
5063                if (mLockScreenShown) {
5064                    mLockScreenShown = false;
5065                    comeOutOfSleepIfNeededLocked();
5066                }
5067                mStackSupervisor.setDismissKeyguard(true);
5068            }
5069        } finally {
5070            Binder.restoreCallingIdentity(token);
5071        }
5072    }
5073
5074    final void finishBooting() {
5075        IntentFilter pkgFilter = new IntentFilter();
5076        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5077        pkgFilter.addDataScheme("package");
5078        mContext.registerReceiver(new BroadcastReceiver() {
5079            @Override
5080            public void onReceive(Context context, Intent intent) {
5081                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5082                if (pkgs != null) {
5083                    for (String pkg : pkgs) {
5084                        synchronized (ActivityManagerService.this) {
5085                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
5086                                    "finished booting")) {
5087                                setResultCode(Activity.RESULT_OK);
5088                                return;
5089                            }
5090                        }
5091                    }
5092                }
5093            }
5094        }, pkgFilter);
5095
5096        synchronized (this) {
5097            // Ensure that any processes we had put on hold are now started
5098            // up.
5099            final int NP = mProcessesOnHold.size();
5100            if (NP > 0) {
5101                ArrayList<ProcessRecord> procs =
5102                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5103                for (int ip=0; ip<NP; ip++) {
5104                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5105                            + procs.get(ip));
5106                    startProcessLocked(procs.get(ip), "on-hold", null);
5107                }
5108            }
5109
5110            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5111                // Start looking for apps that are abusing wake locks.
5112                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5113                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5114                // Tell anyone interested that we are done booting!
5115                SystemProperties.set("sys.boot_completed", "1");
5116                SystemProperties.set("dev.bootcomplete", "1");
5117                for (int i=0; i<mStartedUsers.size(); i++) {
5118                    UserStartedState uss = mStartedUsers.valueAt(i);
5119                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5120                        uss.mState = UserStartedState.STATE_RUNNING;
5121                        final int userId = mStartedUsers.keyAt(i);
5122                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5123                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5124                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5125                        broadcastIntentLocked(null, null, intent, null,
5126                                new IIntentReceiver.Stub() {
5127                                    @Override
5128                                    public void performReceive(Intent intent, int resultCode,
5129                                            String data, Bundle extras, boolean ordered,
5130                                            boolean sticky, int sendingUser) {
5131                                        synchronized (ActivityManagerService.this) {
5132                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5133                                                    true, false);
5134                                        }
5135                                    }
5136                                },
5137                                0, null, null,
5138                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5139                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5140                                userId);
5141                    }
5142                }
5143            }
5144        }
5145    }
5146
5147    final void ensureBootCompleted() {
5148        boolean booting;
5149        boolean enableScreen;
5150        synchronized (this) {
5151            booting = mBooting;
5152            mBooting = false;
5153            enableScreen = !mBooted;
5154            mBooted = true;
5155        }
5156
5157        if (booting) {
5158            finishBooting();
5159        }
5160
5161        if (enableScreen) {
5162            enableScreenAfterBoot();
5163        }
5164    }
5165
5166    @Override
5167    public final void activityResumed(IBinder token) {
5168        final long origId = Binder.clearCallingIdentity();
5169        synchronized(this) {
5170            ActivityStack stack = ActivityRecord.getStackLocked(token);
5171            if (stack != null) {
5172                ActivityRecord.activityResumedLocked(token);
5173            }
5174        }
5175        Binder.restoreCallingIdentity(origId);
5176    }
5177
5178    @Override
5179    public final void activityPaused(IBinder token) {
5180        final long origId = Binder.clearCallingIdentity();
5181        synchronized(this) {
5182            ActivityStack stack = ActivityRecord.getStackLocked(token);
5183            if (stack != null) {
5184                stack.activityPausedLocked(token, false);
5185            }
5186        }
5187        Binder.restoreCallingIdentity(origId);
5188    }
5189
5190    @Override
5191    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5192            CharSequence description) {
5193        if (localLOGV) Slog.v(
5194            TAG, "Activity stopped: token=" + token);
5195
5196        // Refuse possible leaked file descriptors
5197        if (icicle != null && icicle.hasFileDescriptors()) {
5198            throw new IllegalArgumentException("File descriptors passed in Bundle");
5199        }
5200
5201        ActivityRecord r = null;
5202
5203        final long origId = Binder.clearCallingIdentity();
5204
5205        synchronized (this) {
5206            r = ActivityRecord.isInStackLocked(token);
5207            if (r != null) {
5208                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5209            }
5210        }
5211
5212        if (r != null) {
5213            sendPendingThumbnail(r, null, null, null, false);
5214        }
5215
5216        trimApplications();
5217
5218        Binder.restoreCallingIdentity(origId);
5219    }
5220
5221    @Override
5222    public final void activityDestroyed(IBinder token) {
5223        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5224        synchronized (this) {
5225            ActivityStack stack = ActivityRecord.getStackLocked(token);
5226            if (stack != null) {
5227                stack.activityDestroyedLocked(token);
5228            }
5229        }
5230    }
5231
5232    @Override
5233    public String getCallingPackage(IBinder token) {
5234        synchronized (this) {
5235            ActivityRecord r = getCallingRecordLocked(token);
5236            return r != null ? r.info.packageName : null;
5237        }
5238    }
5239
5240    @Override
5241    public ComponentName getCallingActivity(IBinder token) {
5242        synchronized (this) {
5243            ActivityRecord r = getCallingRecordLocked(token);
5244            return r != null ? r.intent.getComponent() : null;
5245        }
5246    }
5247
5248    private ActivityRecord getCallingRecordLocked(IBinder token) {
5249        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5250        if (r == null) {
5251            return null;
5252        }
5253        return r.resultTo;
5254    }
5255
5256    @Override
5257    public ComponentName getActivityClassForToken(IBinder token) {
5258        synchronized(this) {
5259            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5260            if (r == null) {
5261                return null;
5262            }
5263            return r.intent.getComponent();
5264        }
5265    }
5266
5267    @Override
5268    public String getPackageForToken(IBinder token) {
5269        synchronized(this) {
5270            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5271            if (r == null) {
5272                return null;
5273            }
5274            return r.packageName;
5275        }
5276    }
5277
5278    @Override
5279    public IIntentSender getIntentSender(int type,
5280            String packageName, IBinder token, String resultWho,
5281            int requestCode, Intent[] intents, String[] resolvedTypes,
5282            int flags, Bundle options, int userId) {
5283        enforceNotIsolatedCaller("getIntentSender");
5284        // Refuse possible leaked file descriptors
5285        if (intents != null) {
5286            if (intents.length < 1) {
5287                throw new IllegalArgumentException("Intents array length must be >= 1");
5288            }
5289            for (int i=0; i<intents.length; i++) {
5290                Intent intent = intents[i];
5291                if (intent != null) {
5292                    if (intent.hasFileDescriptors()) {
5293                        throw new IllegalArgumentException("File descriptors passed in Intent");
5294                    }
5295                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5296                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5297                        throw new IllegalArgumentException(
5298                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5299                    }
5300                    intents[i] = new Intent(intent);
5301                }
5302            }
5303            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5304                throw new IllegalArgumentException(
5305                        "Intent array length does not match resolvedTypes length");
5306            }
5307        }
5308        if (options != null) {
5309            if (options.hasFileDescriptors()) {
5310                throw new IllegalArgumentException("File descriptors passed in options");
5311            }
5312        }
5313
5314        synchronized(this) {
5315            int callingUid = Binder.getCallingUid();
5316            int origUserId = userId;
5317            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5318                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5319                    "getIntentSender", null);
5320            if (origUserId == UserHandle.USER_CURRENT) {
5321                // We don't want to evaluate this until the pending intent is
5322                // actually executed.  However, we do want to always do the
5323                // security checking for it above.
5324                userId = UserHandle.USER_CURRENT;
5325            }
5326            try {
5327                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5328                    int uid = AppGlobals.getPackageManager()
5329                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5330                    if (!UserHandle.isSameApp(callingUid, uid)) {
5331                        String msg = "Permission Denial: getIntentSender() from pid="
5332                            + Binder.getCallingPid()
5333                            + ", uid=" + Binder.getCallingUid()
5334                            + ", (need uid=" + uid + ")"
5335                            + " is not allowed to send as package " + packageName;
5336                        Slog.w(TAG, msg);
5337                        throw new SecurityException(msg);
5338                    }
5339                }
5340
5341                return getIntentSenderLocked(type, packageName, callingUid, userId,
5342                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5343
5344            } catch (RemoteException e) {
5345                throw new SecurityException(e);
5346            }
5347        }
5348    }
5349
5350    IIntentSender getIntentSenderLocked(int type, String packageName,
5351            int callingUid, int userId, IBinder token, String resultWho,
5352            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5353            Bundle options) {
5354        if (DEBUG_MU)
5355            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5356        ActivityRecord activity = null;
5357        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5358            activity = ActivityRecord.isInStackLocked(token);
5359            if (activity == null) {
5360                return null;
5361            }
5362            if (activity.finishing) {
5363                return null;
5364            }
5365        }
5366
5367        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5368        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5369        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5370        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5371                |PendingIntent.FLAG_UPDATE_CURRENT);
5372
5373        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5374                type, packageName, activity, resultWho,
5375                requestCode, intents, resolvedTypes, flags, options, userId);
5376        WeakReference<PendingIntentRecord> ref;
5377        ref = mIntentSenderRecords.get(key);
5378        PendingIntentRecord rec = ref != null ? ref.get() : null;
5379        if (rec != null) {
5380            if (!cancelCurrent) {
5381                if (updateCurrent) {
5382                    if (rec.key.requestIntent != null) {
5383                        rec.key.requestIntent.replaceExtras(intents != null ?
5384                                intents[intents.length - 1] : null);
5385                    }
5386                    if (intents != null) {
5387                        intents[intents.length-1] = rec.key.requestIntent;
5388                        rec.key.allIntents = intents;
5389                        rec.key.allResolvedTypes = resolvedTypes;
5390                    } else {
5391                        rec.key.allIntents = null;
5392                        rec.key.allResolvedTypes = null;
5393                    }
5394                }
5395                return rec;
5396            }
5397            rec.canceled = true;
5398            mIntentSenderRecords.remove(key);
5399        }
5400        if (noCreate) {
5401            return rec;
5402        }
5403        rec = new PendingIntentRecord(this, key, callingUid);
5404        mIntentSenderRecords.put(key, rec.ref);
5405        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5406            if (activity.pendingResults == null) {
5407                activity.pendingResults
5408                        = new HashSet<WeakReference<PendingIntentRecord>>();
5409            }
5410            activity.pendingResults.add(rec.ref);
5411        }
5412        return rec;
5413    }
5414
5415    @Override
5416    public void cancelIntentSender(IIntentSender sender) {
5417        if (!(sender instanceof PendingIntentRecord)) {
5418            return;
5419        }
5420        synchronized(this) {
5421            PendingIntentRecord rec = (PendingIntentRecord)sender;
5422            try {
5423                int uid = AppGlobals.getPackageManager()
5424                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5425                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5426                    String msg = "Permission Denial: cancelIntentSender() from pid="
5427                        + Binder.getCallingPid()
5428                        + ", uid=" + Binder.getCallingUid()
5429                        + " is not allowed to cancel packges "
5430                        + rec.key.packageName;
5431                    Slog.w(TAG, msg);
5432                    throw new SecurityException(msg);
5433                }
5434            } catch (RemoteException e) {
5435                throw new SecurityException(e);
5436            }
5437            cancelIntentSenderLocked(rec, true);
5438        }
5439    }
5440
5441    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5442        rec.canceled = true;
5443        mIntentSenderRecords.remove(rec.key);
5444        if (cleanActivity && rec.key.activity != null) {
5445            rec.key.activity.pendingResults.remove(rec.ref);
5446        }
5447    }
5448
5449    @Override
5450    public String getPackageForIntentSender(IIntentSender pendingResult) {
5451        if (!(pendingResult instanceof PendingIntentRecord)) {
5452            return null;
5453        }
5454        try {
5455            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5456            return res.key.packageName;
5457        } catch (ClassCastException e) {
5458        }
5459        return null;
5460    }
5461
5462    @Override
5463    public int getUidForIntentSender(IIntentSender sender) {
5464        if (sender instanceof PendingIntentRecord) {
5465            try {
5466                PendingIntentRecord res = (PendingIntentRecord)sender;
5467                return res.uid;
5468            } catch (ClassCastException e) {
5469            }
5470        }
5471        return -1;
5472    }
5473
5474    @Override
5475    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5476        if (!(pendingResult instanceof PendingIntentRecord)) {
5477            return false;
5478        }
5479        try {
5480            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5481            if (res.key.allIntents == null) {
5482                return false;
5483            }
5484            for (int i=0; i<res.key.allIntents.length; i++) {
5485                Intent intent = res.key.allIntents[i];
5486                if (intent.getPackage() != null && intent.getComponent() != null) {
5487                    return false;
5488                }
5489            }
5490            return true;
5491        } catch (ClassCastException e) {
5492        }
5493        return false;
5494    }
5495
5496    @Override
5497    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5498        if (!(pendingResult instanceof PendingIntentRecord)) {
5499            return false;
5500        }
5501        try {
5502            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5503            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5504                return true;
5505            }
5506            return false;
5507        } catch (ClassCastException e) {
5508        }
5509        return false;
5510    }
5511
5512    @Override
5513    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5514        if (!(pendingResult instanceof PendingIntentRecord)) {
5515            return null;
5516        }
5517        try {
5518            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5519            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5520        } catch (ClassCastException e) {
5521        }
5522        return null;
5523    }
5524
5525    @Override
5526    public void setProcessLimit(int max) {
5527        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5528                "setProcessLimit()");
5529        synchronized (this) {
5530            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5531            mProcessLimitOverride = max;
5532        }
5533        trimApplications();
5534    }
5535
5536    @Override
5537    public int getProcessLimit() {
5538        synchronized (this) {
5539            return mProcessLimitOverride;
5540        }
5541    }
5542
5543    void foregroundTokenDied(ForegroundToken token) {
5544        synchronized (ActivityManagerService.this) {
5545            synchronized (mPidsSelfLocked) {
5546                ForegroundToken cur
5547                    = mForegroundProcesses.get(token.pid);
5548                if (cur != token) {
5549                    return;
5550                }
5551                mForegroundProcesses.remove(token.pid);
5552                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5553                if (pr == null) {
5554                    return;
5555                }
5556                pr.forcingToForeground = null;
5557                pr.foregroundServices = false;
5558            }
5559            updateOomAdjLocked();
5560        }
5561    }
5562
5563    @Override
5564    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5565        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5566                "setProcessForeground()");
5567        synchronized(this) {
5568            boolean changed = false;
5569
5570            synchronized (mPidsSelfLocked) {
5571                ProcessRecord pr = mPidsSelfLocked.get(pid);
5572                if (pr == null && isForeground) {
5573                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5574                    return;
5575                }
5576                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5577                if (oldToken != null) {
5578                    oldToken.token.unlinkToDeath(oldToken, 0);
5579                    mForegroundProcesses.remove(pid);
5580                    if (pr != null) {
5581                        pr.forcingToForeground = null;
5582                    }
5583                    changed = true;
5584                }
5585                if (isForeground && token != null) {
5586                    ForegroundToken newToken = new ForegroundToken() {
5587                        @Override
5588                        public void binderDied() {
5589                            foregroundTokenDied(this);
5590                        }
5591                    };
5592                    newToken.pid = pid;
5593                    newToken.token = token;
5594                    try {
5595                        token.linkToDeath(newToken, 0);
5596                        mForegroundProcesses.put(pid, newToken);
5597                        pr.forcingToForeground = token;
5598                        changed = true;
5599                    } catch (RemoteException e) {
5600                        // If the process died while doing this, we will later
5601                        // do the cleanup with the process death link.
5602                    }
5603                }
5604            }
5605
5606            if (changed) {
5607                updateOomAdjLocked();
5608            }
5609        }
5610    }
5611
5612    // =========================================================
5613    // PERMISSIONS
5614    // =========================================================
5615
5616    static class PermissionController extends IPermissionController.Stub {
5617        ActivityManagerService mActivityManagerService;
5618        PermissionController(ActivityManagerService activityManagerService) {
5619            mActivityManagerService = activityManagerService;
5620        }
5621
5622        @Override
5623        public boolean checkPermission(String permission, int pid, int uid) {
5624            return mActivityManagerService.checkPermission(permission, pid,
5625                    uid) == PackageManager.PERMISSION_GRANTED;
5626        }
5627    }
5628
5629    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5630        @Override
5631        public int checkComponentPermission(String permission, int pid, int uid,
5632                int owningUid, boolean exported) {
5633            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5634                    owningUid, exported);
5635        }
5636
5637        @Override
5638        public Object getAMSLock() {
5639            return ActivityManagerService.this;
5640        }
5641    }
5642
5643    /**
5644     * This can be called with or without the global lock held.
5645     */
5646    int checkComponentPermission(String permission, int pid, int uid,
5647            int owningUid, boolean exported) {
5648        // We might be performing an operation on behalf of an indirect binder
5649        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5650        // client identity accordingly before proceeding.
5651        Identity tlsIdentity = sCallerIdentity.get();
5652        if (tlsIdentity != null) {
5653            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5654                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5655            uid = tlsIdentity.uid;
5656            pid = tlsIdentity.pid;
5657        }
5658
5659        if (pid == MY_PID) {
5660            return PackageManager.PERMISSION_GRANTED;
5661        }
5662
5663        return ActivityManager.checkComponentPermission(permission, uid,
5664                owningUid, exported);
5665    }
5666
5667    /**
5668     * As the only public entry point for permissions checking, this method
5669     * can enforce the semantic that requesting a check on a null global
5670     * permission is automatically denied.  (Internally a null permission
5671     * string is used when calling {@link #checkComponentPermission} in cases
5672     * when only uid-based security is needed.)
5673     *
5674     * This can be called with or without the global lock held.
5675     */
5676    @Override
5677    public int checkPermission(String permission, int pid, int uid) {
5678        if (permission == null) {
5679            return PackageManager.PERMISSION_DENIED;
5680        }
5681        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5682    }
5683
5684    /**
5685     * Binder IPC calls go through the public entry point.
5686     * This can be called with or without the global lock held.
5687     */
5688    int checkCallingPermission(String permission) {
5689        return checkPermission(permission,
5690                Binder.getCallingPid(),
5691                UserHandle.getAppId(Binder.getCallingUid()));
5692    }
5693
5694    /**
5695     * This can be called with or without the global lock held.
5696     */
5697    void enforceCallingPermission(String permission, String func) {
5698        if (checkCallingPermission(permission)
5699                == PackageManager.PERMISSION_GRANTED) {
5700            return;
5701        }
5702
5703        String msg = "Permission Denial: " + func + " from pid="
5704                + Binder.getCallingPid()
5705                + ", uid=" + Binder.getCallingUid()
5706                + " requires " + permission;
5707        Slog.w(TAG, msg);
5708        throw new SecurityException(msg);
5709    }
5710
5711    /**
5712     * Determine if UID is holding permissions required to access {@link Uri} in
5713     * the given {@link ProviderInfo}. Final permission checking is always done
5714     * in {@link ContentProvider}.
5715     */
5716    private final boolean checkHoldingPermissionsLocked(
5717            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5718        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5719                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5720
5721        if (pi.applicationInfo.uid == uid) {
5722            return true;
5723        } else if (!pi.exported) {
5724            return false;
5725        }
5726
5727        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5728        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5729        try {
5730            // check if target holds top-level <provider> permissions
5731            if (!readMet && pi.readPermission != null
5732                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5733                readMet = true;
5734            }
5735            if (!writeMet && pi.writePermission != null
5736                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5737                writeMet = true;
5738            }
5739
5740            // track if unprotected read/write is allowed; any denied
5741            // <path-permission> below removes this ability
5742            boolean allowDefaultRead = pi.readPermission == null;
5743            boolean allowDefaultWrite = pi.writePermission == null;
5744
5745            // check if target holds any <path-permission> that match uri
5746            final PathPermission[] pps = pi.pathPermissions;
5747            if (pps != null) {
5748                final String path = uri.getPath();
5749                int i = pps.length;
5750                while (i > 0 && (!readMet || !writeMet)) {
5751                    i--;
5752                    PathPermission pp = pps[i];
5753                    if (pp.match(path)) {
5754                        if (!readMet) {
5755                            final String pprperm = pp.getReadPermission();
5756                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5757                                    + pprperm + " for " + pp.getPath()
5758                                    + ": match=" + pp.match(path)
5759                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5760                            if (pprperm != null) {
5761                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5762                                    readMet = true;
5763                                } else {
5764                                    allowDefaultRead = false;
5765                                }
5766                            }
5767                        }
5768                        if (!writeMet) {
5769                            final String ppwperm = pp.getWritePermission();
5770                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5771                                    + ppwperm + " for " + pp.getPath()
5772                                    + ": match=" + pp.match(path)
5773                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5774                            if (ppwperm != null) {
5775                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5776                                    writeMet = true;
5777                                } else {
5778                                    allowDefaultWrite = false;
5779                                }
5780                            }
5781                        }
5782                    }
5783                }
5784            }
5785
5786            // grant unprotected <provider> read/write, if not blocked by
5787            // <path-permission> above
5788            if (allowDefaultRead) readMet = true;
5789            if (allowDefaultWrite) writeMet = true;
5790
5791        } catch (RemoteException e) {
5792            return false;
5793        }
5794
5795        return readMet && writeMet;
5796    }
5797
5798    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5799        ProviderInfo pi = null;
5800        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5801        if (cpr != null) {
5802            pi = cpr.info;
5803        } else {
5804            try {
5805                pi = AppGlobals.getPackageManager().resolveContentProvider(
5806                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5807            } catch (RemoteException ex) {
5808            }
5809        }
5810        return pi;
5811    }
5812
5813    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5814        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5815        if (targetUris != null) {
5816            return targetUris.get(uri);
5817        } else {
5818            return null;
5819        }
5820    }
5821
5822    private UriPermission findOrCreateUriPermissionLocked(
5823            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5824        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5825        if (targetUris == null) {
5826            targetUris = Maps.newArrayMap();
5827            mGrantedUriPermissions.put(targetUid, targetUris);
5828        }
5829
5830        UriPermission perm = targetUris.get(uri);
5831        if (perm == null) {
5832            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5833            targetUris.put(uri, perm);
5834        }
5835
5836        return perm;
5837    }
5838
5839    private final boolean checkUriPermissionLocked(
5840            Uri uri, int uid, int modeFlags, int minStrength) {
5841        // Root gets to do everything.
5842        if (uid == 0) {
5843            return true;
5844        }
5845        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5846        if (perms == null) return false;
5847        UriPermission perm = perms.get(uri);
5848        if (perm == null) return false;
5849        return perm.getStrength(modeFlags) >= minStrength;
5850    }
5851
5852    @Override
5853    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5854        enforceNotIsolatedCaller("checkUriPermission");
5855
5856        // Another redirected-binder-call permissions check as in
5857        // {@link checkComponentPermission}.
5858        Identity tlsIdentity = sCallerIdentity.get();
5859        if (tlsIdentity != null) {
5860            uid = tlsIdentity.uid;
5861            pid = tlsIdentity.pid;
5862        }
5863
5864        // Our own process gets to do everything.
5865        if (pid == MY_PID) {
5866            return PackageManager.PERMISSION_GRANTED;
5867        }
5868        synchronized(this) {
5869            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5870                    ? PackageManager.PERMISSION_GRANTED
5871                    : PackageManager.PERMISSION_DENIED;
5872        }
5873    }
5874
5875    /**
5876     * Check if the targetPkg can be granted permission to access uri by
5877     * the callingUid using the given modeFlags.  Throws a security exception
5878     * if callingUid is not allowed to do this.  Returns the uid of the target
5879     * if the URI permission grant should be performed; returns -1 if it is not
5880     * needed (for example targetPkg already has permission to access the URI).
5881     * If you already know the uid of the target, you can supply it in
5882     * lastTargetUid else set that to -1.
5883     */
5884    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5885            Uri uri, int modeFlags, int lastTargetUid) {
5886        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5887        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5888                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5889        if (modeFlags == 0) {
5890            return -1;
5891        }
5892
5893        if (targetPkg != null) {
5894            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5895                    "Checking grant " + targetPkg + " permission to " + uri);
5896        }
5897
5898        final IPackageManager pm = AppGlobals.getPackageManager();
5899
5900        // If this is not a content: uri, we can't do anything with it.
5901        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5902            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5903                    "Can't grant URI permission for non-content URI: " + uri);
5904            return -1;
5905        }
5906
5907        final String authority = uri.getAuthority();
5908        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5909        if (pi == null) {
5910            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5911            return -1;
5912        }
5913
5914        int targetUid = lastTargetUid;
5915        if (targetUid < 0 && targetPkg != null) {
5916            try {
5917                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5918                if (targetUid < 0) {
5919                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5920                            "Can't grant URI permission no uid for: " + targetPkg);
5921                    return -1;
5922                }
5923            } catch (RemoteException ex) {
5924                return -1;
5925            }
5926        }
5927
5928        if (targetUid >= 0) {
5929            // First...  does the target actually need this permission?
5930            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5931                // No need to grant the target this permission.
5932                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5933                        "Target " + targetPkg + " already has full permission to " + uri);
5934                return -1;
5935            }
5936        } else {
5937            // First...  there is no target package, so can anyone access it?
5938            boolean allowed = pi.exported;
5939            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5940                if (pi.readPermission != null) {
5941                    allowed = false;
5942                }
5943            }
5944            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5945                if (pi.writePermission != null) {
5946                    allowed = false;
5947                }
5948            }
5949            if (allowed) {
5950                return -1;
5951            }
5952        }
5953
5954        // Second...  is the provider allowing granting of URI permissions?
5955        if (!pi.grantUriPermissions) {
5956            throw new SecurityException("Provider " + pi.packageName
5957                    + "/" + pi.name
5958                    + " does not allow granting of Uri permissions (uri "
5959                    + uri + ")");
5960        }
5961        if (pi.uriPermissionPatterns != null) {
5962            final int N = pi.uriPermissionPatterns.length;
5963            boolean allowed = false;
5964            for (int i=0; i<N; i++) {
5965                if (pi.uriPermissionPatterns[i] != null
5966                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5967                    allowed = true;
5968                    break;
5969                }
5970            }
5971            if (!allowed) {
5972                throw new SecurityException("Provider " + pi.packageName
5973                        + "/" + pi.name
5974                        + " does not allow granting of permission to path of Uri "
5975                        + uri);
5976            }
5977        }
5978
5979        // Third...  does the caller itself have permission to access
5980        // this uri?
5981        if (callingUid != Process.myUid()) {
5982            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5983                // Require they hold a strong enough Uri permission
5984                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
5985                        : UriPermission.STRENGTH_OWNED;
5986                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
5987                    throw new SecurityException("Uid " + callingUid
5988                            + " does not have permission to uri " + uri);
5989                }
5990            }
5991        }
5992
5993        return targetUid;
5994    }
5995
5996    @Override
5997    public int checkGrantUriPermission(int callingUid, String targetPkg,
5998            Uri uri, int modeFlags) {
5999        enforceNotIsolatedCaller("checkGrantUriPermission");
6000        synchronized(this) {
6001            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6002        }
6003    }
6004
6005    void grantUriPermissionUncheckedLocked(
6006            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6007        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6008        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6009                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6010        if (modeFlags == 0) {
6011            return;
6012        }
6013
6014        // So here we are: the caller has the assumed permission
6015        // to the uri, and the target doesn't.  Let's now give this to
6016        // the target.
6017
6018        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6019                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6020
6021        final String authority = uri.getAuthority();
6022        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6023        if (pi == null) {
6024            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6025            return;
6026        }
6027
6028        final UriPermission perm = findOrCreateUriPermissionLocked(
6029                pi.packageName, targetPkg, targetUid, uri);
6030        perm.grantModes(modeFlags, persistable, owner);
6031    }
6032
6033    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6034            int modeFlags, UriPermissionOwner owner) {
6035        if (targetPkg == null) {
6036            throw new NullPointerException("targetPkg");
6037        }
6038
6039        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6040        if (targetUid < 0) {
6041            return;
6042        }
6043
6044        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6045    }
6046
6047    static class NeededUriGrants extends ArrayList<Uri> {
6048        final String targetPkg;
6049        final int targetUid;
6050        final int flags;
6051
6052        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6053            this.targetPkg = targetPkg;
6054            this.targetUid = targetUid;
6055            this.flags = flags;
6056        }
6057    }
6058
6059    /**
6060     * Like checkGrantUriPermissionLocked, but takes an Intent.
6061     */
6062    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6063            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6064        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6065                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6066                + " clip=" + (intent != null ? intent.getClipData() : null)
6067                + " from " + intent + "; flags=0x"
6068                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6069
6070        if (targetPkg == null) {
6071            throw new NullPointerException("targetPkg");
6072        }
6073
6074        if (intent == null) {
6075            return null;
6076        }
6077        Uri data = intent.getData();
6078        ClipData clip = intent.getClipData();
6079        if (data == null && clip == null) {
6080            return null;
6081        }
6082
6083        if (data != null) {
6084            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6085                mode, needed != null ? needed.targetUid : -1);
6086            if (targetUid > 0) {
6087                if (needed == null) {
6088                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6089                }
6090                needed.add(data);
6091            }
6092        }
6093        if (clip != null) {
6094            for (int i=0; i<clip.getItemCount(); i++) {
6095                Uri uri = clip.getItemAt(i).getUri();
6096                if (uri != null) {
6097                    int targetUid = -1;
6098                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6099                            mode, needed != null ? needed.targetUid : -1);
6100                    if (targetUid > 0) {
6101                        if (needed == null) {
6102                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6103                        }
6104                        needed.add(uri);
6105                    }
6106                } else {
6107                    Intent clipIntent = clip.getItemAt(i).getIntent();
6108                    if (clipIntent != null) {
6109                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6110                                callingUid, targetPkg, clipIntent, mode, needed);
6111                        if (newNeeded != null) {
6112                            needed = newNeeded;
6113                        }
6114                    }
6115                }
6116            }
6117        }
6118
6119        return needed;
6120    }
6121
6122    /**
6123     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6124     */
6125    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6126            UriPermissionOwner owner) {
6127        if (needed != null) {
6128            for (int i=0; i<needed.size(); i++) {
6129                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6130                        needed.get(i), needed.flags, owner);
6131            }
6132        }
6133    }
6134
6135    void grantUriPermissionFromIntentLocked(int callingUid,
6136            String targetPkg, Intent intent, UriPermissionOwner owner) {
6137        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6138                intent, intent != null ? intent.getFlags() : 0, null);
6139        if (needed == null) {
6140            return;
6141        }
6142
6143        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6144    }
6145
6146    @Override
6147    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6148            Uri uri, int modeFlags) {
6149        enforceNotIsolatedCaller("grantUriPermission");
6150        synchronized(this) {
6151            final ProcessRecord r = getRecordForAppLocked(caller);
6152            if (r == null) {
6153                throw new SecurityException("Unable to find app for caller "
6154                        + caller
6155                        + " when granting permission to uri " + uri);
6156            }
6157            if (targetPkg == null) {
6158                throw new IllegalArgumentException("null target");
6159            }
6160            if (uri == null) {
6161                throw new IllegalArgumentException("null uri");
6162            }
6163
6164            // Persistable only supported through Intents
6165            Preconditions.checkFlagsArgument(modeFlags,
6166                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6167
6168            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6169                    null);
6170        }
6171    }
6172
6173    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6174        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6175                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6176            ArrayMap<Uri, UriPermission> perms
6177                    = mGrantedUriPermissions.get(perm.targetUid);
6178            if (perms != null) {
6179                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6180                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6181                perms.remove(perm.uri);
6182                if (perms.size() == 0) {
6183                    mGrantedUriPermissions.remove(perm.targetUid);
6184                }
6185            }
6186        }
6187    }
6188
6189    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6190        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6191
6192        final IPackageManager pm = AppGlobals.getPackageManager();
6193        final String authority = uri.getAuthority();
6194        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6195        if (pi == null) {
6196            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6197            return;
6198        }
6199
6200        // Does the caller have this permission on the URI?
6201        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6202            // Right now, if you are not the original owner of the permission,
6203            // you are not allowed to revoke it.
6204            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6205                throw new SecurityException("Uid " + callingUid
6206                        + " does not have permission to uri " + uri);
6207            //}
6208        }
6209
6210        boolean persistChanged = false;
6211
6212        // Go through all of the permissions and remove any that match.
6213        final List<String> SEGMENTS = uri.getPathSegments();
6214        if (SEGMENTS != null) {
6215            final int NS = SEGMENTS.size();
6216            int N = mGrantedUriPermissions.size();
6217            for (int i=0; i<N; i++) {
6218                ArrayMap<Uri, UriPermission> perms
6219                        = mGrantedUriPermissions.valueAt(i);
6220                Iterator<UriPermission> it = perms.values().iterator();
6221            toploop:
6222                while (it.hasNext()) {
6223                    UriPermission perm = it.next();
6224                    Uri targetUri = perm.uri;
6225                    if (!authority.equals(targetUri.getAuthority())) {
6226                        continue;
6227                    }
6228                    List<String> targetSegments = targetUri.getPathSegments();
6229                    if (targetSegments == null) {
6230                        continue;
6231                    }
6232                    if (targetSegments.size() < NS) {
6233                        continue;
6234                    }
6235                    for (int j=0; j<NS; j++) {
6236                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6237                            continue toploop;
6238                        }
6239                    }
6240                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6241                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6242                    persistChanged |= perm.clearModes(modeFlags, true);
6243                    if (perm.modeFlags == 0) {
6244                        it.remove();
6245                    }
6246                }
6247                if (perms.size() == 0) {
6248                    mGrantedUriPermissions.remove(
6249                            mGrantedUriPermissions.keyAt(i));
6250                    N--;
6251                    i--;
6252                }
6253            }
6254        }
6255
6256        if (persistChanged) {
6257            schedulePersistUriGrants();
6258        }
6259    }
6260
6261    @Override
6262    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6263            int modeFlags) {
6264        enforceNotIsolatedCaller("revokeUriPermission");
6265        synchronized(this) {
6266            final ProcessRecord r = getRecordForAppLocked(caller);
6267            if (r == null) {
6268                throw new SecurityException("Unable to find app for caller "
6269                        + caller
6270                        + " when revoking permission to uri " + uri);
6271            }
6272            if (uri == null) {
6273                Slog.w(TAG, "revokeUriPermission: null uri");
6274                return;
6275            }
6276
6277            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6278                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6279            if (modeFlags == 0) {
6280                return;
6281            }
6282
6283            final IPackageManager pm = AppGlobals.getPackageManager();
6284            final String authority = uri.getAuthority();
6285            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6286            if (pi == null) {
6287                Slog.w(TAG, "No content provider found for permission revoke: "
6288                        + uri.toSafeString());
6289                return;
6290            }
6291
6292            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6293        }
6294    }
6295
6296    /**
6297     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6298     * given package.
6299     *
6300     * @param packageName Package name to match, or {@code null} to apply to all
6301     *            packages.
6302     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6303     *            to all users.
6304     * @param persistable If persistable grants should be removed.
6305     */
6306    private void removeUriPermissionsForPackageLocked(
6307            String packageName, int userHandle, boolean persistable) {
6308        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6309            throw new IllegalArgumentException("Must narrow by either package or user");
6310        }
6311
6312        boolean persistChanged = false;
6313
6314        final int size = mGrantedUriPermissions.size();
6315        for (int i = 0; i < size; i++) {
6316            // Only inspect grants matching user
6317            if (userHandle == UserHandle.USER_ALL
6318                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6319                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6320                        .values().iterator();
6321                while (it.hasNext()) {
6322                    final UriPermission perm = it.next();
6323
6324                    // Only inspect grants matching package
6325                    if (packageName == null || perm.sourcePkg.equals(packageName)
6326                            || perm.targetPkg.equals(packageName)) {
6327                        persistChanged |= perm.clearModes(~0, persistable);
6328
6329                        // Only remove when no modes remain; any persisted grants
6330                        // will keep this alive.
6331                        if (perm.modeFlags == 0) {
6332                            it.remove();
6333                        }
6334                    }
6335                }
6336            }
6337        }
6338
6339        if (persistChanged) {
6340            schedulePersistUriGrants();
6341        }
6342    }
6343
6344    @Override
6345    public IBinder newUriPermissionOwner(String name) {
6346        enforceNotIsolatedCaller("newUriPermissionOwner");
6347        synchronized(this) {
6348            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6349            return owner.getExternalTokenLocked();
6350        }
6351    }
6352
6353    @Override
6354    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6355            Uri uri, int modeFlags) {
6356        synchronized(this) {
6357            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6358            if (owner == null) {
6359                throw new IllegalArgumentException("Unknown owner: " + token);
6360            }
6361            if (fromUid != Binder.getCallingUid()) {
6362                if (Binder.getCallingUid() != Process.myUid()) {
6363                    // Only system code can grant URI permissions on behalf
6364                    // of other users.
6365                    throw new SecurityException("nice try");
6366                }
6367            }
6368            if (targetPkg == null) {
6369                throw new IllegalArgumentException("null target");
6370            }
6371            if (uri == null) {
6372                throw new IllegalArgumentException("null uri");
6373            }
6374
6375            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6376        }
6377    }
6378
6379    @Override
6380    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6381        synchronized(this) {
6382            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6383            if (owner == null) {
6384                throw new IllegalArgumentException("Unknown owner: " + token);
6385            }
6386
6387            if (uri == null) {
6388                owner.removeUriPermissionsLocked(mode);
6389            } else {
6390                owner.removeUriPermissionLocked(uri, mode);
6391            }
6392        }
6393    }
6394
6395    private void schedulePersistUriGrants() {
6396        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6397            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6398                    10 * DateUtils.SECOND_IN_MILLIS);
6399        }
6400    }
6401
6402    private void writeGrantedUriPermissions() {
6403        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6404
6405        // Snapshot permissions so we can persist without lock
6406        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6407        synchronized (this) {
6408            final int size = mGrantedUriPermissions.size();
6409            for (int i = 0 ; i < size; i++) {
6410                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6411                    if (perm.persistedModeFlags != 0) {
6412                        persist.add(perm.snapshot());
6413                    }
6414                }
6415            }
6416        }
6417
6418        FileOutputStream fos = null;
6419        try {
6420            fos = mGrantFile.startWrite();
6421
6422            XmlSerializer out = new FastXmlSerializer();
6423            out.setOutput(fos, "utf-8");
6424            out.startDocument(null, true);
6425            out.startTag(null, TAG_URI_GRANTS);
6426            for (UriPermission.Snapshot perm : persist) {
6427                out.startTag(null, TAG_URI_GRANT);
6428                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6429                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6430                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6431                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6432                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6433                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6434                out.endTag(null, TAG_URI_GRANT);
6435            }
6436            out.endTag(null, TAG_URI_GRANTS);
6437            out.endDocument();
6438
6439            mGrantFile.finishWrite(fos);
6440        } catch (IOException e) {
6441            if (fos != null) {
6442                mGrantFile.failWrite(fos);
6443            }
6444        }
6445    }
6446
6447    private void readGrantedUriPermissionsLocked() {
6448        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6449
6450        final long now = System.currentTimeMillis();
6451
6452        FileInputStream fis = null;
6453        try {
6454            fis = mGrantFile.openRead();
6455            final XmlPullParser in = Xml.newPullParser();
6456            in.setInput(fis, null);
6457
6458            int type;
6459            while ((type = in.next()) != END_DOCUMENT) {
6460                final String tag = in.getName();
6461                if (type == START_TAG) {
6462                    if (TAG_URI_GRANT.equals(tag)) {
6463                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6464                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6465                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6466                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6467                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6468                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6469
6470                        // Sanity check that provider still belongs to source package
6471                        final ProviderInfo pi = getProviderInfoLocked(
6472                                uri.getAuthority(), userHandle);
6473                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6474                            int targetUid = -1;
6475                            try {
6476                                targetUid = AppGlobals.getPackageManager()
6477                                        .getPackageUid(targetPkg, userHandle);
6478                            } catch (RemoteException e) {
6479                            }
6480                            if (targetUid != -1) {
6481                                final UriPermission perm = findOrCreateUriPermissionLocked(
6482                                        sourcePkg, targetPkg, targetUid, uri);
6483                                perm.initPersistedModes(modeFlags, createdTime);
6484                            }
6485                        } else {
6486                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6487                                    + " but instead found " + pi);
6488                        }
6489                    }
6490                }
6491            }
6492        } catch (FileNotFoundException e) {
6493            // Missing grants is okay
6494        } catch (IOException e) {
6495            Log.wtf(TAG, "Failed reading Uri grants", e);
6496        } catch (XmlPullParserException e) {
6497            Log.wtf(TAG, "Failed reading Uri grants", e);
6498        } finally {
6499            IoUtils.closeQuietly(fis);
6500        }
6501    }
6502
6503    @Override
6504    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6505        enforceNotIsolatedCaller("takePersistableUriPermission");
6506
6507        Preconditions.checkFlagsArgument(modeFlags,
6508                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6509
6510        synchronized (this) {
6511            final int callingUid = Binder.getCallingUid();
6512            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6513            if (perm == null) {
6514                throw new SecurityException("No permission grant found for UID " + callingUid
6515                        + " and Uri " + uri.toSafeString());
6516            }
6517
6518            boolean persistChanged = perm.takePersistableModes(modeFlags);
6519            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6520
6521            if (persistChanged) {
6522                schedulePersistUriGrants();
6523            }
6524        }
6525    }
6526
6527    @Override
6528    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6529        enforceNotIsolatedCaller("releasePersistableUriPermission");
6530
6531        Preconditions.checkFlagsArgument(modeFlags,
6532                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6533
6534        synchronized (this) {
6535            final int callingUid = Binder.getCallingUid();
6536
6537            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6538            if (perm == null) {
6539                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6540                        + uri.toSafeString());
6541                return;
6542            }
6543
6544            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6545            removeUriPermissionIfNeededLocked(perm);
6546            if (persistChanged) {
6547                schedulePersistUriGrants();
6548            }
6549        }
6550    }
6551
6552    /**
6553     * Prune any older {@link UriPermission} for the given UID until outstanding
6554     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6555     *
6556     * @return if any mutations occured that require persisting.
6557     */
6558    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6559        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6560        if (perms == null) return false;
6561        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6562
6563        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6564        for (UriPermission perm : perms.values()) {
6565            if (perm.persistedModeFlags != 0) {
6566                persisted.add(perm);
6567            }
6568        }
6569
6570        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6571        if (trimCount <= 0) return false;
6572
6573        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6574        for (int i = 0; i < trimCount; i++) {
6575            final UriPermission perm = persisted.get(i);
6576
6577            if (DEBUG_URI_PERMISSION) {
6578                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6579            }
6580
6581            perm.releasePersistableModes(~0);
6582            removeUriPermissionIfNeededLocked(perm);
6583        }
6584
6585        return true;
6586    }
6587
6588    @Override
6589    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6590            String packageName, boolean incoming) {
6591        enforceNotIsolatedCaller("getPersistedUriPermissions");
6592        Preconditions.checkNotNull(packageName, "packageName");
6593
6594        final int callingUid = Binder.getCallingUid();
6595        final IPackageManager pm = AppGlobals.getPackageManager();
6596        try {
6597            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6598            if (packageUid != callingUid) {
6599                throw new SecurityException(
6600                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6601            }
6602        } catch (RemoteException e) {
6603            throw new SecurityException("Failed to verify package name ownership");
6604        }
6605
6606        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6607        synchronized (this) {
6608            if (incoming) {
6609                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6610                if (perms == null) {
6611                    Slog.w(TAG, "No permission grants found for " + packageName);
6612                } else {
6613                    final int size = perms.size();
6614                    for (int i = 0; i < size; i++) {
6615                        final UriPermission perm = perms.valueAt(i);
6616                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6617                            result.add(perm.buildPersistedPublicApiObject());
6618                        }
6619                    }
6620                }
6621            } else {
6622                final int size = mGrantedUriPermissions.size();
6623                for (int i = 0; i < size; i++) {
6624                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6625                    final int permsSize = perms.size();
6626                    for (int j = 0; j < permsSize; j++) {
6627                        final UriPermission perm = perms.valueAt(j);
6628                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6629                            result.add(perm.buildPersistedPublicApiObject());
6630                        }
6631                    }
6632                }
6633            }
6634        }
6635        return new ParceledListSlice<android.content.UriPermission>(result);
6636    }
6637
6638    @Override
6639    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6640        synchronized (this) {
6641            ProcessRecord app =
6642                who != null ? getRecordForAppLocked(who) : null;
6643            if (app == null) return;
6644
6645            Message msg = Message.obtain();
6646            msg.what = WAIT_FOR_DEBUGGER_MSG;
6647            msg.obj = app;
6648            msg.arg1 = waiting ? 1 : 0;
6649            mHandler.sendMessage(msg);
6650        }
6651    }
6652
6653    @Override
6654    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6655        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6656        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6657        outInfo.availMem = Process.getFreeMemory();
6658        outInfo.totalMem = Process.getTotalMemory();
6659        outInfo.threshold = homeAppMem;
6660        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6661        outInfo.hiddenAppThreshold = cachedAppMem;
6662        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6663                ProcessList.SERVICE_ADJ);
6664        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6665                ProcessList.VISIBLE_APP_ADJ);
6666        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6667                ProcessList.FOREGROUND_APP_ADJ);
6668    }
6669
6670    // =========================================================
6671    // TASK MANAGEMENT
6672    // =========================================================
6673
6674    @Override
6675    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6676                         IThumbnailReceiver receiver) {
6677        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6678
6679        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6680        ActivityRecord topRecord = null;
6681
6682        synchronized(this) {
6683            if (localLOGV) Slog.v(
6684                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6685                + ", receiver=" + receiver);
6686
6687            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6688                    != PackageManager.PERMISSION_GRANTED) {
6689                if (receiver != null) {
6690                    // If the caller wants to wait for pending thumbnails,
6691                    // it ain't gonna get them.
6692                    try {
6693                        receiver.finished();
6694                    } catch (RemoteException ex) {
6695                    }
6696                }
6697                String msg = "Permission Denial: getTasks() from pid="
6698                        + Binder.getCallingPid()
6699                        + ", uid=" + Binder.getCallingUid()
6700                        + " requires " + android.Manifest.permission.GET_TASKS;
6701                Slog.w(TAG, msg);
6702                throw new SecurityException(msg);
6703            }
6704
6705            // TODO: Improve with MRU list from all ActivityStacks.
6706            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6707
6708            if (!pending.pendingRecords.isEmpty()) {
6709                mPendingThumbnails.add(pending);
6710            }
6711        }
6712
6713        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6714
6715        if (topRecord != null) {
6716            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6717            try {
6718                IApplicationThread topThumbnail = topRecord.app.thread;
6719                topThumbnail.requestThumbnail(topRecord.appToken);
6720            } catch (Exception e) {
6721                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6722                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6723            }
6724        }
6725
6726        if (pending == null && receiver != null) {
6727            // In this case all thumbnails were available and the client
6728            // is being asked to be told when the remaining ones come in...
6729            // which is unusually, since the top-most currently running
6730            // activity should never have a canned thumbnail!  Oh well.
6731            try {
6732                receiver.finished();
6733            } catch (RemoteException ex) {
6734            }
6735        }
6736
6737        return list;
6738    }
6739
6740    TaskRecord getMostRecentTask() {
6741        return mRecentTasks.get(0);
6742    }
6743
6744    @Override
6745    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6746            int flags, int userId) {
6747        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6748                false, true, "getRecentTasks", null);
6749
6750        synchronized (this) {
6751            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6752                    "getRecentTasks()");
6753            final boolean detailed = checkCallingPermission(
6754                    android.Manifest.permission.GET_DETAILED_TASKS)
6755                    == PackageManager.PERMISSION_GRANTED;
6756
6757            IPackageManager pm = AppGlobals.getPackageManager();
6758
6759            final int N = mRecentTasks.size();
6760            ArrayList<ActivityManager.RecentTaskInfo> res
6761                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6762                            maxNum < N ? maxNum : N);
6763            for (int i=0; i<N && maxNum > 0; i++) {
6764                TaskRecord tr = mRecentTasks.get(i);
6765                // Only add calling user's recent tasks
6766                if (tr.userId != userId) continue;
6767                // Return the entry if desired by the caller.  We always return
6768                // the first entry, because callers always expect this to be the
6769                // foreground app.  We may filter others if the caller has
6770                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6771                // we should exclude the entry.
6772
6773                if (i == 0
6774                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6775                        || (tr.intent == null)
6776                        || ((tr.intent.getFlags()
6777                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6778                    ActivityManager.RecentTaskInfo rti
6779                            = new ActivityManager.RecentTaskInfo();
6780                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6781                    rti.persistentId = tr.taskId;
6782                    rti.baseIntent = new Intent(
6783                            tr.intent != null ? tr.intent : tr.affinityIntent);
6784                    if (!detailed) {
6785                        rti.baseIntent.replaceExtras((Bundle)null);
6786                    }
6787                    rti.origActivity = tr.origActivity;
6788                    rti.description = tr.lastDescription;
6789                    rti.stackId = tr.stack.mStackId;
6790
6791                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6792                        // Check whether this activity is currently available.
6793                        try {
6794                            if (rti.origActivity != null) {
6795                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6796                                        == null) {
6797                                    continue;
6798                                }
6799                            } else if (rti.baseIntent != null) {
6800                                if (pm.queryIntentActivities(rti.baseIntent,
6801                                        null, 0, userId) == null) {
6802                                    continue;
6803                                }
6804                            }
6805                        } catch (RemoteException e) {
6806                            // Will never happen.
6807                        }
6808                    }
6809
6810                    res.add(rti);
6811                    maxNum--;
6812                }
6813            }
6814            return res;
6815        }
6816    }
6817
6818    private TaskRecord recentTaskForIdLocked(int id) {
6819        final int N = mRecentTasks.size();
6820            for (int i=0; i<N; i++) {
6821                TaskRecord tr = mRecentTasks.get(i);
6822                if (tr.taskId == id) {
6823                    return tr;
6824                }
6825            }
6826            return null;
6827    }
6828
6829    @Override
6830    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6831        synchronized (this) {
6832            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6833                    "getTaskThumbnails()");
6834            TaskRecord tr = recentTaskForIdLocked(id);
6835            if (tr != null) {
6836                return tr.getTaskThumbnailsLocked();
6837            }
6838        }
6839        return null;
6840    }
6841
6842    @Override
6843    public Bitmap getTaskTopThumbnail(int id) {
6844        synchronized (this) {
6845            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6846                    "getTaskTopThumbnail()");
6847            TaskRecord tr = recentTaskForIdLocked(id);
6848            if (tr != null) {
6849                return tr.getTaskTopThumbnailLocked();
6850            }
6851        }
6852        return null;
6853    }
6854
6855    @Override
6856    public boolean removeSubTask(int taskId, int subTaskIndex) {
6857        synchronized (this) {
6858            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6859                    "removeSubTask()");
6860            long ident = Binder.clearCallingIdentity();
6861            try {
6862                TaskRecord tr = recentTaskForIdLocked(taskId);
6863                if (tr != null) {
6864                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6865                }
6866                return false;
6867            } finally {
6868                Binder.restoreCallingIdentity(ident);
6869            }
6870        }
6871    }
6872
6873    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6874        if (!pr.killedByAm) {
6875            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6876            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6877                    pr.processName, pr.setAdj, reason);
6878            pr.killedByAm = true;
6879            Process.killProcessQuiet(pr.pid);
6880        }
6881    }
6882
6883    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6884        tr.disposeThumbnail();
6885        mRecentTasks.remove(tr);
6886        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6887        Intent baseIntent = new Intent(
6888                tr.intent != null ? tr.intent : tr.affinityIntent);
6889        ComponentName component = baseIntent.getComponent();
6890        if (component == null) {
6891            Slog.w(TAG, "Now component for base intent of task: " + tr);
6892            return;
6893        }
6894
6895        // Find any running services associated with this app.
6896        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6897
6898        if (killProcesses) {
6899            // Find any running processes associated with this app.
6900            final String pkg = component.getPackageName();
6901            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6902            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6903            for (int i=0; i<pmap.size(); i++) {
6904                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6905                for (int j=0; j<uids.size(); j++) {
6906                    ProcessRecord proc = uids.valueAt(j);
6907                    if (proc.userId != tr.userId) {
6908                        continue;
6909                    }
6910                    if (!proc.pkgList.containsKey(pkg)) {
6911                        continue;
6912                    }
6913                    procs.add(proc);
6914                }
6915            }
6916
6917            // Kill the running processes.
6918            for (int i=0; i<procs.size(); i++) {
6919                ProcessRecord pr = procs.get(i);
6920                if (pr == mHomeProcess) {
6921                    // Don't kill the home process along with tasks from the same package.
6922                    continue;
6923                }
6924                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6925                    killUnneededProcessLocked(pr, "remove task");
6926                } else {
6927                    pr.waitingToKill = "remove task";
6928                }
6929            }
6930        }
6931    }
6932
6933    @Override
6934    public boolean removeTask(int taskId, int flags) {
6935        synchronized (this) {
6936            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6937                    "removeTask()");
6938            long ident = Binder.clearCallingIdentity();
6939            try {
6940                TaskRecord tr = recentTaskForIdLocked(taskId);
6941                if (tr != null) {
6942                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6943                    if (r != null) {
6944                        cleanUpRemovedTaskLocked(tr, flags);
6945                        return true;
6946                    }
6947                    if (tr.mActivities.size() == 0) {
6948                        // Caller is just removing a recent task that is
6949                        // not actively running.  That is easy!
6950                        cleanUpRemovedTaskLocked(tr, flags);
6951                        return true;
6952                    }
6953                    Slog.w(TAG, "removeTask: task " + taskId
6954                            + " does not have activities to remove, "
6955                            + " but numActivities=" + tr.numActivities
6956                            + ": " + tr);
6957                }
6958            } finally {
6959                Binder.restoreCallingIdentity(ident);
6960            }
6961        }
6962        return false;
6963    }
6964
6965    /**
6966     * TODO: Add mController hook
6967     */
6968    @Override
6969    public void moveTaskToFront(int task, int flags, Bundle options) {
6970        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6971                "moveTaskToFront()");
6972
6973        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
6974        synchronized(this) {
6975            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6976                    Binder.getCallingUid(), "Task to front")) {
6977                ActivityOptions.abort(options);
6978                return;
6979            }
6980            final long origId = Binder.clearCallingIdentity();
6981            try {
6982                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
6983            } finally {
6984                Binder.restoreCallingIdentity(origId);
6985            }
6986            ActivityOptions.abort(options);
6987        }
6988    }
6989
6990    @Override
6991    public void moveTaskToBack(int taskId) {
6992        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6993                "moveTaskToBack()");
6994
6995        synchronized(this) {
6996            TaskRecord tr = recentTaskForIdLocked(taskId);
6997            if (tr != null) {
6998                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
6999                ActivityStack stack = tr.stack;
7000                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7001                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7002                            Binder.getCallingUid(), "Task to back")) {
7003                        return;
7004                    }
7005                }
7006                final long origId = Binder.clearCallingIdentity();
7007                try {
7008                    stack.moveTaskToBackLocked(taskId, null);
7009                } finally {
7010                    Binder.restoreCallingIdentity(origId);
7011                }
7012            }
7013        }
7014    }
7015
7016    /**
7017     * Moves an activity, and all of the other activities within the same task, to the bottom
7018     * of the history stack.  The activity's order within the task is unchanged.
7019     *
7020     * @param token A reference to the activity we wish to move
7021     * @param nonRoot If false then this only works if the activity is the root
7022     *                of a task; if true it will work for any activity in a task.
7023     * @return Returns true if the move completed, false if not.
7024     */
7025    @Override
7026    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7027        enforceNotIsolatedCaller("moveActivityTaskToBack");
7028        synchronized(this) {
7029            final long origId = Binder.clearCallingIdentity();
7030            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7031            if (taskId >= 0) {
7032                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7033            }
7034            Binder.restoreCallingIdentity(origId);
7035        }
7036        return false;
7037    }
7038
7039    @Override
7040    public void moveTaskBackwards(int task) {
7041        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7042                "moveTaskBackwards()");
7043
7044        synchronized(this) {
7045            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7046                    Binder.getCallingUid(), "Task backwards")) {
7047                return;
7048            }
7049            final long origId = Binder.clearCallingIdentity();
7050            moveTaskBackwardsLocked(task);
7051            Binder.restoreCallingIdentity(origId);
7052        }
7053    }
7054
7055    private final void moveTaskBackwardsLocked(int task) {
7056        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7057    }
7058
7059    @Override
7060    public IBinder getHomeActivityToken() throws RemoteException {
7061        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7062                "getHomeActivityToken()");
7063        synchronized (this) {
7064            return mStackSupervisor.getHomeActivityToken();
7065        }
7066    }
7067
7068    @Override
7069    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7070            IActivityContainerCallback callback) throws RemoteException {
7071        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7072                "createActivityContainer()");
7073        synchronized (this) {
7074            if (parentActivityToken == null) {
7075                throw new IllegalArgumentException("parent token must not be null");
7076            }
7077            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7078            if (r == null) {
7079                return null;
7080            }
7081            return mStackSupervisor.createActivityContainer(r, callback);
7082        }
7083    }
7084
7085    @Override
7086    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7087        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7088                "deleteActivityContainer()");
7089        synchronized (this) {
7090            mStackSupervisor.deleteActivityContainer(container);
7091        }
7092    }
7093
7094    @Override
7095    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7096            throws RemoteException {
7097        synchronized (this) {
7098            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7099            if (stack != null) {
7100                return stack.mActivityContainer;
7101            }
7102            return null;
7103        }
7104    }
7105
7106    @Override
7107    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7108        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7109                "moveTaskToStack()");
7110        if (stackId == HOME_STACK_ID) {
7111            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7112                    new RuntimeException("here").fillInStackTrace());
7113        }
7114        synchronized (this) {
7115            long ident = Binder.clearCallingIdentity();
7116            try {
7117                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7118                        + stackId + " toTop=" + toTop);
7119                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7120            } finally {
7121                Binder.restoreCallingIdentity(ident);
7122            }
7123        }
7124    }
7125
7126    @Override
7127    public void resizeStack(int stackBoxId, Rect bounds) {
7128        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7129                "resizeStackBox()");
7130        long ident = Binder.clearCallingIdentity();
7131        try {
7132            mWindowManager.resizeStack(stackBoxId, bounds);
7133        } finally {
7134            Binder.restoreCallingIdentity(ident);
7135        }
7136    }
7137
7138    @Override
7139    public List<StackInfo> getAllStackInfos() {
7140        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7141                "getAllStackInfos()");
7142        long ident = Binder.clearCallingIdentity();
7143        try {
7144            synchronized (this) {
7145                return mStackSupervisor.getAllStackInfosLocked();
7146            }
7147        } finally {
7148            Binder.restoreCallingIdentity(ident);
7149        }
7150    }
7151
7152    @Override
7153    public StackInfo getStackInfo(int stackId) {
7154        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7155                "getStackInfo()");
7156        long ident = Binder.clearCallingIdentity();
7157        try {
7158            synchronized (this) {
7159                return mStackSupervisor.getStackInfoLocked(stackId);
7160            }
7161        } finally {
7162            Binder.restoreCallingIdentity(ident);
7163        }
7164    }
7165
7166    @Override
7167    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7168        synchronized(this) {
7169            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7170        }
7171    }
7172
7173    // =========================================================
7174    // THUMBNAILS
7175    // =========================================================
7176
7177    public void reportThumbnail(IBinder token,
7178            Bitmap thumbnail, CharSequence description) {
7179        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7180        final long origId = Binder.clearCallingIdentity();
7181        sendPendingThumbnail(null, token, thumbnail, description, true);
7182        Binder.restoreCallingIdentity(origId);
7183    }
7184
7185    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7186            Bitmap thumbnail, CharSequence description, boolean always) {
7187        TaskRecord task;
7188        ArrayList<PendingThumbnailsRecord> receivers = null;
7189
7190        //System.out.println("Send pending thumbnail: " + r);
7191
7192        synchronized(this) {
7193            if (r == null) {
7194                r = ActivityRecord.isInStackLocked(token);
7195                if (r == null) {
7196                    return;
7197                }
7198            }
7199            if (thumbnail == null && r.thumbHolder != null) {
7200                thumbnail = r.thumbHolder.lastThumbnail;
7201                description = r.thumbHolder.lastDescription;
7202            }
7203            if (thumbnail == null && !always) {
7204                // If there is no thumbnail, and this entry is not actually
7205                // going away, then abort for now and pick up the next
7206                // thumbnail we get.
7207                return;
7208            }
7209            task = r.task;
7210
7211            int N = mPendingThumbnails.size();
7212            int i=0;
7213            while (i<N) {
7214                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7215                //System.out.println("Looking in " + pr.pendingRecords);
7216                if (pr.pendingRecords.remove(r)) {
7217                    if (receivers == null) {
7218                        receivers = new ArrayList<PendingThumbnailsRecord>();
7219                    }
7220                    receivers.add(pr);
7221                    if (pr.pendingRecords.size() == 0) {
7222                        pr.finished = true;
7223                        mPendingThumbnails.remove(i);
7224                        N--;
7225                        continue;
7226                    }
7227                }
7228                i++;
7229            }
7230        }
7231
7232        if (receivers != null) {
7233            final int N = receivers.size();
7234            for (int i=0; i<N; i++) {
7235                try {
7236                    PendingThumbnailsRecord pr = receivers.get(i);
7237                    pr.receiver.newThumbnail(
7238                        task != null ? task.taskId : -1, thumbnail, description);
7239                    if (pr.finished) {
7240                        pr.receiver.finished();
7241                    }
7242                } catch (Exception e) {
7243                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7244                }
7245            }
7246        }
7247    }
7248
7249    // =========================================================
7250    // CONTENT PROVIDERS
7251    // =========================================================
7252
7253    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7254        List<ProviderInfo> providers = null;
7255        try {
7256            providers = AppGlobals.getPackageManager().
7257                queryContentProviders(app.processName, app.uid,
7258                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7259        } catch (RemoteException ex) {
7260        }
7261        if (DEBUG_MU)
7262            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7263        int userId = app.userId;
7264        if (providers != null) {
7265            int N = providers.size();
7266            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7267            for (int i=0; i<N; i++) {
7268                ProviderInfo cpi =
7269                    (ProviderInfo)providers.get(i);
7270                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7271                        cpi.name, cpi.flags);
7272                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7273                    // This is a singleton provider, but a user besides the
7274                    // default user is asking to initialize a process it runs
7275                    // in...  well, no, it doesn't actually run in this process,
7276                    // it runs in the process of the default user.  Get rid of it.
7277                    providers.remove(i);
7278                    N--;
7279                    i--;
7280                    continue;
7281                }
7282
7283                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7284                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7285                if (cpr == null) {
7286                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7287                    mProviderMap.putProviderByClass(comp, cpr);
7288                }
7289                if (DEBUG_MU)
7290                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7291                app.pubProviders.put(cpi.name, cpr);
7292                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7293                    // Don't add this if it is a platform component that is marked
7294                    // to run in multiple processes, because this is actually
7295                    // part of the framework so doesn't make sense to track as a
7296                    // separate apk in the process.
7297                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7298                }
7299                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7300            }
7301        }
7302        return providers;
7303    }
7304
7305    /**
7306     * Check if {@link ProcessRecord} has a possible chance at accessing the
7307     * given {@link ProviderInfo}. Final permission checking is always done
7308     * in {@link ContentProvider}.
7309     */
7310    private final String checkContentProviderPermissionLocked(
7311            ProviderInfo cpi, ProcessRecord r) {
7312        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7313        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7314        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7315                cpi.applicationInfo.uid, cpi.exported)
7316                == PackageManager.PERMISSION_GRANTED) {
7317            return null;
7318        }
7319        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7320                cpi.applicationInfo.uid, cpi.exported)
7321                == PackageManager.PERMISSION_GRANTED) {
7322            return null;
7323        }
7324
7325        PathPermission[] pps = cpi.pathPermissions;
7326        if (pps != null) {
7327            int i = pps.length;
7328            while (i > 0) {
7329                i--;
7330                PathPermission pp = pps[i];
7331                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7332                        cpi.applicationInfo.uid, cpi.exported)
7333                        == PackageManager.PERMISSION_GRANTED) {
7334                    return null;
7335                }
7336                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7337                        cpi.applicationInfo.uid, cpi.exported)
7338                        == PackageManager.PERMISSION_GRANTED) {
7339                    return null;
7340                }
7341            }
7342        }
7343
7344        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7345        if (perms != null) {
7346            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7347                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7348                    return null;
7349                }
7350            }
7351        }
7352
7353        String msg;
7354        if (!cpi.exported) {
7355            msg = "Permission Denial: opening provider " + cpi.name
7356                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7357                    + ", uid=" + callingUid + ") that is not exported from uid "
7358                    + cpi.applicationInfo.uid;
7359        } else {
7360            msg = "Permission Denial: opening provider " + cpi.name
7361                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7362                    + ", uid=" + callingUid + ") requires "
7363                    + cpi.readPermission + " or " + cpi.writePermission;
7364        }
7365        Slog.w(TAG, msg);
7366        return msg;
7367    }
7368
7369    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7370            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7371        if (r != null) {
7372            for (int i=0; i<r.conProviders.size(); i++) {
7373                ContentProviderConnection conn = r.conProviders.get(i);
7374                if (conn.provider == cpr) {
7375                    if (DEBUG_PROVIDER) Slog.v(TAG,
7376                            "Adding provider requested by "
7377                            + r.processName + " from process "
7378                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7379                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7380                    if (stable) {
7381                        conn.stableCount++;
7382                        conn.numStableIncs++;
7383                    } else {
7384                        conn.unstableCount++;
7385                        conn.numUnstableIncs++;
7386                    }
7387                    return conn;
7388                }
7389            }
7390            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7391            if (stable) {
7392                conn.stableCount = 1;
7393                conn.numStableIncs = 1;
7394            } else {
7395                conn.unstableCount = 1;
7396                conn.numUnstableIncs = 1;
7397            }
7398            cpr.connections.add(conn);
7399            r.conProviders.add(conn);
7400            return conn;
7401        }
7402        cpr.addExternalProcessHandleLocked(externalProcessToken);
7403        return null;
7404    }
7405
7406    boolean decProviderCountLocked(ContentProviderConnection conn,
7407            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7408        if (conn != null) {
7409            cpr = conn.provider;
7410            if (DEBUG_PROVIDER) Slog.v(TAG,
7411                    "Removing provider requested by "
7412                    + conn.client.processName + " from process "
7413                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7414                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7415            if (stable) {
7416                conn.stableCount--;
7417            } else {
7418                conn.unstableCount--;
7419            }
7420            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7421                cpr.connections.remove(conn);
7422                conn.client.conProviders.remove(conn);
7423                return true;
7424            }
7425            return false;
7426        }
7427        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7428        return false;
7429    }
7430
7431    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7432            String name, IBinder token, boolean stable, int userId) {
7433        ContentProviderRecord cpr;
7434        ContentProviderConnection conn = null;
7435        ProviderInfo cpi = null;
7436
7437        synchronized(this) {
7438            ProcessRecord r = null;
7439            if (caller != null) {
7440                r = getRecordForAppLocked(caller);
7441                if (r == null) {
7442                    throw new SecurityException(
7443                            "Unable to find app for caller " + caller
7444                          + " (pid=" + Binder.getCallingPid()
7445                          + ") when getting content provider " + name);
7446                }
7447            }
7448
7449            // First check if this content provider has been published...
7450            cpr = mProviderMap.getProviderByName(name, userId);
7451            boolean providerRunning = cpr != null;
7452            if (providerRunning) {
7453                cpi = cpr.info;
7454                String msg;
7455                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7456                    throw new SecurityException(msg);
7457                }
7458
7459                if (r != null && cpr.canRunHere(r)) {
7460                    // This provider has been published or is in the process
7461                    // of being published...  but it is also allowed to run
7462                    // in the caller's process, so don't make a connection
7463                    // and just let the caller instantiate its own instance.
7464                    ContentProviderHolder holder = cpr.newHolder(null);
7465                    // don't give caller the provider object, it needs
7466                    // to make its own.
7467                    holder.provider = null;
7468                    return holder;
7469                }
7470
7471                final long origId = Binder.clearCallingIdentity();
7472
7473                // In this case the provider instance already exists, so we can
7474                // return it right away.
7475                conn = incProviderCountLocked(r, cpr, token, stable);
7476                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7477                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7478                        // If this is a perceptible app accessing the provider,
7479                        // make sure to count it as being accessed and thus
7480                        // back up on the LRU list.  This is good because
7481                        // content providers are often expensive to start.
7482                        updateLruProcessLocked(cpr.proc, false, null);
7483                    }
7484                }
7485
7486                if (cpr.proc != null) {
7487                    if (false) {
7488                        if (cpr.name.flattenToShortString().equals(
7489                                "com.android.providers.calendar/.CalendarProvider2")) {
7490                            Slog.v(TAG, "****************** KILLING "
7491                                + cpr.name.flattenToShortString());
7492                            Process.killProcess(cpr.proc.pid);
7493                        }
7494                    }
7495                    boolean success = updateOomAdjLocked(cpr.proc);
7496                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7497                    // NOTE: there is still a race here where a signal could be
7498                    // pending on the process even though we managed to update its
7499                    // adj level.  Not sure what to do about this, but at least
7500                    // the race is now smaller.
7501                    if (!success) {
7502                        // Uh oh...  it looks like the provider's process
7503                        // has been killed on us.  We need to wait for a new
7504                        // process to be started, and make sure its death
7505                        // doesn't kill our process.
7506                        Slog.i(TAG,
7507                                "Existing provider " + cpr.name.flattenToShortString()
7508                                + " is crashing; detaching " + r);
7509                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7510                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7511                        if (!lastRef) {
7512                            // This wasn't the last ref our process had on
7513                            // the provider...  we have now been killed, bail.
7514                            return null;
7515                        }
7516                        providerRunning = false;
7517                        conn = null;
7518                    }
7519                }
7520
7521                Binder.restoreCallingIdentity(origId);
7522            }
7523
7524            boolean singleton;
7525            if (!providerRunning) {
7526                try {
7527                    cpi = AppGlobals.getPackageManager().
7528                        resolveContentProvider(name,
7529                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7530                } catch (RemoteException ex) {
7531                }
7532                if (cpi == null) {
7533                    return null;
7534                }
7535                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7536                        cpi.name, cpi.flags);
7537                if (singleton) {
7538                    userId = 0;
7539                }
7540                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7541
7542                String msg;
7543                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7544                    throw new SecurityException(msg);
7545                }
7546
7547                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7548                        && !cpi.processName.equals("system")) {
7549                    // If this content provider does not run in the system
7550                    // process, and the system is not yet ready to run other
7551                    // processes, then fail fast instead of hanging.
7552                    throw new IllegalArgumentException(
7553                            "Attempt to launch content provider before system ready");
7554                }
7555
7556                // Make sure that the user who owns this provider is started.  If not,
7557                // we don't want to allow it to run.
7558                if (mStartedUsers.get(userId) == null) {
7559                    Slog.w(TAG, "Unable to launch app "
7560                            + cpi.applicationInfo.packageName + "/"
7561                            + cpi.applicationInfo.uid + " for provider "
7562                            + name + ": user " + userId + " is stopped");
7563                    return null;
7564                }
7565
7566                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7567                cpr = mProviderMap.getProviderByClass(comp, userId);
7568                final boolean firstClass = cpr == null;
7569                if (firstClass) {
7570                    try {
7571                        ApplicationInfo ai =
7572                            AppGlobals.getPackageManager().
7573                                getApplicationInfo(
7574                                        cpi.applicationInfo.packageName,
7575                                        STOCK_PM_FLAGS, userId);
7576                        if (ai == null) {
7577                            Slog.w(TAG, "No package info for content provider "
7578                                    + cpi.name);
7579                            return null;
7580                        }
7581                        ai = getAppInfoForUser(ai, userId);
7582                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7583                    } catch (RemoteException ex) {
7584                        // pm is in same process, this will never happen.
7585                    }
7586                }
7587
7588                if (r != null && cpr.canRunHere(r)) {
7589                    // If this is a multiprocess provider, then just return its
7590                    // info and allow the caller to instantiate it.  Only do
7591                    // this if the provider is the same user as the caller's
7592                    // process, or can run as root (so can be in any process).
7593                    return cpr.newHolder(null);
7594                }
7595
7596                if (DEBUG_PROVIDER) {
7597                    RuntimeException e = new RuntimeException("here");
7598                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7599                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7600                }
7601
7602                // This is single process, and our app is now connecting to it.
7603                // See if we are already in the process of launching this
7604                // provider.
7605                final int N = mLaunchingProviders.size();
7606                int i;
7607                for (i=0; i<N; i++) {
7608                    if (mLaunchingProviders.get(i) == cpr) {
7609                        break;
7610                    }
7611                }
7612
7613                // If the provider is not already being launched, then get it
7614                // started.
7615                if (i >= N) {
7616                    final long origId = Binder.clearCallingIdentity();
7617
7618                    try {
7619                        // Content provider is now in use, its package can't be stopped.
7620                        try {
7621                            AppGlobals.getPackageManager().setPackageStoppedState(
7622                                    cpr.appInfo.packageName, false, userId);
7623                        } catch (RemoteException e) {
7624                        } catch (IllegalArgumentException e) {
7625                            Slog.w(TAG, "Failed trying to unstop package "
7626                                    + cpr.appInfo.packageName + ": " + e);
7627                        }
7628
7629                        // Use existing process if already started
7630                        ProcessRecord proc = getProcessRecordLocked(
7631                                cpi.processName, cpr.appInfo.uid, false);
7632                        if (proc != null && proc.thread != null) {
7633                            if (DEBUG_PROVIDER) {
7634                                Slog.d(TAG, "Installing in existing process " + proc);
7635                            }
7636                            proc.pubProviders.put(cpi.name, cpr);
7637                            try {
7638                                proc.thread.scheduleInstallProvider(cpi);
7639                            } catch (RemoteException e) {
7640                            }
7641                        } else {
7642                            proc = startProcessLocked(cpi.processName,
7643                                    cpr.appInfo, false, 0, "content provider",
7644                                    new ComponentName(cpi.applicationInfo.packageName,
7645                                            cpi.name), false, false, false);
7646                            if (proc == null) {
7647                                Slog.w(TAG, "Unable to launch app "
7648                                        + cpi.applicationInfo.packageName + "/"
7649                                        + cpi.applicationInfo.uid + " for provider "
7650                                        + name + ": process is bad");
7651                                return null;
7652                            }
7653                        }
7654                        cpr.launchingApp = proc;
7655                        mLaunchingProviders.add(cpr);
7656                    } finally {
7657                        Binder.restoreCallingIdentity(origId);
7658                    }
7659                }
7660
7661                // Make sure the provider is published (the same provider class
7662                // may be published under multiple names).
7663                if (firstClass) {
7664                    mProviderMap.putProviderByClass(comp, cpr);
7665                }
7666
7667                mProviderMap.putProviderByName(name, cpr);
7668                conn = incProviderCountLocked(r, cpr, token, stable);
7669                if (conn != null) {
7670                    conn.waiting = true;
7671                }
7672            }
7673        }
7674
7675        // Wait for the provider to be published...
7676        synchronized (cpr) {
7677            while (cpr.provider == null) {
7678                if (cpr.launchingApp == null) {
7679                    Slog.w(TAG, "Unable to launch app "
7680                            + cpi.applicationInfo.packageName + "/"
7681                            + cpi.applicationInfo.uid + " for provider "
7682                            + name + ": launching app became null");
7683                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7684                            UserHandle.getUserId(cpi.applicationInfo.uid),
7685                            cpi.applicationInfo.packageName,
7686                            cpi.applicationInfo.uid, name);
7687                    return null;
7688                }
7689                try {
7690                    if (DEBUG_MU) {
7691                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7692                                + cpr.launchingApp);
7693                    }
7694                    if (conn != null) {
7695                        conn.waiting = true;
7696                    }
7697                    cpr.wait();
7698                } catch (InterruptedException ex) {
7699                } finally {
7700                    if (conn != null) {
7701                        conn.waiting = false;
7702                    }
7703                }
7704            }
7705        }
7706        return cpr != null ? cpr.newHolder(conn) : null;
7707    }
7708
7709    public final ContentProviderHolder getContentProvider(
7710            IApplicationThread caller, String name, int userId, boolean stable) {
7711        enforceNotIsolatedCaller("getContentProvider");
7712        if (caller == null) {
7713            String msg = "null IApplicationThread when getting content provider "
7714                    + name;
7715            Slog.w(TAG, msg);
7716            throw new SecurityException(msg);
7717        }
7718
7719        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7720                false, true, "getContentProvider", null);
7721        return getContentProviderImpl(caller, name, null, stable, userId);
7722    }
7723
7724    public ContentProviderHolder getContentProviderExternal(
7725            String name, int userId, IBinder token) {
7726        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7727            "Do not have permission in call getContentProviderExternal()");
7728        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7729                false, true, "getContentProvider", null);
7730        return getContentProviderExternalUnchecked(name, token, userId);
7731    }
7732
7733    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7734            IBinder token, int userId) {
7735        return getContentProviderImpl(null, name, token, true, userId);
7736    }
7737
7738    /**
7739     * Drop a content provider from a ProcessRecord's bookkeeping
7740     */
7741    public void removeContentProvider(IBinder connection, boolean stable) {
7742        enforceNotIsolatedCaller("removeContentProvider");
7743        synchronized (this) {
7744            ContentProviderConnection conn;
7745            try {
7746                conn = (ContentProviderConnection)connection;
7747            } catch (ClassCastException e) {
7748                String msg ="removeContentProvider: " + connection
7749                        + " not a ContentProviderConnection";
7750                Slog.w(TAG, msg);
7751                throw new IllegalArgumentException(msg);
7752            }
7753            if (conn == null) {
7754                throw new NullPointerException("connection is null");
7755            }
7756            if (decProviderCountLocked(conn, null, null, stable)) {
7757                updateOomAdjLocked();
7758            }
7759        }
7760    }
7761
7762    public void removeContentProviderExternal(String name, IBinder token) {
7763        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7764            "Do not have permission in call removeContentProviderExternal()");
7765        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7766    }
7767
7768    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7769        synchronized (this) {
7770            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7771            if(cpr == null) {
7772                //remove from mProvidersByClass
7773                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7774                return;
7775            }
7776
7777            //update content provider record entry info
7778            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7779            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7780            if (localCpr.hasExternalProcessHandles()) {
7781                if (localCpr.removeExternalProcessHandleLocked(token)) {
7782                    updateOomAdjLocked();
7783                } else {
7784                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7785                            + " with no external reference for token: "
7786                            + token + ".");
7787                }
7788            } else {
7789                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7790                        + " with no external references.");
7791            }
7792        }
7793    }
7794
7795    public final void publishContentProviders(IApplicationThread caller,
7796            List<ContentProviderHolder> providers) {
7797        if (providers == null) {
7798            return;
7799        }
7800
7801        enforceNotIsolatedCaller("publishContentProviders");
7802        synchronized (this) {
7803            final ProcessRecord r = getRecordForAppLocked(caller);
7804            if (DEBUG_MU)
7805                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7806            if (r == null) {
7807                throw new SecurityException(
7808                        "Unable to find app for caller " + caller
7809                      + " (pid=" + Binder.getCallingPid()
7810                      + ") when publishing content providers");
7811            }
7812
7813            final long origId = Binder.clearCallingIdentity();
7814
7815            final int N = providers.size();
7816            for (int i=0; i<N; i++) {
7817                ContentProviderHolder src = providers.get(i);
7818                if (src == null || src.info == null || src.provider == null) {
7819                    continue;
7820                }
7821                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7822                if (DEBUG_MU)
7823                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7824                if (dst != null) {
7825                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7826                    mProviderMap.putProviderByClass(comp, dst);
7827                    String names[] = dst.info.authority.split(";");
7828                    for (int j = 0; j < names.length; j++) {
7829                        mProviderMap.putProviderByName(names[j], dst);
7830                    }
7831
7832                    int NL = mLaunchingProviders.size();
7833                    int j;
7834                    for (j=0; j<NL; j++) {
7835                        if (mLaunchingProviders.get(j) == dst) {
7836                            mLaunchingProviders.remove(j);
7837                            j--;
7838                            NL--;
7839                        }
7840                    }
7841                    synchronized (dst) {
7842                        dst.provider = src.provider;
7843                        dst.proc = r;
7844                        dst.notifyAll();
7845                    }
7846                    updateOomAdjLocked(r);
7847                }
7848            }
7849
7850            Binder.restoreCallingIdentity(origId);
7851        }
7852    }
7853
7854    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7855        ContentProviderConnection conn;
7856        try {
7857            conn = (ContentProviderConnection)connection;
7858        } catch (ClassCastException e) {
7859            String msg ="refContentProvider: " + connection
7860                    + " not a ContentProviderConnection";
7861            Slog.w(TAG, msg);
7862            throw new IllegalArgumentException(msg);
7863        }
7864        if (conn == null) {
7865            throw new NullPointerException("connection is null");
7866        }
7867
7868        synchronized (this) {
7869            if (stable > 0) {
7870                conn.numStableIncs += stable;
7871            }
7872            stable = conn.stableCount + stable;
7873            if (stable < 0) {
7874                throw new IllegalStateException("stableCount < 0: " + stable);
7875            }
7876
7877            if (unstable > 0) {
7878                conn.numUnstableIncs += unstable;
7879            }
7880            unstable = conn.unstableCount + unstable;
7881            if (unstable < 0) {
7882                throw new IllegalStateException("unstableCount < 0: " + unstable);
7883            }
7884
7885            if ((stable+unstable) <= 0) {
7886                throw new IllegalStateException("ref counts can't go to zero here: stable="
7887                        + stable + " unstable=" + unstable);
7888            }
7889            conn.stableCount = stable;
7890            conn.unstableCount = unstable;
7891            return !conn.dead;
7892        }
7893    }
7894
7895    public void unstableProviderDied(IBinder connection) {
7896        ContentProviderConnection conn;
7897        try {
7898            conn = (ContentProviderConnection)connection;
7899        } catch (ClassCastException e) {
7900            String msg ="refContentProvider: " + connection
7901                    + " not a ContentProviderConnection";
7902            Slog.w(TAG, msg);
7903            throw new IllegalArgumentException(msg);
7904        }
7905        if (conn == null) {
7906            throw new NullPointerException("connection is null");
7907        }
7908
7909        // Safely retrieve the content provider associated with the connection.
7910        IContentProvider provider;
7911        synchronized (this) {
7912            provider = conn.provider.provider;
7913        }
7914
7915        if (provider == null) {
7916            // Um, yeah, we're way ahead of you.
7917            return;
7918        }
7919
7920        // Make sure the caller is being honest with us.
7921        if (provider.asBinder().pingBinder()) {
7922            // Er, no, still looks good to us.
7923            synchronized (this) {
7924                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7925                        + " says " + conn + " died, but we don't agree");
7926                return;
7927            }
7928        }
7929
7930        // Well look at that!  It's dead!
7931        synchronized (this) {
7932            if (conn.provider.provider != provider) {
7933                // But something changed...  good enough.
7934                return;
7935            }
7936
7937            ProcessRecord proc = conn.provider.proc;
7938            if (proc == null || proc.thread == null) {
7939                // Seems like the process is already cleaned up.
7940                return;
7941            }
7942
7943            // As far as we're concerned, this is just like receiving a
7944            // death notification...  just a bit prematurely.
7945            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7946                    + ") early provider death");
7947            final long ident = Binder.clearCallingIdentity();
7948            try {
7949                appDiedLocked(proc, proc.pid, proc.thread);
7950            } finally {
7951                Binder.restoreCallingIdentity(ident);
7952            }
7953        }
7954    }
7955
7956    @Override
7957    public void appNotRespondingViaProvider(IBinder connection) {
7958        enforceCallingPermission(
7959                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7960
7961        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7962        if (conn == null) {
7963            Slog.w(TAG, "ContentProviderConnection is null");
7964            return;
7965        }
7966
7967        final ProcessRecord host = conn.provider.proc;
7968        if (host == null) {
7969            Slog.w(TAG, "Failed to find hosting ProcessRecord");
7970            return;
7971        }
7972
7973        final long token = Binder.clearCallingIdentity();
7974        try {
7975            appNotResponding(host, null, null, false, "ContentProvider not responding");
7976        } finally {
7977            Binder.restoreCallingIdentity(token);
7978        }
7979    }
7980
7981    public final void installSystemProviders() {
7982        List<ProviderInfo> providers;
7983        synchronized (this) {
7984            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
7985            providers = generateApplicationProvidersLocked(app);
7986            if (providers != null) {
7987                for (int i=providers.size()-1; i>=0; i--) {
7988                    ProviderInfo pi = (ProviderInfo)providers.get(i);
7989                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7990                        Slog.w(TAG, "Not installing system proc provider " + pi.name
7991                                + ": not system .apk");
7992                        providers.remove(i);
7993                    }
7994                }
7995            }
7996        }
7997        if (providers != null) {
7998            mSystemThread.installSystemProviders(providers);
7999        }
8000
8001        mCoreSettingsObserver = new CoreSettingsObserver(this);
8002
8003        mUsageStatsService.monitorPackages();
8004    }
8005
8006    /**
8007     * Allows app to retrieve the MIME type of a URI without having permission
8008     * to access its content provider.
8009     *
8010     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8011     *
8012     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8013     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8014     */
8015    public String getProviderMimeType(Uri uri, int userId) {
8016        enforceNotIsolatedCaller("getProviderMimeType");
8017        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8018                userId, false, true, "getProviderMimeType", null);
8019        final String name = uri.getAuthority();
8020        final long ident = Binder.clearCallingIdentity();
8021        ContentProviderHolder holder = null;
8022
8023        try {
8024            holder = getContentProviderExternalUnchecked(name, null, userId);
8025            if (holder != null) {
8026                return holder.provider.getType(uri);
8027            }
8028        } catch (RemoteException e) {
8029            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8030            return null;
8031        } finally {
8032            if (holder != null) {
8033                removeContentProviderExternalUnchecked(name, null, userId);
8034            }
8035            Binder.restoreCallingIdentity(ident);
8036        }
8037
8038        return null;
8039    }
8040
8041    // =========================================================
8042    // GLOBAL MANAGEMENT
8043    // =========================================================
8044
8045    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8046            boolean isolated) {
8047        String proc = customProcess != null ? customProcess : info.processName;
8048        BatteryStatsImpl.Uid.Proc ps = null;
8049        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8050        int uid = info.uid;
8051        if (isolated) {
8052            int userId = UserHandle.getUserId(uid);
8053            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8054            while (true) {
8055                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8056                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8057                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8058                }
8059                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8060                mNextIsolatedProcessUid++;
8061                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8062                    // No process for this uid, use it.
8063                    break;
8064                }
8065                stepsLeft--;
8066                if (stepsLeft <= 0) {
8067                    return null;
8068                }
8069            }
8070        }
8071        return new ProcessRecord(stats, info, proc, uid);
8072    }
8073
8074    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8075        ProcessRecord app;
8076        if (!isolated) {
8077            app = getProcessRecordLocked(info.processName, info.uid, true);
8078        } else {
8079            app = null;
8080        }
8081
8082        if (app == null) {
8083            app = newProcessRecordLocked(info, null, isolated);
8084            mProcessNames.put(info.processName, app.uid, app);
8085            if (isolated) {
8086                mIsolatedProcesses.put(app.uid, app);
8087            }
8088            updateLruProcessLocked(app, false, null);
8089            updateOomAdjLocked();
8090        }
8091
8092        // This package really, really can not be stopped.
8093        try {
8094            AppGlobals.getPackageManager().setPackageStoppedState(
8095                    info.packageName, false, UserHandle.getUserId(app.uid));
8096        } catch (RemoteException e) {
8097        } catch (IllegalArgumentException e) {
8098            Slog.w(TAG, "Failed trying to unstop package "
8099                    + info.packageName + ": " + e);
8100        }
8101
8102        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8103                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8104            app.persistent = true;
8105            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8106        }
8107        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8108            mPersistentStartingProcesses.add(app);
8109            startProcessLocked(app, "added application", app.processName);
8110        }
8111
8112        return app;
8113    }
8114
8115    public void unhandledBack() {
8116        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8117                "unhandledBack()");
8118
8119        synchronized(this) {
8120            final long origId = Binder.clearCallingIdentity();
8121            try {
8122                getFocusedStack().unhandledBackLocked();
8123            } finally {
8124                Binder.restoreCallingIdentity(origId);
8125            }
8126        }
8127    }
8128
8129    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8130        enforceNotIsolatedCaller("openContentUri");
8131        final int userId = UserHandle.getCallingUserId();
8132        String name = uri.getAuthority();
8133        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8134        ParcelFileDescriptor pfd = null;
8135        if (cph != null) {
8136            // We record the binder invoker's uid in thread-local storage before
8137            // going to the content provider to open the file.  Later, in the code
8138            // that handles all permissions checks, we look for this uid and use
8139            // that rather than the Activity Manager's own uid.  The effect is that
8140            // we do the check against the caller's permissions even though it looks
8141            // to the content provider like the Activity Manager itself is making
8142            // the request.
8143            sCallerIdentity.set(new Identity(
8144                    Binder.getCallingPid(), Binder.getCallingUid()));
8145            try {
8146                pfd = cph.provider.openFile(null, uri, "r", null);
8147            } catch (FileNotFoundException e) {
8148                // do nothing; pfd will be returned null
8149            } finally {
8150                // Ensure that whatever happens, we clean up the identity state
8151                sCallerIdentity.remove();
8152            }
8153
8154            // We've got the fd now, so we're done with the provider.
8155            removeContentProviderExternalUnchecked(name, null, userId);
8156        } else {
8157            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8158        }
8159        return pfd;
8160    }
8161
8162    // Actually is sleeping or shutting down or whatever else in the future
8163    // is an inactive state.
8164    public boolean isSleepingOrShuttingDown() {
8165        return mSleeping || mShuttingDown;
8166    }
8167
8168    void goingToSleep() {
8169        synchronized(this) {
8170            mWentToSleep = true;
8171            updateEventDispatchingLocked();
8172
8173            if (!mSleeping) {
8174                mSleeping = true;
8175                mStackSupervisor.goingToSleepLocked();
8176
8177                // Initialize the wake times of all processes.
8178                checkExcessivePowerUsageLocked(false);
8179                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8180                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8181                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8182            }
8183        }
8184    }
8185
8186    @Override
8187    public boolean shutdown(int timeout) {
8188        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8189                != PackageManager.PERMISSION_GRANTED) {
8190            throw new SecurityException("Requires permission "
8191                    + android.Manifest.permission.SHUTDOWN);
8192        }
8193
8194        boolean timedout = false;
8195
8196        synchronized(this) {
8197            mShuttingDown = true;
8198            updateEventDispatchingLocked();
8199            timedout = mStackSupervisor.shutdownLocked(timeout);
8200        }
8201
8202        mAppOpsService.shutdown();
8203        mUsageStatsService.shutdown();
8204        mBatteryStatsService.shutdown();
8205        synchronized (this) {
8206            mProcessStats.shutdownLocked();
8207        }
8208
8209        return timedout;
8210    }
8211
8212    public final void activitySlept(IBinder token) {
8213        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8214
8215        final long origId = Binder.clearCallingIdentity();
8216
8217        synchronized (this) {
8218            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8219            if (r != null) {
8220                mStackSupervisor.activitySleptLocked(r);
8221            }
8222        }
8223
8224        Binder.restoreCallingIdentity(origId);
8225    }
8226
8227    void logLockScreen(String msg) {
8228        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8229                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8230                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8231                mStackSupervisor.mDismissKeyguardOnNextActivity);
8232    }
8233
8234    private void comeOutOfSleepIfNeededLocked() {
8235        if (!mWentToSleep && !mLockScreenShown) {
8236            if (mSleeping) {
8237                mSleeping = false;
8238                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8239            }
8240        }
8241    }
8242
8243    void wakingUp() {
8244        synchronized(this) {
8245            mWentToSleep = false;
8246            updateEventDispatchingLocked();
8247            comeOutOfSleepIfNeededLocked();
8248        }
8249    }
8250
8251    private void updateEventDispatchingLocked() {
8252        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8253    }
8254
8255    public void setLockScreenShown(boolean shown) {
8256        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8257                != PackageManager.PERMISSION_GRANTED) {
8258            throw new SecurityException("Requires permission "
8259                    + android.Manifest.permission.DEVICE_POWER);
8260        }
8261
8262        synchronized(this) {
8263            long ident = Binder.clearCallingIdentity();
8264            try {
8265                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8266                mLockScreenShown = shown;
8267                comeOutOfSleepIfNeededLocked();
8268            } finally {
8269                Binder.restoreCallingIdentity(ident);
8270            }
8271        }
8272    }
8273
8274    public void stopAppSwitches() {
8275        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8276                != PackageManager.PERMISSION_GRANTED) {
8277            throw new SecurityException("Requires permission "
8278                    + android.Manifest.permission.STOP_APP_SWITCHES);
8279        }
8280
8281        synchronized(this) {
8282            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8283                    + APP_SWITCH_DELAY_TIME;
8284            mDidAppSwitch = false;
8285            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8286            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8287            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8288        }
8289    }
8290
8291    public void resumeAppSwitches() {
8292        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8293                != PackageManager.PERMISSION_GRANTED) {
8294            throw new SecurityException("Requires permission "
8295                    + android.Manifest.permission.STOP_APP_SWITCHES);
8296        }
8297
8298        synchronized(this) {
8299            // Note that we don't execute any pending app switches... we will
8300            // let those wait until either the timeout, or the next start
8301            // activity request.
8302            mAppSwitchesAllowedTime = 0;
8303        }
8304    }
8305
8306    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8307            String name) {
8308        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8309            return true;
8310        }
8311
8312        final int perm = checkComponentPermission(
8313                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8314                callingUid, -1, true);
8315        if (perm == PackageManager.PERMISSION_GRANTED) {
8316            return true;
8317        }
8318
8319        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8320        return false;
8321    }
8322
8323    public void setDebugApp(String packageName, boolean waitForDebugger,
8324            boolean persistent) {
8325        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8326                "setDebugApp()");
8327
8328        long ident = Binder.clearCallingIdentity();
8329        try {
8330            // Note that this is not really thread safe if there are multiple
8331            // callers into it at the same time, but that's not a situation we
8332            // care about.
8333            if (persistent) {
8334                final ContentResolver resolver = mContext.getContentResolver();
8335                Settings.Global.putString(
8336                    resolver, Settings.Global.DEBUG_APP,
8337                    packageName);
8338                Settings.Global.putInt(
8339                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8340                    waitForDebugger ? 1 : 0);
8341            }
8342
8343            synchronized (this) {
8344                if (!persistent) {
8345                    mOrigDebugApp = mDebugApp;
8346                    mOrigWaitForDebugger = mWaitForDebugger;
8347                }
8348                mDebugApp = packageName;
8349                mWaitForDebugger = waitForDebugger;
8350                mDebugTransient = !persistent;
8351                if (packageName != null) {
8352                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8353                            UserHandle.USER_ALL, "set debug app");
8354                }
8355            }
8356        } finally {
8357            Binder.restoreCallingIdentity(ident);
8358        }
8359    }
8360
8361    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8362        synchronized (this) {
8363            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8364            if (!isDebuggable) {
8365                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8366                    throw new SecurityException("Process not debuggable: " + app.packageName);
8367                }
8368            }
8369
8370            mOpenGlTraceApp = processName;
8371        }
8372    }
8373
8374    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8375            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8376        synchronized (this) {
8377            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8378            if (!isDebuggable) {
8379                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8380                    throw new SecurityException("Process not debuggable: " + app.packageName);
8381                }
8382            }
8383            mProfileApp = processName;
8384            mProfileFile = profileFile;
8385            if (mProfileFd != null) {
8386                try {
8387                    mProfileFd.close();
8388                } catch (IOException e) {
8389                }
8390                mProfileFd = null;
8391            }
8392            mProfileFd = profileFd;
8393            mProfileType = 0;
8394            mAutoStopProfiler = autoStopProfiler;
8395        }
8396    }
8397
8398    @Override
8399    public void setAlwaysFinish(boolean enabled) {
8400        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8401                "setAlwaysFinish()");
8402
8403        Settings.Global.putInt(
8404                mContext.getContentResolver(),
8405                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8406
8407        synchronized (this) {
8408            mAlwaysFinishActivities = enabled;
8409        }
8410    }
8411
8412    @Override
8413    public void setActivityController(IActivityController controller) {
8414        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8415                "setActivityController()");
8416        synchronized (this) {
8417            mController = controller;
8418            Watchdog.getInstance().setActivityController(controller);
8419        }
8420    }
8421
8422    @Override
8423    public void setUserIsMonkey(boolean userIsMonkey) {
8424        synchronized (this) {
8425            synchronized (mPidsSelfLocked) {
8426                final int callingPid = Binder.getCallingPid();
8427                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8428                if (precessRecord == null) {
8429                    throw new SecurityException("Unknown process: " + callingPid);
8430                }
8431                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8432                    throw new SecurityException("Only an instrumentation process "
8433                            + "with a UiAutomation can call setUserIsMonkey");
8434                }
8435            }
8436            mUserIsMonkey = userIsMonkey;
8437        }
8438    }
8439
8440    @Override
8441    public boolean isUserAMonkey() {
8442        synchronized (this) {
8443            // If there is a controller also implies the user is a monkey.
8444            return (mUserIsMonkey || mController != null);
8445        }
8446    }
8447
8448    public void requestBugReport() {
8449        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8450        SystemProperties.set("ctl.start", "bugreport");
8451    }
8452
8453    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8454        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8455    }
8456
8457    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8458        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8459            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8460        }
8461        return KEY_DISPATCHING_TIMEOUT;
8462    }
8463
8464    @Override
8465    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8466        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8467                != PackageManager.PERMISSION_GRANTED) {
8468            throw new SecurityException("Requires permission "
8469                    + android.Manifest.permission.FILTER_EVENTS);
8470        }
8471        ProcessRecord proc;
8472        long timeout;
8473        synchronized (this) {
8474            synchronized (mPidsSelfLocked) {
8475                proc = mPidsSelfLocked.get(pid);
8476            }
8477            timeout = getInputDispatchingTimeoutLocked(proc);
8478        }
8479
8480        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8481            return -1;
8482        }
8483
8484        return timeout;
8485    }
8486
8487    /**
8488     * Handle input dispatching timeouts.
8489     * Returns whether input dispatching should be aborted or not.
8490     */
8491    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8492            final ActivityRecord activity, final ActivityRecord parent,
8493            final boolean aboveSystem, String reason) {
8494        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8495                != PackageManager.PERMISSION_GRANTED) {
8496            throw new SecurityException("Requires permission "
8497                    + android.Manifest.permission.FILTER_EVENTS);
8498        }
8499
8500        final String annotation;
8501        if (reason == null) {
8502            annotation = "Input dispatching timed out";
8503        } else {
8504            annotation = "Input dispatching timed out (" + reason + ")";
8505        }
8506
8507        if (proc != null) {
8508            synchronized (this) {
8509                if (proc.debugging) {
8510                    return false;
8511                }
8512
8513                if (mDidDexOpt) {
8514                    // Give more time since we were dexopting.
8515                    mDidDexOpt = false;
8516                    return false;
8517                }
8518
8519                if (proc.instrumentationClass != null) {
8520                    Bundle info = new Bundle();
8521                    info.putString("shortMsg", "keyDispatchingTimedOut");
8522                    info.putString("longMsg", annotation);
8523                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8524                    return true;
8525                }
8526            }
8527            mHandler.post(new Runnable() {
8528                @Override
8529                public void run() {
8530                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8531                }
8532            });
8533        }
8534
8535        return true;
8536    }
8537
8538    public Bundle getAssistContextExtras(int requestType) {
8539        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8540                "getAssistContextExtras()");
8541        PendingAssistExtras pae;
8542        Bundle extras = new Bundle();
8543        synchronized (this) {
8544            ActivityRecord activity = getFocusedStack().mResumedActivity;
8545            if (activity == null) {
8546                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8547                return null;
8548            }
8549            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8550            if (activity.app == null || activity.app.thread == null) {
8551                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8552                return extras;
8553            }
8554            if (activity.app.pid == Binder.getCallingPid()) {
8555                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8556                return extras;
8557            }
8558            pae = new PendingAssistExtras(activity);
8559            try {
8560                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8561                        requestType);
8562                mPendingAssistExtras.add(pae);
8563                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8564            } catch (RemoteException e) {
8565                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8566                return extras;
8567            }
8568        }
8569        synchronized (pae) {
8570            while (!pae.haveResult) {
8571                try {
8572                    pae.wait();
8573                } catch (InterruptedException e) {
8574                }
8575            }
8576            if (pae.result != null) {
8577                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8578            }
8579        }
8580        synchronized (this) {
8581            mPendingAssistExtras.remove(pae);
8582            mHandler.removeCallbacks(pae);
8583        }
8584        return extras;
8585    }
8586
8587    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8588        PendingAssistExtras pae = (PendingAssistExtras)token;
8589        synchronized (pae) {
8590            pae.result = extras;
8591            pae.haveResult = true;
8592            pae.notifyAll();
8593        }
8594    }
8595
8596    public void registerProcessObserver(IProcessObserver observer) {
8597        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8598                "registerProcessObserver()");
8599        synchronized (this) {
8600            mProcessObservers.register(observer);
8601        }
8602    }
8603
8604    @Override
8605    public void unregisterProcessObserver(IProcessObserver observer) {
8606        synchronized (this) {
8607            mProcessObservers.unregister(observer);
8608        }
8609    }
8610
8611    @Override
8612    public boolean convertFromTranslucent(IBinder token) {
8613        final long origId = Binder.clearCallingIdentity();
8614        try {
8615            synchronized (this) {
8616                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8617                if (r == null) {
8618                    return false;
8619                }
8620                if (r.changeWindowTranslucency(true)) {
8621                    mWindowManager.setAppFullscreen(token, true);
8622                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8623                    return true;
8624                }
8625                return false;
8626            }
8627        } finally {
8628            Binder.restoreCallingIdentity(origId);
8629        }
8630    }
8631
8632    @Override
8633    public boolean convertToTranslucent(IBinder token) {
8634        final long origId = Binder.clearCallingIdentity();
8635        try {
8636            synchronized (this) {
8637                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8638                if (r == null) {
8639                    return false;
8640                }
8641                if (r.changeWindowTranslucency(false)) {
8642                    r.task.stack.convertToTranslucent(r);
8643                    mWindowManager.setAppFullscreen(token, false);
8644                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8645                    return true;
8646                }
8647                return false;
8648            }
8649        } finally {
8650            Binder.restoreCallingIdentity(origId);
8651        }
8652    }
8653
8654    @Override
8655    public void setImmersive(IBinder token, boolean immersive) {
8656        synchronized(this) {
8657            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8658            if (r == null) {
8659                throw new IllegalArgumentException();
8660            }
8661            r.immersive = immersive;
8662
8663            // update associated state if we're frontmost
8664            if (r == mFocusedActivity) {
8665                if (DEBUG_IMMERSIVE) {
8666                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8667                }
8668                applyUpdateLockStateLocked(r);
8669            }
8670        }
8671    }
8672
8673    @Override
8674    public boolean isImmersive(IBinder token) {
8675        synchronized (this) {
8676            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8677            if (r == null) {
8678                throw new IllegalArgumentException();
8679            }
8680            return r.immersive;
8681        }
8682    }
8683
8684    public boolean isTopActivityImmersive() {
8685        enforceNotIsolatedCaller("startActivity");
8686        synchronized (this) {
8687            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8688            return (r != null) ? r.immersive : false;
8689        }
8690    }
8691
8692    public final void enterSafeMode() {
8693        synchronized(this) {
8694            // It only makes sense to do this before the system is ready
8695            // and started launching other packages.
8696            if (!mSystemReady) {
8697                try {
8698                    AppGlobals.getPackageManager().enterSafeMode();
8699                } catch (RemoteException e) {
8700                }
8701            }
8702        }
8703    }
8704
8705    public final void showSafeModeOverlay() {
8706        View v = LayoutInflater.from(mContext).inflate(
8707                com.android.internal.R.layout.safe_mode, null);
8708        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8709        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8710        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8711        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8712        lp.gravity = Gravity.BOTTOM | Gravity.START;
8713        lp.format = v.getBackground().getOpacity();
8714        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8715                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8716        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8717        ((WindowManager)mContext.getSystemService(
8718                Context.WINDOW_SERVICE)).addView(v, lp);
8719    }
8720
8721    public void noteWakeupAlarm(IIntentSender sender) {
8722        if (!(sender instanceof PendingIntentRecord)) {
8723            return;
8724        }
8725        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8726        synchronized (stats) {
8727            if (mBatteryStatsService.isOnBattery()) {
8728                mBatteryStatsService.enforceCallingPermission();
8729                PendingIntentRecord rec = (PendingIntentRecord)sender;
8730                int MY_UID = Binder.getCallingUid();
8731                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8732                BatteryStatsImpl.Uid.Pkg pkg =
8733                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8734                pkg.incWakeupsLocked();
8735            }
8736        }
8737    }
8738
8739    public boolean killPids(int[] pids, String pReason, boolean secure) {
8740        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8741            throw new SecurityException("killPids only available to the system");
8742        }
8743        String reason = (pReason == null) ? "Unknown" : pReason;
8744        // XXX Note: don't acquire main activity lock here, because the window
8745        // manager calls in with its locks held.
8746
8747        boolean killed = false;
8748        synchronized (mPidsSelfLocked) {
8749            int[] types = new int[pids.length];
8750            int worstType = 0;
8751            for (int i=0; i<pids.length; i++) {
8752                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8753                if (proc != null) {
8754                    int type = proc.setAdj;
8755                    types[i] = type;
8756                    if (type > worstType) {
8757                        worstType = type;
8758                    }
8759                }
8760            }
8761
8762            // If the worst oom_adj is somewhere in the cached proc LRU range,
8763            // then constrain it so we will kill all cached procs.
8764            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8765                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8766                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8767            }
8768
8769            // If this is not a secure call, don't let it kill processes that
8770            // are important.
8771            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8772                worstType = ProcessList.SERVICE_ADJ;
8773            }
8774
8775            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8776            for (int i=0; i<pids.length; i++) {
8777                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8778                if (proc == null) {
8779                    continue;
8780                }
8781                int adj = proc.setAdj;
8782                if (adj >= worstType && !proc.killedByAm) {
8783                    killUnneededProcessLocked(proc, reason);
8784                    killed = true;
8785                }
8786            }
8787        }
8788        return killed;
8789    }
8790
8791    @Override
8792    public void killUid(int uid, String reason) {
8793        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8794            throw new SecurityException("killUid only available to the system");
8795        }
8796        synchronized (this) {
8797            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8798                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8799                    reason != null ? reason : "kill uid");
8800        }
8801    }
8802
8803    @Override
8804    public boolean killProcessesBelowForeground(String reason) {
8805        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8806            throw new SecurityException("killProcessesBelowForeground() only available to system");
8807        }
8808
8809        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8810    }
8811
8812    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8813        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8814            throw new SecurityException("killProcessesBelowAdj() only available to system");
8815        }
8816
8817        boolean killed = false;
8818        synchronized (mPidsSelfLocked) {
8819            final int size = mPidsSelfLocked.size();
8820            for (int i = 0; i < size; i++) {
8821                final int pid = mPidsSelfLocked.keyAt(i);
8822                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8823                if (proc == null) continue;
8824
8825                final int adj = proc.setAdj;
8826                if (adj > belowAdj && !proc.killedByAm) {
8827                    killUnneededProcessLocked(proc, reason);
8828                    killed = true;
8829                }
8830            }
8831        }
8832        return killed;
8833    }
8834
8835    @Override
8836    public void hang(final IBinder who, boolean allowRestart) {
8837        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8838                != PackageManager.PERMISSION_GRANTED) {
8839            throw new SecurityException("Requires permission "
8840                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8841        }
8842
8843        final IBinder.DeathRecipient death = new DeathRecipient() {
8844            @Override
8845            public void binderDied() {
8846                synchronized (this) {
8847                    notifyAll();
8848                }
8849            }
8850        };
8851
8852        try {
8853            who.linkToDeath(death, 0);
8854        } catch (RemoteException e) {
8855            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8856            return;
8857        }
8858
8859        synchronized (this) {
8860            Watchdog.getInstance().setAllowRestart(allowRestart);
8861            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8862            synchronized (death) {
8863                while (who.isBinderAlive()) {
8864                    try {
8865                        death.wait();
8866                    } catch (InterruptedException e) {
8867                    }
8868                }
8869            }
8870            Watchdog.getInstance().setAllowRestart(true);
8871        }
8872    }
8873
8874    @Override
8875    public void restart() {
8876        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8877                != PackageManager.PERMISSION_GRANTED) {
8878            throw new SecurityException("Requires permission "
8879                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8880        }
8881
8882        Log.i(TAG, "Sending shutdown broadcast...");
8883
8884        BroadcastReceiver br = new BroadcastReceiver() {
8885            @Override public void onReceive(Context context, Intent intent) {
8886                // Now the broadcast is done, finish up the low-level shutdown.
8887                Log.i(TAG, "Shutting down activity manager...");
8888                shutdown(10000);
8889                Log.i(TAG, "Shutdown complete, restarting!");
8890                Process.killProcess(Process.myPid());
8891                System.exit(10);
8892            }
8893        };
8894
8895        // First send the high-level shut down broadcast.
8896        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8897        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8898        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8899        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8900        mContext.sendOrderedBroadcastAsUser(intent,
8901                UserHandle.ALL, null, br, mHandler, 0, null, null);
8902        */
8903        br.onReceive(mContext, intent);
8904    }
8905
8906    private long getLowRamTimeSinceIdle(long now) {
8907        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8908    }
8909
8910    @Override
8911    public void performIdleMaintenance() {
8912        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8913                != PackageManager.PERMISSION_GRANTED) {
8914            throw new SecurityException("Requires permission "
8915                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8916        }
8917
8918        synchronized (this) {
8919            final long now = SystemClock.uptimeMillis();
8920            final long timeSinceLastIdle = now - mLastIdleTime;
8921            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8922            mLastIdleTime = now;
8923            mLowRamTimeSinceLastIdle = 0;
8924            if (mLowRamStartTime != 0) {
8925                mLowRamStartTime = now;
8926            }
8927
8928            StringBuilder sb = new StringBuilder(128);
8929            sb.append("Idle maintenance over ");
8930            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8931            sb.append(" low RAM for ");
8932            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8933            Slog.i(TAG, sb.toString());
8934
8935            // If at least 1/3 of our time since the last idle period has been spent
8936            // with RAM low, then we want to kill processes.
8937            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8938
8939            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8940                ProcessRecord proc = mLruProcesses.get(i);
8941                if (proc.notCachedSinceIdle) {
8942                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8943                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8944                        if (doKilling && proc.initialIdlePss != 0
8945                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8946                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8947                                    + " from " + proc.initialIdlePss + ")");
8948                        }
8949                    }
8950                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8951                    proc.notCachedSinceIdle = true;
8952                    proc.initialIdlePss = 0;
8953                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8954                            mSleeping, now);
8955                }
8956            }
8957
8958            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8959            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8960        }
8961    }
8962
8963    private void retrieveSettings() {
8964        final ContentResolver resolver = mContext.getContentResolver();
8965        String debugApp = Settings.Global.getString(
8966            resolver, Settings.Global.DEBUG_APP);
8967        boolean waitForDebugger = Settings.Global.getInt(
8968            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
8969        boolean alwaysFinishActivities = Settings.Global.getInt(
8970            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
8971        boolean forceRtl = Settings.Global.getInt(
8972                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
8973        // Transfer any global setting for forcing RTL layout, into a System Property
8974        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
8975
8976        Configuration configuration = new Configuration();
8977        Settings.System.getConfiguration(resolver, configuration);
8978        if (forceRtl) {
8979            // This will take care of setting the correct layout direction flags
8980            configuration.setLayoutDirection(configuration.locale);
8981        }
8982
8983        synchronized (this) {
8984            mDebugApp = mOrigDebugApp = debugApp;
8985            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
8986            mAlwaysFinishActivities = alwaysFinishActivities;
8987            // This happens before any activities are started, so we can
8988            // change mConfiguration in-place.
8989            updateConfigurationLocked(configuration, null, false, true);
8990            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
8991        }
8992    }
8993
8994    public boolean testIsSystemReady() {
8995        // no need to synchronize(this) just to read & return the value
8996        return mSystemReady;
8997    }
8998
8999    private static File getCalledPreBootReceiversFile() {
9000        File dataDir = Environment.getDataDirectory();
9001        File systemDir = new File(dataDir, "system");
9002        File fname = new File(systemDir, "called_pre_boots.dat");
9003        return fname;
9004    }
9005
9006    static final int LAST_DONE_VERSION = 10000;
9007
9008    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9009        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9010        File file = getCalledPreBootReceiversFile();
9011        FileInputStream fis = null;
9012        try {
9013            fis = new FileInputStream(file);
9014            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9015            int fvers = dis.readInt();
9016            if (fvers == LAST_DONE_VERSION) {
9017                String vers = dis.readUTF();
9018                String codename = dis.readUTF();
9019                String build = dis.readUTF();
9020                if (android.os.Build.VERSION.RELEASE.equals(vers)
9021                        && android.os.Build.VERSION.CODENAME.equals(codename)
9022                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9023                    int num = dis.readInt();
9024                    while (num > 0) {
9025                        num--;
9026                        String pkg = dis.readUTF();
9027                        String cls = dis.readUTF();
9028                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9029                    }
9030                }
9031            }
9032        } catch (FileNotFoundException e) {
9033        } catch (IOException e) {
9034            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9035        } finally {
9036            if (fis != null) {
9037                try {
9038                    fis.close();
9039                } catch (IOException e) {
9040                }
9041            }
9042        }
9043        return lastDoneReceivers;
9044    }
9045
9046    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9047        File file = getCalledPreBootReceiversFile();
9048        FileOutputStream fos = null;
9049        DataOutputStream dos = null;
9050        try {
9051            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9052            fos = new FileOutputStream(file);
9053            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9054            dos.writeInt(LAST_DONE_VERSION);
9055            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9056            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9057            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9058            dos.writeInt(list.size());
9059            for (int i=0; i<list.size(); i++) {
9060                dos.writeUTF(list.get(i).getPackageName());
9061                dos.writeUTF(list.get(i).getClassName());
9062            }
9063        } catch (IOException e) {
9064            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9065            file.delete();
9066        } finally {
9067            FileUtils.sync(fos);
9068            if (dos != null) {
9069                try {
9070                    dos.close();
9071                } catch (IOException e) {
9072                    // TODO Auto-generated catch block
9073                    e.printStackTrace();
9074                }
9075            }
9076        }
9077    }
9078
9079    public void systemReady(final Runnable goingCallback) {
9080        synchronized(this) {
9081            if (mSystemReady) {
9082                if (goingCallback != null) goingCallback.run();
9083                return;
9084            }
9085
9086            // Check to see if there are any update receivers to run.
9087            if (!mDidUpdate) {
9088                if (mWaitingUpdate) {
9089                    return;
9090                }
9091                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9092                List<ResolveInfo> ris = null;
9093                try {
9094                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9095                            intent, null, 0, 0);
9096                } catch (RemoteException e) {
9097                }
9098                if (ris != null) {
9099                    for (int i=ris.size()-1; i>=0; i--) {
9100                        if ((ris.get(i).activityInfo.applicationInfo.flags
9101                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9102                            ris.remove(i);
9103                        }
9104                    }
9105                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9106
9107                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9108
9109                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9110                    for (int i=0; i<ris.size(); i++) {
9111                        ActivityInfo ai = ris.get(i).activityInfo;
9112                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9113                        if (lastDoneReceivers.contains(comp)) {
9114                            // We already did the pre boot receiver for this app with the current
9115                            // platform version, so don't do it again...
9116                            ris.remove(i);
9117                            i--;
9118                            // ...however, do keep it as one that has been done, so we don't
9119                            // forget about it when rewriting the file of last done receivers.
9120                            doneReceivers.add(comp);
9121                        }
9122                    }
9123
9124                    final int[] users = getUsersLocked();
9125                    for (int i=0; i<ris.size(); i++) {
9126                        ActivityInfo ai = ris.get(i).activityInfo;
9127                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9128                        doneReceivers.add(comp);
9129                        intent.setComponent(comp);
9130                        for (int j=0; j<users.length; j++) {
9131                            IIntentReceiver finisher = null;
9132                            if (i == ris.size()-1 && j == users.length-1) {
9133                                finisher = new IIntentReceiver.Stub() {
9134                                    public void performReceive(Intent intent, int resultCode,
9135                                            String data, Bundle extras, boolean ordered,
9136                                            boolean sticky, int sendingUser) {
9137                                        // The raw IIntentReceiver interface is called
9138                                        // with the AM lock held, so redispatch to
9139                                        // execute our code without the lock.
9140                                        mHandler.post(new Runnable() {
9141                                            public void run() {
9142                                                synchronized (ActivityManagerService.this) {
9143                                                    mDidUpdate = true;
9144                                                }
9145                                                writeLastDonePreBootReceivers(doneReceivers);
9146                                                showBootMessage(mContext.getText(
9147                                                        R.string.android_upgrading_complete),
9148                                                        false);
9149                                                systemReady(goingCallback);
9150                                            }
9151                                        });
9152                                    }
9153                                };
9154                            }
9155                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9156                                    + " for user " + users[j]);
9157                            broadcastIntentLocked(null, null, intent, null, finisher,
9158                                    0, null, null, null, AppOpsManager.OP_NONE,
9159                                    true, false, MY_PID, Process.SYSTEM_UID,
9160                                    users[j]);
9161                            if (finisher != null) {
9162                                mWaitingUpdate = true;
9163                            }
9164                        }
9165                    }
9166                }
9167                if (mWaitingUpdate) {
9168                    return;
9169                }
9170                mDidUpdate = true;
9171            }
9172
9173            mAppOpsService.systemReady();
9174            mSystemReady = true;
9175        }
9176
9177        ArrayList<ProcessRecord> procsToKill = null;
9178        synchronized(mPidsSelfLocked) {
9179            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9180                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9181                if (!isAllowedWhileBooting(proc.info)){
9182                    if (procsToKill == null) {
9183                        procsToKill = new ArrayList<ProcessRecord>();
9184                    }
9185                    procsToKill.add(proc);
9186                }
9187            }
9188        }
9189
9190        synchronized(this) {
9191            if (procsToKill != null) {
9192                for (int i=procsToKill.size()-1; i>=0; i--) {
9193                    ProcessRecord proc = procsToKill.get(i);
9194                    Slog.i(TAG, "Removing system update proc: " + proc);
9195                    removeProcessLocked(proc, true, false, "system update done");
9196                }
9197            }
9198
9199            // Now that we have cleaned up any update processes, we
9200            // are ready to start launching real processes and know that
9201            // we won't trample on them any more.
9202            mProcessesReady = true;
9203        }
9204
9205        Slog.i(TAG, "System now ready");
9206        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9207            SystemClock.uptimeMillis());
9208
9209        synchronized(this) {
9210            // Make sure we have no pre-ready processes sitting around.
9211
9212            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9213                ResolveInfo ri = mContext.getPackageManager()
9214                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9215                                STOCK_PM_FLAGS);
9216                CharSequence errorMsg = null;
9217                if (ri != null) {
9218                    ActivityInfo ai = ri.activityInfo;
9219                    ApplicationInfo app = ai.applicationInfo;
9220                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9221                        mTopAction = Intent.ACTION_FACTORY_TEST;
9222                        mTopData = null;
9223                        mTopComponent = new ComponentName(app.packageName,
9224                                ai.name);
9225                    } else {
9226                        errorMsg = mContext.getResources().getText(
9227                                com.android.internal.R.string.factorytest_not_system);
9228                    }
9229                } else {
9230                    errorMsg = mContext.getResources().getText(
9231                            com.android.internal.R.string.factorytest_no_action);
9232                }
9233                if (errorMsg != null) {
9234                    mTopAction = null;
9235                    mTopData = null;
9236                    mTopComponent = null;
9237                    Message msg = Message.obtain();
9238                    msg.what = SHOW_FACTORY_ERROR_MSG;
9239                    msg.getData().putCharSequence("msg", errorMsg);
9240                    mHandler.sendMessage(msg);
9241                }
9242            }
9243        }
9244
9245        retrieveSettings();
9246
9247        synchronized (this) {
9248            readGrantedUriPermissionsLocked();
9249        }
9250
9251        if (goingCallback != null) goingCallback.run();
9252
9253        synchronized (this) {
9254            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9255                try {
9256                    List apps = AppGlobals.getPackageManager().
9257                        getPersistentApplications(STOCK_PM_FLAGS);
9258                    if (apps != null) {
9259                        int N = apps.size();
9260                        int i;
9261                        for (i=0; i<N; i++) {
9262                            ApplicationInfo info
9263                                = (ApplicationInfo)apps.get(i);
9264                            if (info != null &&
9265                                    !info.packageName.equals("android")) {
9266                                addAppLocked(info, false);
9267                            }
9268                        }
9269                    }
9270                } catch (RemoteException ex) {
9271                    // pm is in same process, this will never happen.
9272                }
9273            }
9274
9275            // Start up initial activity.
9276            mBooting = true;
9277
9278            try {
9279                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9280                    Message msg = Message.obtain();
9281                    msg.what = SHOW_UID_ERROR_MSG;
9282                    mHandler.sendMessage(msg);
9283                }
9284            } catch (RemoteException e) {
9285            }
9286
9287            long ident = Binder.clearCallingIdentity();
9288            try {
9289                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9290                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9291                        | Intent.FLAG_RECEIVER_FOREGROUND);
9292                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9293                broadcastIntentLocked(null, null, intent,
9294                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9295                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9296                intent = new Intent(Intent.ACTION_USER_STARTING);
9297                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9298                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9299                broadcastIntentLocked(null, null, intent,
9300                        null, new IIntentReceiver.Stub() {
9301                            @Override
9302                            public void performReceive(Intent intent, int resultCode, String data,
9303                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9304                                    throws RemoteException {
9305                            }
9306                        }, 0, null, null,
9307                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9308                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9309            } finally {
9310                Binder.restoreCallingIdentity(ident);
9311            }
9312            mStackSupervisor.resumeTopActivitiesLocked();
9313            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9314        }
9315    }
9316
9317    private boolean makeAppCrashingLocked(ProcessRecord app,
9318            String shortMsg, String longMsg, String stackTrace) {
9319        app.crashing = true;
9320        app.crashingReport = generateProcessError(app,
9321                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9322        startAppProblemLocked(app);
9323        app.stopFreezingAllLocked();
9324        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9325    }
9326
9327    private void makeAppNotRespondingLocked(ProcessRecord app,
9328            String activity, String shortMsg, String longMsg) {
9329        app.notResponding = true;
9330        app.notRespondingReport = generateProcessError(app,
9331                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9332                activity, shortMsg, longMsg, null);
9333        startAppProblemLocked(app);
9334        app.stopFreezingAllLocked();
9335    }
9336
9337    /**
9338     * Generate a process error record, suitable for attachment to a ProcessRecord.
9339     *
9340     * @param app The ProcessRecord in which the error occurred.
9341     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9342     *                      ActivityManager.AppErrorStateInfo
9343     * @param activity The activity associated with the crash, if known.
9344     * @param shortMsg Short message describing the crash.
9345     * @param longMsg Long message describing the crash.
9346     * @param stackTrace Full crash stack trace, may be null.
9347     *
9348     * @return Returns a fully-formed AppErrorStateInfo record.
9349     */
9350    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9351            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9352        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9353
9354        report.condition = condition;
9355        report.processName = app.processName;
9356        report.pid = app.pid;
9357        report.uid = app.info.uid;
9358        report.tag = activity;
9359        report.shortMsg = shortMsg;
9360        report.longMsg = longMsg;
9361        report.stackTrace = stackTrace;
9362
9363        return report;
9364    }
9365
9366    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9367        synchronized (this) {
9368            app.crashing = false;
9369            app.crashingReport = null;
9370            app.notResponding = false;
9371            app.notRespondingReport = null;
9372            if (app.anrDialog == fromDialog) {
9373                app.anrDialog = null;
9374            }
9375            if (app.waitDialog == fromDialog) {
9376                app.waitDialog = null;
9377            }
9378            if (app.pid > 0 && app.pid != MY_PID) {
9379                handleAppCrashLocked(app, null, null, null);
9380                killUnneededProcessLocked(app, "user request after error");
9381            }
9382        }
9383    }
9384
9385    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9386            String stackTrace) {
9387        long now = SystemClock.uptimeMillis();
9388
9389        Long crashTime;
9390        if (!app.isolated) {
9391            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9392        } else {
9393            crashTime = null;
9394        }
9395        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9396            // This process loses!
9397            Slog.w(TAG, "Process " + app.info.processName
9398                    + " has crashed too many times: killing!");
9399            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9400                    app.userId, app.info.processName, app.uid);
9401            mStackSupervisor.handleAppCrashLocked(app);
9402            if (!app.persistent) {
9403                // We don't want to start this process again until the user
9404                // explicitly does so...  but for persistent process, we really
9405                // need to keep it running.  If a persistent process is actually
9406                // repeatedly crashing, then badness for everyone.
9407                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9408                        app.info.processName);
9409                if (!app.isolated) {
9410                    // XXX We don't have a way to mark isolated processes
9411                    // as bad, since they don't have a peristent identity.
9412                    mBadProcesses.put(app.info.processName, app.uid,
9413                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9414                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9415                }
9416                app.bad = true;
9417                app.removed = true;
9418                // Don't let services in this process be restarted and potentially
9419                // annoy the user repeatedly.  Unless it is persistent, since those
9420                // processes run critical code.
9421                removeProcessLocked(app, false, false, "crash");
9422                mStackSupervisor.resumeTopActivitiesLocked();
9423                return false;
9424            }
9425            mStackSupervisor.resumeTopActivitiesLocked();
9426        } else {
9427            mStackSupervisor.finishTopRunningActivityLocked(app);
9428        }
9429
9430        // Bump up the crash count of any services currently running in the proc.
9431        for (int i=app.services.size()-1; i>=0; i--) {
9432            // Any services running in the application need to be placed
9433            // back in the pending list.
9434            ServiceRecord sr = app.services.valueAt(i);
9435            sr.crashCount++;
9436        }
9437
9438        // If the crashing process is what we consider to be the "home process" and it has been
9439        // replaced by a third-party app, clear the package preferred activities from packages
9440        // with a home activity running in the process to prevent a repeatedly crashing app
9441        // from blocking the user to manually clear the list.
9442        final ArrayList<ActivityRecord> activities = app.activities;
9443        if (app == mHomeProcess && activities.size() > 0
9444                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9445            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9446                final ActivityRecord r = activities.get(activityNdx);
9447                if (r.isHomeActivity()) {
9448                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9449                    try {
9450                        ActivityThread.getPackageManager()
9451                                .clearPackagePreferredActivities(r.packageName);
9452                    } catch (RemoteException c) {
9453                        // pm is in same process, this will never happen.
9454                    }
9455                }
9456            }
9457        }
9458
9459        if (!app.isolated) {
9460            // XXX Can't keep track of crash times for isolated processes,
9461            // because they don't have a perisistent identity.
9462            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9463        }
9464
9465        return true;
9466    }
9467
9468    void startAppProblemLocked(ProcessRecord app) {
9469        if (app.userId == mCurrentUserId) {
9470            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9471                    mContext, app.info.packageName, app.info.flags);
9472        } else {
9473            // If this app is not running under the current user, then we
9474            // can't give it a report button because that would require
9475            // launching the report UI under a different user.
9476            app.errorReportReceiver = null;
9477        }
9478        skipCurrentReceiverLocked(app);
9479    }
9480
9481    void skipCurrentReceiverLocked(ProcessRecord app) {
9482        for (BroadcastQueue queue : mBroadcastQueues) {
9483            queue.skipCurrentReceiverLocked(app);
9484        }
9485    }
9486
9487    /**
9488     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9489     * The application process will exit immediately after this call returns.
9490     * @param app object of the crashing app, null for the system server
9491     * @param crashInfo describing the exception
9492     */
9493    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9494        ProcessRecord r = findAppProcess(app, "Crash");
9495        final String processName = app == null ? "system_server"
9496                : (r == null ? "unknown" : r.processName);
9497
9498        handleApplicationCrashInner("crash", r, processName, crashInfo);
9499    }
9500
9501    /* Native crash reporting uses this inner version because it needs to be somewhat
9502     * decoupled from the AM-managed cleanup lifecycle
9503     */
9504    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9505            ApplicationErrorReport.CrashInfo crashInfo) {
9506        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9507                UserHandle.getUserId(Binder.getCallingUid()), processName,
9508                r == null ? -1 : r.info.flags,
9509                crashInfo.exceptionClassName,
9510                crashInfo.exceptionMessage,
9511                crashInfo.throwFileName,
9512                crashInfo.throwLineNumber);
9513
9514        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9515
9516        crashApplication(r, crashInfo);
9517    }
9518
9519    public void handleApplicationStrictModeViolation(
9520            IBinder app,
9521            int violationMask,
9522            StrictMode.ViolationInfo info) {
9523        ProcessRecord r = findAppProcess(app, "StrictMode");
9524        if (r == null) {
9525            return;
9526        }
9527
9528        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9529            Integer stackFingerprint = info.hashCode();
9530            boolean logIt = true;
9531            synchronized (mAlreadyLoggedViolatedStacks) {
9532                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9533                    logIt = false;
9534                    // TODO: sub-sample into EventLog for these, with
9535                    // the info.durationMillis?  Then we'd get
9536                    // the relative pain numbers, without logging all
9537                    // the stack traces repeatedly.  We'd want to do
9538                    // likewise in the client code, which also does
9539                    // dup suppression, before the Binder call.
9540                } else {
9541                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9542                        mAlreadyLoggedViolatedStacks.clear();
9543                    }
9544                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9545                }
9546            }
9547            if (logIt) {
9548                logStrictModeViolationToDropBox(r, info);
9549            }
9550        }
9551
9552        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9553            AppErrorResult result = new AppErrorResult();
9554            synchronized (this) {
9555                final long origId = Binder.clearCallingIdentity();
9556
9557                Message msg = Message.obtain();
9558                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9559                HashMap<String, Object> data = new HashMap<String, Object>();
9560                data.put("result", result);
9561                data.put("app", r);
9562                data.put("violationMask", violationMask);
9563                data.put("info", info);
9564                msg.obj = data;
9565                mHandler.sendMessage(msg);
9566
9567                Binder.restoreCallingIdentity(origId);
9568            }
9569            int res = result.get();
9570            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9571        }
9572    }
9573
9574    // Depending on the policy in effect, there could be a bunch of
9575    // these in quick succession so we try to batch these together to
9576    // minimize disk writes, number of dropbox entries, and maximize
9577    // compression, by having more fewer, larger records.
9578    private void logStrictModeViolationToDropBox(
9579            ProcessRecord process,
9580            StrictMode.ViolationInfo info) {
9581        if (info == null) {
9582            return;
9583        }
9584        final boolean isSystemApp = process == null ||
9585                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9586                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9587        final String processName = process == null ? "unknown" : process.processName;
9588        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9589        final DropBoxManager dbox = (DropBoxManager)
9590                mContext.getSystemService(Context.DROPBOX_SERVICE);
9591
9592        // Exit early if the dropbox isn't configured to accept this report type.
9593        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9594
9595        boolean bufferWasEmpty;
9596        boolean needsFlush;
9597        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9598        synchronized (sb) {
9599            bufferWasEmpty = sb.length() == 0;
9600            appendDropBoxProcessHeaders(process, processName, sb);
9601            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9602            sb.append("System-App: ").append(isSystemApp).append("\n");
9603            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9604            if (info.violationNumThisLoop != 0) {
9605                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9606            }
9607            if (info.numAnimationsRunning != 0) {
9608                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9609            }
9610            if (info.broadcastIntentAction != null) {
9611                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9612            }
9613            if (info.durationMillis != -1) {
9614                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9615            }
9616            if (info.numInstances != -1) {
9617                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9618            }
9619            if (info.tags != null) {
9620                for (String tag : info.tags) {
9621                    sb.append("Span-Tag: ").append(tag).append("\n");
9622                }
9623            }
9624            sb.append("\n");
9625            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9626                sb.append(info.crashInfo.stackTrace);
9627            }
9628            sb.append("\n");
9629
9630            // Only buffer up to ~64k.  Various logging bits truncate
9631            // things at 128k.
9632            needsFlush = (sb.length() > 64 * 1024);
9633        }
9634
9635        // Flush immediately if the buffer's grown too large, or this
9636        // is a non-system app.  Non-system apps are isolated with a
9637        // different tag & policy and not batched.
9638        //
9639        // Batching is useful during internal testing with
9640        // StrictMode settings turned up high.  Without batching,
9641        // thousands of separate files could be created on boot.
9642        if (!isSystemApp || needsFlush) {
9643            new Thread("Error dump: " + dropboxTag) {
9644                @Override
9645                public void run() {
9646                    String report;
9647                    synchronized (sb) {
9648                        report = sb.toString();
9649                        sb.delete(0, sb.length());
9650                        sb.trimToSize();
9651                    }
9652                    if (report.length() != 0) {
9653                        dbox.addText(dropboxTag, report);
9654                    }
9655                }
9656            }.start();
9657            return;
9658        }
9659
9660        // System app batching:
9661        if (!bufferWasEmpty) {
9662            // An existing dropbox-writing thread is outstanding, so
9663            // we don't need to start it up.  The existing thread will
9664            // catch the buffer appends we just did.
9665            return;
9666        }
9667
9668        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9669        // (After this point, we shouldn't access AMS internal data structures.)
9670        new Thread("Error dump: " + dropboxTag) {
9671            @Override
9672            public void run() {
9673                // 5 second sleep to let stacks arrive and be batched together
9674                try {
9675                    Thread.sleep(5000);  // 5 seconds
9676                } catch (InterruptedException e) {}
9677
9678                String errorReport;
9679                synchronized (mStrictModeBuffer) {
9680                    errorReport = mStrictModeBuffer.toString();
9681                    if (errorReport.length() == 0) {
9682                        return;
9683                    }
9684                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9685                    mStrictModeBuffer.trimToSize();
9686                }
9687                dbox.addText(dropboxTag, errorReport);
9688            }
9689        }.start();
9690    }
9691
9692    /**
9693     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9694     * @param app object of the crashing app, null for the system server
9695     * @param tag reported by the caller
9696     * @param crashInfo describing the context of the error
9697     * @return true if the process should exit immediately (WTF is fatal)
9698     */
9699    public boolean handleApplicationWtf(IBinder app, String tag,
9700            ApplicationErrorReport.CrashInfo crashInfo) {
9701        ProcessRecord r = findAppProcess(app, "WTF");
9702        final String processName = app == null ? "system_server"
9703                : (r == null ? "unknown" : r.processName);
9704
9705        EventLog.writeEvent(EventLogTags.AM_WTF,
9706                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9707                processName,
9708                r == null ? -1 : r.info.flags,
9709                tag, crashInfo.exceptionMessage);
9710
9711        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9712
9713        if (r != null && r.pid != Process.myPid() &&
9714                Settings.Global.getInt(mContext.getContentResolver(),
9715                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9716            crashApplication(r, crashInfo);
9717            return true;
9718        } else {
9719            return false;
9720        }
9721    }
9722
9723    /**
9724     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9725     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9726     */
9727    private ProcessRecord findAppProcess(IBinder app, String reason) {
9728        if (app == null) {
9729            return null;
9730        }
9731
9732        synchronized (this) {
9733            final int NP = mProcessNames.getMap().size();
9734            for (int ip=0; ip<NP; ip++) {
9735                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9736                final int NA = apps.size();
9737                for (int ia=0; ia<NA; ia++) {
9738                    ProcessRecord p = apps.valueAt(ia);
9739                    if (p.thread != null && p.thread.asBinder() == app) {
9740                        return p;
9741                    }
9742                }
9743            }
9744
9745            Slog.w(TAG, "Can't find mystery application for " + reason
9746                    + " from pid=" + Binder.getCallingPid()
9747                    + " uid=" + Binder.getCallingUid() + ": " + app);
9748            return null;
9749        }
9750    }
9751
9752    /**
9753     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9754     * to append various headers to the dropbox log text.
9755     */
9756    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9757            StringBuilder sb) {
9758        // Watchdog thread ends up invoking this function (with
9759        // a null ProcessRecord) to add the stack file to dropbox.
9760        // Do not acquire a lock on this (am) in such cases, as it
9761        // could cause a potential deadlock, if and when watchdog
9762        // is invoked due to unavailability of lock on am and it
9763        // would prevent watchdog from killing system_server.
9764        if (process == null) {
9765            sb.append("Process: ").append(processName).append("\n");
9766            return;
9767        }
9768        // Note: ProcessRecord 'process' is guarded by the service
9769        // instance.  (notably process.pkgList, which could otherwise change
9770        // concurrently during execution of this method)
9771        synchronized (this) {
9772            sb.append("Process: ").append(processName).append("\n");
9773            int flags = process.info.flags;
9774            IPackageManager pm = AppGlobals.getPackageManager();
9775            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9776            for (int ip=0; ip<process.pkgList.size(); ip++) {
9777                String pkg = process.pkgList.keyAt(ip);
9778                sb.append("Package: ").append(pkg);
9779                try {
9780                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9781                    if (pi != null) {
9782                        sb.append(" v").append(pi.versionCode);
9783                        if (pi.versionName != null) {
9784                            sb.append(" (").append(pi.versionName).append(")");
9785                        }
9786                    }
9787                } catch (RemoteException e) {
9788                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9789                }
9790                sb.append("\n");
9791            }
9792        }
9793    }
9794
9795    private static String processClass(ProcessRecord process) {
9796        if (process == null || process.pid == MY_PID) {
9797            return "system_server";
9798        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9799            return "system_app";
9800        } else {
9801            return "data_app";
9802        }
9803    }
9804
9805    /**
9806     * Write a description of an error (crash, WTF, ANR) to the drop box.
9807     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9808     * @param process which caused the error, null means the system server
9809     * @param activity which triggered the error, null if unknown
9810     * @param parent activity related to the error, null if unknown
9811     * @param subject line related to the error, null if absent
9812     * @param report in long form describing the error, null if absent
9813     * @param logFile to include in the report, null if none
9814     * @param crashInfo giving an application stack trace, null if absent
9815     */
9816    public void addErrorToDropBox(String eventType,
9817            ProcessRecord process, String processName, ActivityRecord activity,
9818            ActivityRecord parent, String subject,
9819            final String report, final File logFile,
9820            final ApplicationErrorReport.CrashInfo crashInfo) {
9821        // NOTE -- this must never acquire the ActivityManagerService lock,
9822        // otherwise the watchdog may be prevented from resetting the system.
9823
9824        final String dropboxTag = processClass(process) + "_" + eventType;
9825        final DropBoxManager dbox = (DropBoxManager)
9826                mContext.getSystemService(Context.DROPBOX_SERVICE);
9827
9828        // Exit early if the dropbox isn't configured to accept this report type.
9829        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9830
9831        final StringBuilder sb = new StringBuilder(1024);
9832        appendDropBoxProcessHeaders(process, processName, sb);
9833        if (activity != null) {
9834            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9835        }
9836        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9837            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9838        }
9839        if (parent != null && parent != activity) {
9840            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9841        }
9842        if (subject != null) {
9843            sb.append("Subject: ").append(subject).append("\n");
9844        }
9845        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9846        if (Debug.isDebuggerConnected()) {
9847            sb.append("Debugger: Connected\n");
9848        }
9849        sb.append("\n");
9850
9851        // Do the rest in a worker thread to avoid blocking the caller on I/O
9852        // (After this point, we shouldn't access AMS internal data structures.)
9853        Thread worker = new Thread("Error dump: " + dropboxTag) {
9854            @Override
9855            public void run() {
9856                if (report != null) {
9857                    sb.append(report);
9858                }
9859                if (logFile != null) {
9860                    try {
9861                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9862                                    "\n\n[[TRUNCATED]]"));
9863                    } catch (IOException e) {
9864                        Slog.e(TAG, "Error reading " + logFile, e);
9865                    }
9866                }
9867                if (crashInfo != null && crashInfo.stackTrace != null) {
9868                    sb.append(crashInfo.stackTrace);
9869                }
9870
9871                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9872                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9873                if (lines > 0) {
9874                    sb.append("\n");
9875
9876                    // Merge several logcat streams, and take the last N lines
9877                    InputStreamReader input = null;
9878                    try {
9879                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9880                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9881                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9882
9883                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9884                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9885                        input = new InputStreamReader(logcat.getInputStream());
9886
9887                        int num;
9888                        char[] buf = new char[8192];
9889                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9890                    } catch (IOException e) {
9891                        Slog.e(TAG, "Error running logcat", e);
9892                    } finally {
9893                        if (input != null) try { input.close(); } catch (IOException e) {}
9894                    }
9895                }
9896
9897                dbox.addText(dropboxTag, sb.toString());
9898            }
9899        };
9900
9901        if (process == null) {
9902            // If process is null, we are being called from some internal code
9903            // and may be about to die -- run this synchronously.
9904            worker.run();
9905        } else {
9906            worker.start();
9907        }
9908    }
9909
9910    /**
9911     * Bring up the "unexpected error" dialog box for a crashing app.
9912     * Deal with edge cases (intercepts from instrumented applications,
9913     * ActivityController, error intent receivers, that sort of thing).
9914     * @param r the application crashing
9915     * @param crashInfo describing the failure
9916     */
9917    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9918        long timeMillis = System.currentTimeMillis();
9919        String shortMsg = crashInfo.exceptionClassName;
9920        String longMsg = crashInfo.exceptionMessage;
9921        String stackTrace = crashInfo.stackTrace;
9922        if (shortMsg != null && longMsg != null) {
9923            longMsg = shortMsg + ": " + longMsg;
9924        } else if (shortMsg != null) {
9925            longMsg = shortMsg;
9926        }
9927
9928        AppErrorResult result = new AppErrorResult();
9929        synchronized (this) {
9930            if (mController != null) {
9931                try {
9932                    String name = r != null ? r.processName : null;
9933                    int pid = r != null ? r.pid : Binder.getCallingPid();
9934                    if (!mController.appCrashed(name, pid,
9935                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9936                        Slog.w(TAG, "Force-killing crashed app " + name
9937                                + " at watcher's request");
9938                        Process.killProcess(pid);
9939                        return;
9940                    }
9941                } catch (RemoteException e) {
9942                    mController = null;
9943                    Watchdog.getInstance().setActivityController(null);
9944                }
9945            }
9946
9947            final long origId = Binder.clearCallingIdentity();
9948
9949            // If this process is running instrumentation, finish it.
9950            if (r != null && r.instrumentationClass != null) {
9951                Slog.w(TAG, "Error in app " + r.processName
9952                      + " running instrumentation " + r.instrumentationClass + ":");
9953                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
9954                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
9955                Bundle info = new Bundle();
9956                info.putString("shortMsg", shortMsg);
9957                info.putString("longMsg", longMsg);
9958                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
9959                Binder.restoreCallingIdentity(origId);
9960                return;
9961            }
9962
9963            // If we can't identify the process or it's already exceeded its crash quota,
9964            // quit right away without showing a crash dialog.
9965            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
9966                Binder.restoreCallingIdentity(origId);
9967                return;
9968            }
9969
9970            Message msg = Message.obtain();
9971            msg.what = SHOW_ERROR_MSG;
9972            HashMap data = new HashMap();
9973            data.put("result", result);
9974            data.put("app", r);
9975            msg.obj = data;
9976            mHandler.sendMessage(msg);
9977
9978            Binder.restoreCallingIdentity(origId);
9979        }
9980
9981        int res = result.get();
9982
9983        Intent appErrorIntent = null;
9984        synchronized (this) {
9985            if (r != null && !r.isolated) {
9986                // XXX Can't keep track of crash time for isolated processes,
9987                // since they don't have a persistent identity.
9988                mProcessCrashTimes.put(r.info.processName, r.uid,
9989                        SystemClock.uptimeMillis());
9990            }
9991            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
9992                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
9993            }
9994        }
9995
9996        if (appErrorIntent != null) {
9997            try {
9998                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
9999            } catch (ActivityNotFoundException e) {
10000                Slog.w(TAG, "bug report receiver dissappeared", e);
10001            }
10002        }
10003    }
10004
10005    Intent createAppErrorIntentLocked(ProcessRecord r,
10006            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10007        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10008        if (report == null) {
10009            return null;
10010        }
10011        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10012        result.setComponent(r.errorReportReceiver);
10013        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10014        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10015        return result;
10016    }
10017
10018    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10019            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10020        if (r.errorReportReceiver == null) {
10021            return null;
10022        }
10023
10024        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10025            return null;
10026        }
10027
10028        ApplicationErrorReport report = new ApplicationErrorReport();
10029        report.packageName = r.info.packageName;
10030        report.installerPackageName = r.errorReportReceiver.getPackageName();
10031        report.processName = r.processName;
10032        report.time = timeMillis;
10033        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10034
10035        if (r.crashing || r.forceCrashReport) {
10036            report.type = ApplicationErrorReport.TYPE_CRASH;
10037            report.crashInfo = crashInfo;
10038        } else if (r.notResponding) {
10039            report.type = ApplicationErrorReport.TYPE_ANR;
10040            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10041
10042            report.anrInfo.activity = r.notRespondingReport.tag;
10043            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10044            report.anrInfo.info = r.notRespondingReport.longMsg;
10045        }
10046
10047        return report;
10048    }
10049
10050    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10051        enforceNotIsolatedCaller("getProcessesInErrorState");
10052        // assume our apps are happy - lazy create the list
10053        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10054
10055        final boolean allUsers = ActivityManager.checkUidPermission(
10056                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10057                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10058        int userId = UserHandle.getUserId(Binder.getCallingUid());
10059
10060        synchronized (this) {
10061
10062            // iterate across all processes
10063            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10064                ProcessRecord app = mLruProcesses.get(i);
10065                if (!allUsers && app.userId != userId) {
10066                    continue;
10067                }
10068                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10069                    // This one's in trouble, so we'll generate a report for it
10070                    // crashes are higher priority (in case there's a crash *and* an anr)
10071                    ActivityManager.ProcessErrorStateInfo report = null;
10072                    if (app.crashing) {
10073                        report = app.crashingReport;
10074                    } else if (app.notResponding) {
10075                        report = app.notRespondingReport;
10076                    }
10077
10078                    if (report != null) {
10079                        if (errList == null) {
10080                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10081                        }
10082                        errList.add(report);
10083                    } else {
10084                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10085                                " crashing = " + app.crashing +
10086                                " notResponding = " + app.notResponding);
10087                    }
10088                }
10089            }
10090        }
10091
10092        return errList;
10093    }
10094
10095    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10096        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10097            if (currApp != null) {
10098                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10099            }
10100            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10101        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10102            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10103        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10104            if (currApp != null) {
10105                currApp.lru = 0;
10106            }
10107            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10108        } else if (adj >= ProcessList.SERVICE_ADJ) {
10109            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10110        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10111            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10112        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10113            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10114        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10115            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10116        } else {
10117            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10118        }
10119    }
10120
10121    private void fillInProcMemInfo(ProcessRecord app,
10122            ActivityManager.RunningAppProcessInfo outInfo) {
10123        outInfo.pid = app.pid;
10124        outInfo.uid = app.info.uid;
10125        if (mHeavyWeightProcess == app) {
10126            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10127        }
10128        if (app.persistent) {
10129            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10130        }
10131        if (app.activities.size() > 0) {
10132            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10133        }
10134        outInfo.lastTrimLevel = app.trimMemoryLevel;
10135        int adj = app.curAdj;
10136        outInfo.importance = oomAdjToImportance(adj, outInfo);
10137        outInfo.importanceReasonCode = app.adjTypeCode;
10138    }
10139
10140    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10141        enforceNotIsolatedCaller("getRunningAppProcesses");
10142        // Lazy instantiation of list
10143        List<ActivityManager.RunningAppProcessInfo> runList = null;
10144        final boolean allUsers = ActivityManager.checkUidPermission(
10145                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10146                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10147        int userId = UserHandle.getUserId(Binder.getCallingUid());
10148        synchronized (this) {
10149            // Iterate across all processes
10150            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10151                ProcessRecord app = mLruProcesses.get(i);
10152                if (!allUsers && app.userId != userId) {
10153                    continue;
10154                }
10155                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10156                    // Generate process state info for running application
10157                    ActivityManager.RunningAppProcessInfo currApp =
10158                        new ActivityManager.RunningAppProcessInfo(app.processName,
10159                                app.pid, app.getPackageList());
10160                    fillInProcMemInfo(app, currApp);
10161                    if (app.adjSource instanceof ProcessRecord) {
10162                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10163                        currApp.importanceReasonImportance = oomAdjToImportance(
10164                                app.adjSourceOom, null);
10165                    } else if (app.adjSource instanceof ActivityRecord) {
10166                        ActivityRecord r = (ActivityRecord)app.adjSource;
10167                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10168                    }
10169                    if (app.adjTarget instanceof ComponentName) {
10170                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10171                    }
10172                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10173                    //        + " lru=" + currApp.lru);
10174                    if (runList == null) {
10175                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10176                    }
10177                    runList.add(currApp);
10178                }
10179            }
10180        }
10181        return runList;
10182    }
10183
10184    public List<ApplicationInfo> getRunningExternalApplications() {
10185        enforceNotIsolatedCaller("getRunningExternalApplications");
10186        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10187        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10188        if (runningApps != null && runningApps.size() > 0) {
10189            Set<String> extList = new HashSet<String>();
10190            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10191                if (app.pkgList != null) {
10192                    for (String pkg : app.pkgList) {
10193                        extList.add(pkg);
10194                    }
10195                }
10196            }
10197            IPackageManager pm = AppGlobals.getPackageManager();
10198            for (String pkg : extList) {
10199                try {
10200                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10201                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10202                        retList.add(info);
10203                    }
10204                } catch (RemoteException e) {
10205                }
10206            }
10207        }
10208        return retList;
10209    }
10210
10211    @Override
10212    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10213        enforceNotIsolatedCaller("getMyMemoryState");
10214        synchronized (this) {
10215            ProcessRecord proc;
10216            synchronized (mPidsSelfLocked) {
10217                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10218            }
10219            fillInProcMemInfo(proc, outInfo);
10220        }
10221    }
10222
10223    @Override
10224    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10225        if (checkCallingPermission(android.Manifest.permission.DUMP)
10226                != PackageManager.PERMISSION_GRANTED) {
10227            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10228                    + Binder.getCallingPid()
10229                    + ", uid=" + Binder.getCallingUid()
10230                    + " without permission "
10231                    + android.Manifest.permission.DUMP);
10232            return;
10233        }
10234
10235        boolean dumpAll = false;
10236        boolean dumpClient = false;
10237        String dumpPackage = null;
10238
10239        int opti = 0;
10240        while (opti < args.length) {
10241            String opt = args[opti];
10242            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10243                break;
10244            }
10245            opti++;
10246            if ("-a".equals(opt)) {
10247                dumpAll = true;
10248            } else if ("-c".equals(opt)) {
10249                dumpClient = true;
10250            } else if ("-h".equals(opt)) {
10251                pw.println("Activity manager dump options:");
10252                pw.println("  [-a] [-c] [-h] [cmd] ...");
10253                pw.println("  cmd may be one of:");
10254                pw.println("    a[ctivities]: activity stack state");
10255                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10256                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10257                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10258                pw.println("    o[om]: out of memory management");
10259                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10260                pw.println("    provider [COMP_SPEC]: provider client-side state");
10261                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10262                pw.println("    service [COMP_SPEC]: service client-side state");
10263                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10264                pw.println("    all: dump all activities");
10265                pw.println("    top: dump the top activity");
10266                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10267                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10268                pw.println("    a partial substring in a component name, a");
10269                pw.println("    hex object identifier.");
10270                pw.println("  -a: include all available server state.");
10271                pw.println("  -c: include client state.");
10272                return;
10273            } else {
10274                pw.println("Unknown argument: " + opt + "; use -h for help");
10275            }
10276        }
10277
10278        long origId = Binder.clearCallingIdentity();
10279        boolean more = false;
10280        // Is the caller requesting to dump a particular piece of data?
10281        if (opti < args.length) {
10282            String cmd = args[opti];
10283            opti++;
10284            if ("activities".equals(cmd) || "a".equals(cmd)) {
10285                synchronized (this) {
10286                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10287                }
10288            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10289                String[] newArgs;
10290                String name;
10291                if (opti >= args.length) {
10292                    name = null;
10293                    newArgs = EMPTY_STRING_ARRAY;
10294                } else {
10295                    name = args[opti];
10296                    opti++;
10297                    newArgs = new String[args.length - opti];
10298                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10299                            args.length - opti);
10300                }
10301                synchronized (this) {
10302                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10303                }
10304            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10305                String[] newArgs;
10306                String name;
10307                if (opti >= args.length) {
10308                    name = null;
10309                    newArgs = EMPTY_STRING_ARRAY;
10310                } else {
10311                    name = args[opti];
10312                    opti++;
10313                    newArgs = new String[args.length - opti];
10314                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10315                            args.length - opti);
10316                }
10317                synchronized (this) {
10318                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10319                }
10320            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10321                String[] newArgs;
10322                String name;
10323                if (opti >= args.length) {
10324                    name = null;
10325                    newArgs = EMPTY_STRING_ARRAY;
10326                } else {
10327                    name = args[opti];
10328                    opti++;
10329                    newArgs = new String[args.length - opti];
10330                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10331                            args.length - opti);
10332                }
10333                synchronized (this) {
10334                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10335                }
10336            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10337                synchronized (this) {
10338                    dumpOomLocked(fd, pw, args, opti, true);
10339                }
10340            } else if ("provider".equals(cmd)) {
10341                String[] newArgs;
10342                String name;
10343                if (opti >= args.length) {
10344                    name = null;
10345                    newArgs = EMPTY_STRING_ARRAY;
10346                } else {
10347                    name = args[opti];
10348                    opti++;
10349                    newArgs = new String[args.length - opti];
10350                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10351                }
10352                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10353                    pw.println("No providers match: " + name);
10354                    pw.println("Use -h for help.");
10355                }
10356            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10357                synchronized (this) {
10358                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10359                }
10360            } else if ("service".equals(cmd)) {
10361                String[] newArgs;
10362                String name;
10363                if (opti >= args.length) {
10364                    name = null;
10365                    newArgs = EMPTY_STRING_ARRAY;
10366                } else {
10367                    name = args[opti];
10368                    opti++;
10369                    newArgs = new String[args.length - opti];
10370                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10371                            args.length - opti);
10372                }
10373                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10374                    pw.println("No services match: " + name);
10375                    pw.println("Use -h for help.");
10376                }
10377            } else if ("package".equals(cmd)) {
10378                String[] newArgs;
10379                if (opti >= args.length) {
10380                    pw.println("package: no package name specified");
10381                    pw.println("Use -h for help.");
10382                } else {
10383                    dumpPackage = args[opti];
10384                    opti++;
10385                    newArgs = new String[args.length - opti];
10386                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10387                            args.length - opti);
10388                    args = newArgs;
10389                    opti = 0;
10390                    more = true;
10391                }
10392            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10393                synchronized (this) {
10394                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10395                }
10396            } else {
10397                // Dumping a single activity?
10398                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10399                    pw.println("Bad activity command, or no activities match: " + cmd);
10400                    pw.println("Use -h for help.");
10401                }
10402            }
10403            if (!more) {
10404                Binder.restoreCallingIdentity(origId);
10405                return;
10406            }
10407        }
10408
10409        // No piece of data specified, dump everything.
10410        synchronized (this) {
10411            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10412            pw.println();
10413            if (dumpAll) {
10414                pw.println("-------------------------------------------------------------------------------");
10415            }
10416            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10417            pw.println();
10418            if (dumpAll) {
10419                pw.println("-------------------------------------------------------------------------------");
10420            }
10421            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10422            pw.println();
10423            if (dumpAll) {
10424                pw.println("-------------------------------------------------------------------------------");
10425            }
10426            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10427            pw.println();
10428            if (dumpAll) {
10429                pw.println("-------------------------------------------------------------------------------");
10430            }
10431            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10432            pw.println();
10433            if (dumpAll) {
10434                pw.println("-------------------------------------------------------------------------------");
10435            }
10436            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10437        }
10438        Binder.restoreCallingIdentity(origId);
10439    }
10440
10441    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10442            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10443        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10444
10445        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10446                dumpPackage);
10447        boolean needSep = printedAnything;
10448
10449        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10450                dumpPackage, needSep, "  mFocusedActivity: ");
10451        if (printed) {
10452            printedAnything = true;
10453            needSep = false;
10454        }
10455
10456        if (dumpPackage == null) {
10457            if (needSep) {
10458                pw.println();
10459            }
10460            needSep = true;
10461            printedAnything = true;
10462            mStackSupervisor.dump(pw, "  ");
10463        }
10464
10465        if (mRecentTasks.size() > 0) {
10466            boolean printedHeader = false;
10467
10468            final int N = mRecentTasks.size();
10469            for (int i=0; i<N; i++) {
10470                TaskRecord tr = mRecentTasks.get(i);
10471                if (dumpPackage != null) {
10472                    if (tr.realActivity == null ||
10473                            !dumpPackage.equals(tr.realActivity)) {
10474                        continue;
10475                    }
10476                }
10477                if (!printedHeader) {
10478                    if (needSep) {
10479                        pw.println();
10480                    }
10481                    pw.println("  Recent tasks:");
10482                    printedHeader = true;
10483                    printedAnything = true;
10484                }
10485                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10486                        pw.println(tr);
10487                if (dumpAll) {
10488                    mRecentTasks.get(i).dump(pw, "    ");
10489                }
10490            }
10491        }
10492
10493        if (!printedAnything) {
10494            pw.println("  (nothing)");
10495        }
10496    }
10497
10498    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10499            int opti, boolean dumpAll, String dumpPackage) {
10500        boolean needSep = false;
10501        boolean printedAnything = false;
10502        int numPers = 0;
10503
10504        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10505
10506        if (dumpAll) {
10507            final int NP = mProcessNames.getMap().size();
10508            for (int ip=0; ip<NP; ip++) {
10509                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10510                final int NA = procs.size();
10511                for (int ia=0; ia<NA; ia++) {
10512                    ProcessRecord r = procs.valueAt(ia);
10513                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10514                        continue;
10515                    }
10516                    if (!needSep) {
10517                        pw.println("  All known processes:");
10518                        needSep = true;
10519                        printedAnything = true;
10520                    }
10521                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10522                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10523                        pw.print(" "); pw.println(r);
10524                    r.dump(pw, "    ");
10525                    if (r.persistent) {
10526                        numPers++;
10527                    }
10528                }
10529            }
10530        }
10531
10532        if (mIsolatedProcesses.size() > 0) {
10533            boolean printed = false;
10534            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10535                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10536                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10537                    continue;
10538                }
10539                if (!printed) {
10540                    if (needSep) {
10541                        pw.println();
10542                    }
10543                    pw.println("  Isolated process list (sorted by uid):");
10544                    printedAnything = true;
10545                    printed = true;
10546                    needSep = true;
10547                }
10548                pw.println(String.format("%sIsolated #%2d: %s",
10549                        "    ", i, r.toString()));
10550            }
10551        }
10552
10553        if (mLruProcesses.size() > 0) {
10554            if (needSep) {
10555                pw.println();
10556            }
10557            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10558                    pw.print(" total, non-act at ");
10559                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10560                    pw.print(", non-svc at ");
10561                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10562                    pw.println("):");
10563            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10564            needSep = true;
10565            printedAnything = true;
10566        }
10567
10568        if (dumpAll || dumpPackage != null) {
10569            synchronized (mPidsSelfLocked) {
10570                boolean printed = false;
10571                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10572                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10573                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10574                        continue;
10575                    }
10576                    if (!printed) {
10577                        if (needSep) pw.println();
10578                        needSep = true;
10579                        pw.println("  PID mappings:");
10580                        printed = true;
10581                        printedAnything = true;
10582                    }
10583                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10584                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10585                }
10586            }
10587        }
10588
10589        if (mForegroundProcesses.size() > 0) {
10590            synchronized (mPidsSelfLocked) {
10591                boolean printed = false;
10592                for (int i=0; i<mForegroundProcesses.size(); i++) {
10593                    ProcessRecord r = mPidsSelfLocked.get(
10594                            mForegroundProcesses.valueAt(i).pid);
10595                    if (dumpPackage != null && (r == null
10596                            || !r.pkgList.containsKey(dumpPackage))) {
10597                        continue;
10598                    }
10599                    if (!printed) {
10600                        if (needSep) pw.println();
10601                        needSep = true;
10602                        pw.println("  Foreground Processes:");
10603                        printed = true;
10604                        printedAnything = true;
10605                    }
10606                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10607                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10608                }
10609            }
10610        }
10611
10612        if (mPersistentStartingProcesses.size() > 0) {
10613            if (needSep) pw.println();
10614            needSep = true;
10615            printedAnything = true;
10616            pw.println("  Persisent processes that are starting:");
10617            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10618                    "Starting Norm", "Restarting PERS", dumpPackage);
10619        }
10620
10621        if (mRemovedProcesses.size() > 0) {
10622            if (needSep) pw.println();
10623            needSep = true;
10624            printedAnything = true;
10625            pw.println("  Processes that are being removed:");
10626            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10627                    "Removed Norm", "Removed PERS", dumpPackage);
10628        }
10629
10630        if (mProcessesOnHold.size() > 0) {
10631            if (needSep) pw.println();
10632            needSep = true;
10633            printedAnything = true;
10634            pw.println("  Processes that are on old until the system is ready:");
10635            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10636                    "OnHold Norm", "OnHold PERS", dumpPackage);
10637        }
10638
10639        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10640
10641        if (mProcessCrashTimes.getMap().size() > 0) {
10642            boolean printed = false;
10643            long now = SystemClock.uptimeMillis();
10644            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10645            final int NP = pmap.size();
10646            for (int ip=0; ip<NP; ip++) {
10647                String pname = pmap.keyAt(ip);
10648                SparseArray<Long> uids = pmap.valueAt(ip);
10649                final int N = uids.size();
10650                for (int i=0; i<N; i++) {
10651                    int puid = uids.keyAt(i);
10652                    ProcessRecord r = mProcessNames.get(pname, puid);
10653                    if (dumpPackage != null && (r == null
10654                            || !r.pkgList.containsKey(dumpPackage))) {
10655                        continue;
10656                    }
10657                    if (!printed) {
10658                        if (needSep) pw.println();
10659                        needSep = true;
10660                        pw.println("  Time since processes crashed:");
10661                        printed = true;
10662                        printedAnything = true;
10663                    }
10664                    pw.print("    Process "); pw.print(pname);
10665                            pw.print(" uid "); pw.print(puid);
10666                            pw.print(": last crashed ");
10667                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10668                            pw.println(" ago");
10669                }
10670            }
10671        }
10672
10673        if (mBadProcesses.getMap().size() > 0) {
10674            boolean printed = false;
10675            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10676            final int NP = pmap.size();
10677            for (int ip=0; ip<NP; ip++) {
10678                String pname = pmap.keyAt(ip);
10679                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10680                final int N = uids.size();
10681                for (int i=0; i<N; i++) {
10682                    int puid = uids.keyAt(i);
10683                    ProcessRecord r = mProcessNames.get(pname, puid);
10684                    if (dumpPackage != null && (r == null
10685                            || !r.pkgList.containsKey(dumpPackage))) {
10686                        continue;
10687                    }
10688                    if (!printed) {
10689                        if (needSep) pw.println();
10690                        needSep = true;
10691                        pw.println("  Bad processes:");
10692                        printedAnything = true;
10693                    }
10694                    BadProcessInfo info = uids.valueAt(i);
10695                    pw.print("    Bad process "); pw.print(pname);
10696                            pw.print(" uid "); pw.print(puid);
10697                            pw.print(": crashed at time "); pw.println(info.time);
10698                    if (info.shortMsg != null) {
10699                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10700                    }
10701                    if (info.longMsg != null) {
10702                        pw.print("      Long msg: "); pw.println(info.longMsg);
10703                    }
10704                    if (info.stack != null) {
10705                        pw.println("      Stack:");
10706                        int lastPos = 0;
10707                        for (int pos=0; pos<info.stack.length(); pos++) {
10708                            if (info.stack.charAt(pos) == '\n') {
10709                                pw.print("        ");
10710                                pw.write(info.stack, lastPos, pos-lastPos);
10711                                pw.println();
10712                                lastPos = pos+1;
10713                            }
10714                        }
10715                        if (lastPos < info.stack.length()) {
10716                            pw.print("        ");
10717                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10718                            pw.println();
10719                        }
10720                    }
10721                }
10722            }
10723        }
10724
10725        if (dumpPackage == null) {
10726            pw.println();
10727            needSep = false;
10728            pw.println("  mStartedUsers:");
10729            for (int i=0; i<mStartedUsers.size(); i++) {
10730                UserStartedState uss = mStartedUsers.valueAt(i);
10731                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10732                        pw.print(": "); uss.dump("", pw);
10733            }
10734            pw.print("  mStartedUserArray: [");
10735            for (int i=0; i<mStartedUserArray.length; i++) {
10736                if (i > 0) pw.print(", ");
10737                pw.print(mStartedUserArray[i]);
10738            }
10739            pw.println("]");
10740            pw.print("  mUserLru: [");
10741            for (int i=0; i<mUserLru.size(); i++) {
10742                if (i > 0) pw.print(", ");
10743                pw.print(mUserLru.get(i));
10744            }
10745            pw.println("]");
10746            if (dumpAll) {
10747                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10748            }
10749        }
10750        if (mHomeProcess != null && (dumpPackage == null
10751                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10752            if (needSep) {
10753                pw.println();
10754                needSep = false;
10755            }
10756            pw.println("  mHomeProcess: " + mHomeProcess);
10757        }
10758        if (mPreviousProcess != null && (dumpPackage == null
10759                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10760            if (needSep) {
10761                pw.println();
10762                needSep = false;
10763            }
10764            pw.println("  mPreviousProcess: " + mPreviousProcess);
10765        }
10766        if (dumpAll) {
10767            StringBuilder sb = new StringBuilder(128);
10768            sb.append("  mPreviousProcessVisibleTime: ");
10769            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10770            pw.println(sb);
10771        }
10772        if (mHeavyWeightProcess != null && (dumpPackage == null
10773                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10774            if (needSep) {
10775                pw.println();
10776                needSep = false;
10777            }
10778            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10779        }
10780        if (dumpPackage == null) {
10781            pw.println("  mConfiguration: " + mConfiguration);
10782        }
10783        if (dumpAll) {
10784            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10785            if (mCompatModePackages.getPackages().size() > 0) {
10786                boolean printed = false;
10787                for (Map.Entry<String, Integer> entry
10788                        : mCompatModePackages.getPackages().entrySet()) {
10789                    String pkg = entry.getKey();
10790                    int mode = entry.getValue();
10791                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10792                        continue;
10793                    }
10794                    if (!printed) {
10795                        pw.println("  mScreenCompatPackages:");
10796                        printed = true;
10797                    }
10798                    pw.print("    "); pw.print(pkg); pw.print(": ");
10799                            pw.print(mode); pw.println();
10800                }
10801            }
10802        }
10803        if (dumpPackage == null) {
10804            if (mSleeping || mWentToSleep || mLockScreenShown) {
10805                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10806                        + " mLockScreenShown " + mLockScreenShown);
10807            }
10808            if (mShuttingDown) {
10809                pw.println("  mShuttingDown=" + mShuttingDown);
10810            }
10811        }
10812        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10813                || mOrigWaitForDebugger) {
10814            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10815                    || dumpPackage.equals(mOrigDebugApp)) {
10816                if (needSep) {
10817                    pw.println();
10818                    needSep = false;
10819                }
10820                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10821                        + " mDebugTransient=" + mDebugTransient
10822                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10823            }
10824        }
10825        if (mOpenGlTraceApp != null) {
10826            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10827                if (needSep) {
10828                    pw.println();
10829                    needSep = false;
10830                }
10831                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10832            }
10833        }
10834        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10835                || mProfileFd != null) {
10836            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10837                if (needSep) {
10838                    pw.println();
10839                    needSep = false;
10840                }
10841                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10842                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10843                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10844                        + mAutoStopProfiler);
10845            }
10846        }
10847        if (dumpPackage == null) {
10848            if (mAlwaysFinishActivities || mController != null) {
10849                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10850                        + " mController=" + mController);
10851            }
10852            if (dumpAll) {
10853                pw.println("  Total persistent processes: " + numPers);
10854                pw.println("  mProcessesReady=" + mProcessesReady
10855                        + " mSystemReady=" + mSystemReady);
10856                pw.println("  mBooting=" + mBooting
10857                        + " mBooted=" + mBooted
10858                        + " mFactoryTest=" + mFactoryTest);
10859                pw.print("  mLastPowerCheckRealtime=");
10860                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10861                        pw.println("");
10862                pw.print("  mLastPowerCheckUptime=");
10863                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10864                        pw.println("");
10865                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10866                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10867                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10868                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10869                        + " (" + mLruProcesses.size() + " total)"
10870                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10871                        + " mNumServiceProcs=" + mNumServiceProcs
10872                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10873                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10874                        + " mLastMemoryLevel" + mLastMemoryLevel
10875                        + " mLastNumProcesses" + mLastNumProcesses);
10876                long now = SystemClock.uptimeMillis();
10877                pw.print("  mLastIdleTime=");
10878                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10879                        pw.print(" mLowRamSinceLastIdle=");
10880                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10881                        pw.println();
10882            }
10883        }
10884
10885        if (!printedAnything) {
10886            pw.println("  (nothing)");
10887        }
10888    }
10889
10890    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10891            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10892        if (mProcessesToGc.size() > 0) {
10893            boolean printed = false;
10894            long now = SystemClock.uptimeMillis();
10895            for (int i=0; i<mProcessesToGc.size(); i++) {
10896                ProcessRecord proc = mProcessesToGc.get(i);
10897                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10898                    continue;
10899                }
10900                if (!printed) {
10901                    if (needSep) pw.println();
10902                    needSep = true;
10903                    pw.println("  Processes that are waiting to GC:");
10904                    printed = true;
10905                }
10906                pw.print("    Process "); pw.println(proc);
10907                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10908                        pw.print(", last gced=");
10909                        pw.print(now-proc.lastRequestedGc);
10910                        pw.print(" ms ago, last lowMem=");
10911                        pw.print(now-proc.lastLowMemory);
10912                        pw.println(" ms ago");
10913
10914            }
10915        }
10916        return needSep;
10917    }
10918
10919    void printOomLevel(PrintWriter pw, String name, int adj) {
10920        pw.print("    ");
10921        if (adj >= 0) {
10922            pw.print(' ');
10923            if (adj < 10) pw.print(' ');
10924        } else {
10925            if (adj > -10) pw.print(' ');
10926        }
10927        pw.print(adj);
10928        pw.print(": ");
10929        pw.print(name);
10930        pw.print(" (");
10931        pw.print(mProcessList.getMemLevel(adj)/1024);
10932        pw.println(" kB)");
10933    }
10934
10935    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10936            int opti, boolean dumpAll) {
10937        boolean needSep = false;
10938
10939        if (mLruProcesses.size() > 0) {
10940            if (needSep) pw.println();
10941            needSep = true;
10942            pw.println("  OOM levels:");
10943            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10944            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10945            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10946            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10947            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10948            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10949            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10950            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10951            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
10952            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
10953            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
10954            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
10955            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
10956
10957            if (needSep) pw.println();
10958            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
10959                    pw.print(" total, non-act at ");
10960                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10961                    pw.print(", non-svc at ");
10962                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10963                    pw.println("):");
10964            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
10965            needSep = true;
10966        }
10967
10968        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
10969
10970        pw.println();
10971        pw.println("  mHomeProcess: " + mHomeProcess);
10972        pw.println("  mPreviousProcess: " + mPreviousProcess);
10973        if (mHeavyWeightProcess != null) {
10974            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10975        }
10976
10977        return true;
10978    }
10979
10980    /**
10981     * There are three ways to call this:
10982     *  - no provider specified: dump all the providers
10983     *  - a flattened component name that matched an existing provider was specified as the
10984     *    first arg: dump that one provider
10985     *  - the first arg isn't the flattened component name of an existing provider:
10986     *    dump all providers whose component contains the first arg as a substring
10987     */
10988    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
10989            int opti, boolean dumpAll) {
10990        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
10991    }
10992
10993    static class ItemMatcher {
10994        ArrayList<ComponentName> components;
10995        ArrayList<String> strings;
10996        ArrayList<Integer> objects;
10997        boolean all;
10998
10999        ItemMatcher() {
11000            all = true;
11001        }
11002
11003        void build(String name) {
11004            ComponentName componentName = ComponentName.unflattenFromString(name);
11005            if (componentName != null) {
11006                if (components == null) {
11007                    components = new ArrayList<ComponentName>();
11008                }
11009                components.add(componentName);
11010                all = false;
11011            } else {
11012                int objectId = 0;
11013                // Not a '/' separated full component name; maybe an object ID?
11014                try {
11015                    objectId = Integer.parseInt(name, 16);
11016                    if (objects == null) {
11017                        objects = new ArrayList<Integer>();
11018                    }
11019                    objects.add(objectId);
11020                    all = false;
11021                } catch (RuntimeException e) {
11022                    // Not an integer; just do string match.
11023                    if (strings == null) {
11024                        strings = new ArrayList<String>();
11025                    }
11026                    strings.add(name);
11027                    all = false;
11028                }
11029            }
11030        }
11031
11032        int build(String[] args, int opti) {
11033            for (; opti<args.length; opti++) {
11034                String name = args[opti];
11035                if ("--".equals(name)) {
11036                    return opti+1;
11037                }
11038                build(name);
11039            }
11040            return opti;
11041        }
11042
11043        boolean match(Object object, ComponentName comp) {
11044            if (all) {
11045                return true;
11046            }
11047            if (components != null) {
11048                for (int i=0; i<components.size(); i++) {
11049                    if (components.get(i).equals(comp)) {
11050                        return true;
11051                    }
11052                }
11053            }
11054            if (objects != null) {
11055                for (int i=0; i<objects.size(); i++) {
11056                    if (System.identityHashCode(object) == objects.get(i)) {
11057                        return true;
11058                    }
11059                }
11060            }
11061            if (strings != null) {
11062                String flat = comp.flattenToString();
11063                for (int i=0; i<strings.size(); i++) {
11064                    if (flat.contains(strings.get(i))) {
11065                        return true;
11066                    }
11067                }
11068            }
11069            return false;
11070        }
11071    }
11072
11073    /**
11074     * There are three things that cmd can be:
11075     *  - a flattened component name that matches an existing activity
11076     *  - the cmd arg isn't the flattened component name of an existing activity:
11077     *    dump all activity whose component contains the cmd as a substring
11078     *  - A hex number of the ActivityRecord object instance.
11079     */
11080    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11081            int opti, boolean dumpAll) {
11082        ArrayList<ActivityRecord> activities;
11083
11084        synchronized (this) {
11085            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11086        }
11087
11088        if (activities.size() <= 0) {
11089            return false;
11090        }
11091
11092        String[] newArgs = new String[args.length - opti];
11093        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11094
11095        TaskRecord lastTask = null;
11096        boolean needSep = false;
11097        for (int i=activities.size()-1; i>=0; i--) {
11098            ActivityRecord r = activities.get(i);
11099            if (needSep) {
11100                pw.println();
11101            }
11102            needSep = true;
11103            synchronized (this) {
11104                if (lastTask != r.task) {
11105                    lastTask = r.task;
11106                    pw.print("TASK "); pw.print(lastTask.affinity);
11107                            pw.print(" id="); pw.println(lastTask.taskId);
11108                    if (dumpAll) {
11109                        lastTask.dump(pw, "  ");
11110                    }
11111                }
11112            }
11113            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11114        }
11115        return true;
11116    }
11117
11118    /**
11119     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11120     * there is a thread associated with the activity.
11121     */
11122    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11123            final ActivityRecord r, String[] args, boolean dumpAll) {
11124        String innerPrefix = prefix + "  ";
11125        synchronized (this) {
11126            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11127                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11128                    pw.print(" pid=");
11129                    if (r.app != null) pw.println(r.app.pid);
11130                    else pw.println("(not running)");
11131            if (dumpAll) {
11132                r.dump(pw, innerPrefix);
11133            }
11134        }
11135        if (r.app != null && r.app.thread != null) {
11136            // flush anything that is already in the PrintWriter since the thread is going
11137            // to write to the file descriptor directly
11138            pw.flush();
11139            try {
11140                TransferPipe tp = new TransferPipe();
11141                try {
11142                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11143                            r.appToken, innerPrefix, args);
11144                    tp.go(fd);
11145                } finally {
11146                    tp.kill();
11147                }
11148            } catch (IOException e) {
11149                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11150            } catch (RemoteException e) {
11151                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11152            }
11153        }
11154    }
11155
11156    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11157            int opti, boolean dumpAll, String dumpPackage) {
11158        boolean needSep = false;
11159        boolean onlyHistory = false;
11160        boolean printedAnything = false;
11161
11162        if ("history".equals(dumpPackage)) {
11163            if (opti < args.length && "-s".equals(args[opti])) {
11164                dumpAll = false;
11165            }
11166            onlyHistory = true;
11167            dumpPackage = null;
11168        }
11169
11170        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11171        if (!onlyHistory && dumpAll) {
11172            if (mRegisteredReceivers.size() > 0) {
11173                boolean printed = false;
11174                Iterator it = mRegisteredReceivers.values().iterator();
11175                while (it.hasNext()) {
11176                    ReceiverList r = (ReceiverList)it.next();
11177                    if (dumpPackage != null && (r.app == null ||
11178                            !dumpPackage.equals(r.app.info.packageName))) {
11179                        continue;
11180                    }
11181                    if (!printed) {
11182                        pw.println("  Registered Receivers:");
11183                        needSep = true;
11184                        printed = true;
11185                        printedAnything = true;
11186                    }
11187                    pw.print("  * "); pw.println(r);
11188                    r.dump(pw, "    ");
11189                }
11190            }
11191
11192            if (mReceiverResolver.dump(pw, needSep ?
11193                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11194                    "    ", dumpPackage, false)) {
11195                needSep = true;
11196                printedAnything = true;
11197            }
11198        }
11199
11200        for (BroadcastQueue q : mBroadcastQueues) {
11201            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11202            printedAnything |= needSep;
11203        }
11204
11205        needSep = true;
11206
11207        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11208            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11209                if (needSep) {
11210                    pw.println();
11211                }
11212                needSep = true;
11213                printedAnything = true;
11214                pw.print("  Sticky broadcasts for user ");
11215                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11216                StringBuilder sb = new StringBuilder(128);
11217                for (Map.Entry<String, ArrayList<Intent>> ent
11218                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11219                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11220                    if (dumpAll) {
11221                        pw.println(":");
11222                        ArrayList<Intent> intents = ent.getValue();
11223                        final int N = intents.size();
11224                        for (int i=0; i<N; i++) {
11225                            sb.setLength(0);
11226                            sb.append("    Intent: ");
11227                            intents.get(i).toShortString(sb, false, true, false, false);
11228                            pw.println(sb.toString());
11229                            Bundle bundle = intents.get(i).getExtras();
11230                            if (bundle != null) {
11231                                pw.print("      ");
11232                                pw.println(bundle.toString());
11233                            }
11234                        }
11235                    } else {
11236                        pw.println("");
11237                    }
11238                }
11239            }
11240        }
11241
11242        if (!onlyHistory && dumpAll) {
11243            pw.println();
11244            for (BroadcastQueue queue : mBroadcastQueues) {
11245                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11246                        + queue.mBroadcastsScheduled);
11247            }
11248            pw.println("  mHandler:");
11249            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11250            needSep = true;
11251            printedAnything = true;
11252        }
11253
11254        if (!printedAnything) {
11255            pw.println("  (nothing)");
11256        }
11257    }
11258
11259    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11260            int opti, boolean dumpAll, String dumpPackage) {
11261        boolean needSep;
11262        boolean printedAnything = false;
11263
11264        ItemMatcher matcher = new ItemMatcher();
11265        matcher.build(args, opti);
11266
11267        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11268
11269        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11270        printedAnything |= needSep;
11271
11272        if (mLaunchingProviders.size() > 0) {
11273            boolean printed = false;
11274            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11275                ContentProviderRecord r = mLaunchingProviders.get(i);
11276                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11277                    continue;
11278                }
11279                if (!printed) {
11280                    if (needSep) pw.println();
11281                    needSep = true;
11282                    pw.println("  Launching content providers:");
11283                    printed = true;
11284                    printedAnything = true;
11285                }
11286                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11287                        pw.println(r);
11288            }
11289        }
11290
11291        if (mGrantedUriPermissions.size() > 0) {
11292            boolean printed = false;
11293            int dumpUid = -2;
11294            if (dumpPackage != null) {
11295                try {
11296                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11297                } catch (NameNotFoundException e) {
11298                    dumpUid = -1;
11299                }
11300            }
11301            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11302                int uid = mGrantedUriPermissions.keyAt(i);
11303                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11304                    continue;
11305                }
11306                ArrayMap<Uri, UriPermission> perms
11307                        = mGrantedUriPermissions.valueAt(i);
11308                if (!printed) {
11309                    if (needSep) pw.println();
11310                    needSep = true;
11311                    pw.println("  Granted Uri Permissions:");
11312                    printed = true;
11313                    printedAnything = true;
11314                }
11315                pw.print("  * UID "); pw.print(uid);
11316                        pw.println(" holds:");
11317                for (UriPermission perm : perms.values()) {
11318                    pw.print("    "); pw.println(perm);
11319                    if (dumpAll) {
11320                        perm.dump(pw, "      ");
11321                    }
11322                }
11323            }
11324        }
11325
11326        if (!printedAnything) {
11327            pw.println("  (nothing)");
11328        }
11329    }
11330
11331    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11332            int opti, boolean dumpAll, String dumpPackage) {
11333        boolean printed = false;
11334
11335        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11336
11337        if (mIntentSenderRecords.size() > 0) {
11338            Iterator<WeakReference<PendingIntentRecord>> it
11339                    = mIntentSenderRecords.values().iterator();
11340            while (it.hasNext()) {
11341                WeakReference<PendingIntentRecord> ref = it.next();
11342                PendingIntentRecord rec = ref != null ? ref.get(): null;
11343                if (dumpPackage != null && (rec == null
11344                        || !dumpPackage.equals(rec.key.packageName))) {
11345                    continue;
11346                }
11347                printed = true;
11348                if (rec != null) {
11349                    pw.print("  * "); pw.println(rec);
11350                    if (dumpAll) {
11351                        rec.dump(pw, "    ");
11352                    }
11353                } else {
11354                    pw.print("  * "); pw.println(ref);
11355                }
11356            }
11357        }
11358
11359        if (!printed) {
11360            pw.println("  (nothing)");
11361        }
11362    }
11363
11364    private static final int dumpProcessList(PrintWriter pw,
11365            ActivityManagerService service, List list,
11366            String prefix, String normalLabel, String persistentLabel,
11367            String dumpPackage) {
11368        int numPers = 0;
11369        final int N = list.size()-1;
11370        for (int i=N; i>=0; i--) {
11371            ProcessRecord r = (ProcessRecord)list.get(i);
11372            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11373                continue;
11374            }
11375            pw.println(String.format("%s%s #%2d: %s",
11376                    prefix, (r.persistent ? persistentLabel : normalLabel),
11377                    i, r.toString()));
11378            if (r.persistent) {
11379                numPers++;
11380            }
11381        }
11382        return numPers;
11383    }
11384
11385    private static final boolean dumpProcessOomList(PrintWriter pw,
11386            ActivityManagerService service, List<ProcessRecord> origList,
11387            String prefix, String normalLabel, String persistentLabel,
11388            boolean inclDetails, String dumpPackage) {
11389
11390        ArrayList<Pair<ProcessRecord, Integer>> list
11391                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11392        for (int i=0; i<origList.size(); i++) {
11393            ProcessRecord r = origList.get(i);
11394            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11395                continue;
11396            }
11397            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11398        }
11399
11400        if (list.size() <= 0) {
11401            return false;
11402        }
11403
11404        Comparator<Pair<ProcessRecord, Integer>> comparator
11405                = new Comparator<Pair<ProcessRecord, Integer>>() {
11406            @Override
11407            public int compare(Pair<ProcessRecord, Integer> object1,
11408                    Pair<ProcessRecord, Integer> object2) {
11409                if (object1.first.setAdj != object2.first.setAdj) {
11410                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11411                }
11412                if (object1.second.intValue() != object2.second.intValue()) {
11413                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11414                }
11415                return 0;
11416            }
11417        };
11418
11419        Collections.sort(list, comparator);
11420
11421        final long curRealtime = SystemClock.elapsedRealtime();
11422        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11423        final long curUptime = SystemClock.uptimeMillis();
11424        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11425
11426        for (int i=list.size()-1; i>=0; i--) {
11427            ProcessRecord r = list.get(i).first;
11428            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11429            char schedGroup;
11430            switch (r.setSchedGroup) {
11431                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11432                    schedGroup = 'B';
11433                    break;
11434                case Process.THREAD_GROUP_DEFAULT:
11435                    schedGroup = 'F';
11436                    break;
11437                default:
11438                    schedGroup = '?';
11439                    break;
11440            }
11441            char foreground;
11442            if (r.foregroundActivities) {
11443                foreground = 'A';
11444            } else if (r.foregroundServices) {
11445                foreground = 'S';
11446            } else {
11447                foreground = ' ';
11448            }
11449            String procState = ProcessList.makeProcStateString(r.curProcState);
11450            pw.print(prefix);
11451            pw.print(r.persistent ? persistentLabel : normalLabel);
11452            pw.print(" #");
11453            int num = (origList.size()-1)-list.get(i).second;
11454            if (num < 10) pw.print(' ');
11455            pw.print(num);
11456            pw.print(": ");
11457            pw.print(oomAdj);
11458            pw.print(' ');
11459            pw.print(schedGroup);
11460            pw.print('/');
11461            pw.print(foreground);
11462            pw.print('/');
11463            pw.print(procState);
11464            pw.print(" trm:");
11465            if (r.trimMemoryLevel < 10) pw.print(' ');
11466            pw.print(r.trimMemoryLevel);
11467            pw.print(' ');
11468            pw.print(r.toShortString());
11469            pw.print(" (");
11470            pw.print(r.adjType);
11471            pw.println(')');
11472            if (r.adjSource != null || r.adjTarget != null) {
11473                pw.print(prefix);
11474                pw.print("    ");
11475                if (r.adjTarget instanceof ComponentName) {
11476                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11477                } else if (r.adjTarget != null) {
11478                    pw.print(r.adjTarget.toString());
11479                } else {
11480                    pw.print("{null}");
11481                }
11482                pw.print("<=");
11483                if (r.adjSource instanceof ProcessRecord) {
11484                    pw.print("Proc{");
11485                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11486                    pw.println("}");
11487                } else if (r.adjSource != null) {
11488                    pw.println(r.adjSource.toString());
11489                } else {
11490                    pw.println("{null}");
11491                }
11492            }
11493            if (inclDetails) {
11494                pw.print(prefix);
11495                pw.print("    ");
11496                pw.print("oom: max="); pw.print(r.maxAdj);
11497                pw.print(" curRaw="); pw.print(r.curRawAdj);
11498                pw.print(" setRaw="); pw.print(r.setRawAdj);
11499                pw.print(" cur="); pw.print(r.curAdj);
11500                pw.print(" set="); pw.println(r.setAdj);
11501                pw.print(prefix);
11502                pw.print("    ");
11503                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11504                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11505                pw.print(" lastPss="); pw.print(r.lastPss);
11506                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11507                pw.print(prefix);
11508                pw.print("    ");
11509                pw.print("keeping="); pw.print(r.keeping);
11510                pw.print(" cached="); pw.print(r.cached);
11511                pw.print(" empty="); pw.print(r.empty);
11512                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11513
11514                if (!r.keeping) {
11515                    if (r.lastWakeTime != 0) {
11516                        long wtime;
11517                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11518                        synchronized (stats) {
11519                            wtime = stats.getProcessWakeTime(r.info.uid,
11520                                    r.pid, curRealtime);
11521                        }
11522                        long timeUsed = wtime - r.lastWakeTime;
11523                        pw.print(prefix);
11524                        pw.print("    ");
11525                        pw.print("keep awake over ");
11526                        TimeUtils.formatDuration(realtimeSince, pw);
11527                        pw.print(" used ");
11528                        TimeUtils.formatDuration(timeUsed, pw);
11529                        pw.print(" (");
11530                        pw.print((timeUsed*100)/realtimeSince);
11531                        pw.println("%)");
11532                    }
11533                    if (r.lastCpuTime != 0) {
11534                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11535                        pw.print(prefix);
11536                        pw.print("    ");
11537                        pw.print("run cpu over ");
11538                        TimeUtils.formatDuration(uptimeSince, pw);
11539                        pw.print(" used ");
11540                        TimeUtils.formatDuration(timeUsed, pw);
11541                        pw.print(" (");
11542                        pw.print((timeUsed*100)/uptimeSince);
11543                        pw.println("%)");
11544                    }
11545                }
11546            }
11547        }
11548        return true;
11549    }
11550
11551    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11552        ArrayList<ProcessRecord> procs;
11553        synchronized (this) {
11554            if (args != null && args.length > start
11555                    && args[start].charAt(0) != '-') {
11556                procs = new ArrayList<ProcessRecord>();
11557                int pid = -1;
11558                try {
11559                    pid = Integer.parseInt(args[start]);
11560                } catch (NumberFormatException e) {
11561                }
11562                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11563                    ProcessRecord proc = mLruProcesses.get(i);
11564                    if (proc.pid == pid) {
11565                        procs.add(proc);
11566                    } else if (proc.processName.equals(args[start])) {
11567                        procs.add(proc);
11568                    }
11569                }
11570                if (procs.size() <= 0) {
11571                    return null;
11572                }
11573            } else {
11574                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11575            }
11576        }
11577        return procs;
11578    }
11579
11580    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11581            PrintWriter pw, String[] args) {
11582        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11583        if (procs == null) {
11584            pw.println("No process found for: " + args[0]);
11585            return;
11586        }
11587
11588        long uptime = SystemClock.uptimeMillis();
11589        long realtime = SystemClock.elapsedRealtime();
11590        pw.println("Applications Graphics Acceleration Info:");
11591        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11592
11593        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11594            ProcessRecord r = procs.get(i);
11595            if (r.thread != null) {
11596                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11597                pw.flush();
11598                try {
11599                    TransferPipe tp = new TransferPipe();
11600                    try {
11601                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11602                        tp.go(fd);
11603                    } finally {
11604                        tp.kill();
11605                    }
11606                } catch (IOException e) {
11607                    pw.println("Failure while dumping the app: " + r);
11608                    pw.flush();
11609                } catch (RemoteException e) {
11610                    pw.println("Got a RemoteException while dumping the app " + r);
11611                    pw.flush();
11612                }
11613            }
11614        }
11615    }
11616
11617    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11618        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11619        if (procs == null) {
11620            pw.println("No process found for: " + args[0]);
11621            return;
11622        }
11623
11624        pw.println("Applications Database Info:");
11625
11626        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11627            ProcessRecord r = procs.get(i);
11628            if (r.thread != null) {
11629                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11630                pw.flush();
11631                try {
11632                    TransferPipe tp = new TransferPipe();
11633                    try {
11634                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11635                        tp.go(fd);
11636                    } finally {
11637                        tp.kill();
11638                    }
11639                } catch (IOException e) {
11640                    pw.println("Failure while dumping the app: " + r);
11641                    pw.flush();
11642                } catch (RemoteException e) {
11643                    pw.println("Got a RemoteException while dumping the app " + r);
11644                    pw.flush();
11645                }
11646            }
11647        }
11648    }
11649
11650    final static class MemItem {
11651        final boolean isProc;
11652        final String label;
11653        final String shortLabel;
11654        final long pss;
11655        final int id;
11656        final boolean hasActivities;
11657        ArrayList<MemItem> subitems;
11658
11659        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11660                boolean _hasActivities) {
11661            isProc = true;
11662            label = _label;
11663            shortLabel = _shortLabel;
11664            pss = _pss;
11665            id = _id;
11666            hasActivities = _hasActivities;
11667        }
11668
11669        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11670            isProc = false;
11671            label = _label;
11672            shortLabel = _shortLabel;
11673            pss = _pss;
11674            id = _id;
11675            hasActivities = false;
11676        }
11677    }
11678
11679    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11680            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11681        if (sort && !isCompact) {
11682            Collections.sort(items, new Comparator<MemItem>() {
11683                @Override
11684                public int compare(MemItem lhs, MemItem rhs) {
11685                    if (lhs.pss < rhs.pss) {
11686                        return 1;
11687                    } else if (lhs.pss > rhs.pss) {
11688                        return -1;
11689                    }
11690                    return 0;
11691                }
11692            });
11693        }
11694
11695        for (int i=0; i<items.size(); i++) {
11696            MemItem mi = items.get(i);
11697            if (!isCompact) {
11698                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11699            } else if (mi.isProc) {
11700                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11701                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11702                pw.println(mi.hasActivities ? ",a" : ",e");
11703            } else {
11704                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11705                pw.println(mi.pss);
11706            }
11707            if (mi.subitems != null) {
11708                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11709                        true, isCompact);
11710            }
11711        }
11712    }
11713
11714    // These are in KB.
11715    static final long[] DUMP_MEM_BUCKETS = new long[] {
11716        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11717        120*1024, 160*1024, 200*1024,
11718        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11719        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11720    };
11721
11722    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11723            boolean stackLike) {
11724        int start = label.lastIndexOf('.');
11725        if (start >= 0) start++;
11726        else start = 0;
11727        int end = label.length();
11728        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11729            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11730                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11731                out.append(bucket);
11732                out.append(stackLike ? "MB." : "MB ");
11733                out.append(label, start, end);
11734                return;
11735            }
11736        }
11737        out.append(memKB/1024);
11738        out.append(stackLike ? "MB." : "MB ");
11739        out.append(label, start, end);
11740    }
11741
11742    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11743            ProcessList.NATIVE_ADJ,
11744            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11745            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11746            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11747            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11748            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11749    };
11750    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11751            "Native",
11752            "System", "Persistent", "Foreground",
11753            "Visible", "Perceptible",
11754            "Heavy Weight", "Backup",
11755            "A Services", "Home",
11756            "Previous", "B Services", "Cached"
11757    };
11758    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11759            "native",
11760            "sys", "pers", "fore",
11761            "vis", "percept",
11762            "heavy", "backup",
11763            "servicea", "home",
11764            "prev", "serviceb", "cached"
11765    };
11766
11767    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11768            long realtime, boolean isCheckinRequest, boolean isCompact) {
11769        if (isCheckinRequest || isCompact) {
11770            // short checkin version
11771            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11772        } else {
11773            pw.println("Applications Memory Usage (kB):");
11774            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11775        }
11776    }
11777
11778    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11779            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11780        boolean dumpDetails = false;
11781        boolean dumpFullDetails = false;
11782        boolean dumpDalvik = false;
11783        boolean oomOnly = false;
11784        boolean isCompact = false;
11785        boolean localOnly = false;
11786
11787        int opti = 0;
11788        while (opti < args.length) {
11789            String opt = args[opti];
11790            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11791                break;
11792            }
11793            opti++;
11794            if ("-a".equals(opt)) {
11795                dumpDetails = true;
11796                dumpFullDetails = true;
11797                dumpDalvik = true;
11798            } else if ("-d".equals(opt)) {
11799                dumpDalvik = true;
11800            } else if ("-c".equals(opt)) {
11801                isCompact = true;
11802            } else if ("--oom".equals(opt)) {
11803                oomOnly = true;
11804            } else if ("--local".equals(opt)) {
11805                localOnly = true;
11806            } else if ("-h".equals(opt)) {
11807                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11808                pw.println("  -a: include all available information for each process.");
11809                pw.println("  -d: include dalvik details when dumping process details.");
11810                pw.println("  -c: dump in a compact machine-parseable representation.");
11811                pw.println("  --oom: only show processes organized by oom adj.");
11812                pw.println("  --local: only collect details locally, don't call process.");
11813                pw.println("If [process] is specified it can be the name or ");
11814                pw.println("pid of a specific process to dump.");
11815                return;
11816            } else {
11817                pw.println("Unknown argument: " + opt + "; use -h for help");
11818            }
11819        }
11820
11821        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11822        long uptime = SystemClock.uptimeMillis();
11823        long realtime = SystemClock.elapsedRealtime();
11824        final long[] tmpLong = new long[1];
11825
11826        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11827        if (procs == null) {
11828            // No Java processes.  Maybe they want to print a native process.
11829            if (args != null && args.length > opti
11830                    && args[opti].charAt(0) != '-') {
11831                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11832                        = new ArrayList<ProcessCpuTracker.Stats>();
11833                updateCpuStatsNow();
11834                int findPid = -1;
11835                try {
11836                    findPid = Integer.parseInt(args[opti]);
11837                } catch (NumberFormatException e) {
11838                }
11839                synchronized (mProcessCpuThread) {
11840                    final int N = mProcessCpuTracker.countStats();
11841                    for (int i=0; i<N; i++) {
11842                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11843                        if (st.pid == findPid || (st.baseName != null
11844                                && st.baseName.equals(args[opti]))) {
11845                            nativeProcs.add(st);
11846                        }
11847                    }
11848                }
11849                if (nativeProcs.size() > 0) {
11850                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11851                            isCompact);
11852                    Debug.MemoryInfo mi = null;
11853                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11854                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11855                        final int pid = r.pid;
11856                        if (!isCheckinRequest && dumpDetails) {
11857                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11858                        }
11859                        if (mi == null) {
11860                            mi = new Debug.MemoryInfo();
11861                        }
11862                        if (dumpDetails || (!brief && !oomOnly)) {
11863                            Debug.getMemoryInfo(pid, mi);
11864                        } else {
11865                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11866                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11867                        }
11868                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11869                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11870                        if (isCheckinRequest) {
11871                            pw.println();
11872                        }
11873                    }
11874                    return;
11875                }
11876            }
11877            pw.println("No process found for: " + args[opti]);
11878            return;
11879        }
11880
11881        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11882            dumpDetails = true;
11883        }
11884
11885        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11886
11887        String[] innerArgs = new String[args.length-opti];
11888        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11889
11890        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11891        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11892        long nativePss=0, dalvikPss=0, otherPss=0;
11893        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11894
11895        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11896        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11897                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11898
11899        long totalPss = 0;
11900        long cachedPss = 0;
11901
11902        Debug.MemoryInfo mi = null;
11903        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11904            final ProcessRecord r = procs.get(i);
11905            final IApplicationThread thread;
11906            final int pid;
11907            final int oomAdj;
11908            final boolean hasActivities;
11909            synchronized (this) {
11910                thread = r.thread;
11911                pid = r.pid;
11912                oomAdj = r.getSetAdjWithServices();
11913                hasActivities = r.activities.size() > 0;
11914            }
11915            if (thread != null) {
11916                if (!isCheckinRequest && dumpDetails) {
11917                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11918                }
11919                if (mi == null) {
11920                    mi = new Debug.MemoryInfo();
11921                }
11922                if (dumpDetails || (!brief && !oomOnly)) {
11923                    Debug.getMemoryInfo(pid, mi);
11924                } else {
11925                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11926                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11927                }
11928                if (dumpDetails) {
11929                    if (localOnly) {
11930                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11931                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11932                        if (isCheckinRequest) {
11933                            pw.println();
11934                        }
11935                    } else {
11936                        try {
11937                            pw.flush();
11938                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11939                                    dumpDalvik, innerArgs);
11940                        } catch (RemoteException e) {
11941                            if (!isCheckinRequest) {
11942                                pw.println("Got RemoteException!");
11943                                pw.flush();
11944                            }
11945                        }
11946                    }
11947                }
11948
11949                final long myTotalPss = mi.getTotalPss();
11950                final long myTotalUss = mi.getTotalUss();
11951
11952                synchronized (this) {
11953                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
11954                        // Record this for posterity if the process has been stable.
11955                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
11956                    }
11957                }
11958
11959                if (!isCheckinRequest && mi != null) {
11960                    totalPss += myTotalPss;
11961                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
11962                            (hasActivities ? " / activities)" : ")"),
11963                            r.processName, myTotalPss, pid, hasActivities);
11964                    procMems.add(pssItem);
11965                    procMemsMap.put(pid, pssItem);
11966
11967                    nativePss += mi.nativePss;
11968                    dalvikPss += mi.dalvikPss;
11969                    otherPss += mi.otherPss;
11970                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
11971                        long mem = mi.getOtherPss(j);
11972                        miscPss[j] += mem;
11973                        otherPss -= mem;
11974                    }
11975
11976                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
11977                        cachedPss += myTotalPss;
11978                    }
11979
11980                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
11981                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
11982                                || oomIndex == (oomPss.length-1)) {
11983                            oomPss[oomIndex] += myTotalPss;
11984                            if (oomProcs[oomIndex] == null) {
11985                                oomProcs[oomIndex] = new ArrayList<MemItem>();
11986                            }
11987                            oomProcs[oomIndex].add(pssItem);
11988                            break;
11989                        }
11990                    }
11991                }
11992            }
11993        }
11994
11995        if (!isCheckinRequest && procs.size() > 1) {
11996            // If we are showing aggregations, also look for native processes to
11997            // include so that our aggregations are more accurate.
11998            updateCpuStatsNow();
11999            synchronized (mProcessCpuThread) {
12000                final int N = mProcessCpuTracker.countStats();
12001                for (int i=0; i<N; i++) {
12002                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12003                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12004                        if (mi == null) {
12005                            mi = new Debug.MemoryInfo();
12006                        }
12007                        if (!brief && !oomOnly) {
12008                            Debug.getMemoryInfo(st.pid, mi);
12009                        } else {
12010                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12011                            mi.nativePrivateDirty = (int)tmpLong[0];
12012                        }
12013
12014                        final long myTotalPss = mi.getTotalPss();
12015                        totalPss += myTotalPss;
12016
12017                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12018                                st.name, myTotalPss, st.pid, false);
12019                        procMems.add(pssItem);
12020
12021                        nativePss += mi.nativePss;
12022                        dalvikPss += mi.dalvikPss;
12023                        otherPss += mi.otherPss;
12024                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12025                            long mem = mi.getOtherPss(j);
12026                            miscPss[j] += mem;
12027                            otherPss -= mem;
12028                        }
12029                        oomPss[0] += myTotalPss;
12030                        if (oomProcs[0] == null) {
12031                            oomProcs[0] = new ArrayList<MemItem>();
12032                        }
12033                        oomProcs[0].add(pssItem);
12034                    }
12035                }
12036            }
12037
12038            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12039
12040            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12041            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12042            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12043            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12044                String label = Debug.MemoryInfo.getOtherLabel(j);
12045                catMems.add(new MemItem(label, label, miscPss[j], j));
12046            }
12047
12048            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12049            for (int j=0; j<oomPss.length; j++) {
12050                if (oomPss[j] != 0) {
12051                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12052                            : DUMP_MEM_OOM_LABEL[j];
12053                    MemItem item = new MemItem(label, label, oomPss[j],
12054                            DUMP_MEM_OOM_ADJ[j]);
12055                    item.subitems = oomProcs[j];
12056                    oomMems.add(item);
12057                }
12058            }
12059
12060            if (!brief && !oomOnly && !isCompact) {
12061                pw.println();
12062                pw.println("Total PSS by process:");
12063                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12064                pw.println();
12065            }
12066            if (!isCompact) {
12067                pw.println("Total PSS by OOM adjustment:");
12068            }
12069            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12070            if (!brief && !oomOnly) {
12071                PrintWriter out = categoryPw != null ? categoryPw : pw;
12072                if (!isCompact) {
12073                    out.println();
12074                    out.println("Total PSS by category:");
12075                }
12076                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12077            }
12078            if (!isCompact) {
12079                pw.println();
12080            }
12081            MemInfoReader memInfo = new MemInfoReader();
12082            memInfo.readMemInfo();
12083            if (!brief) {
12084                if (!isCompact) {
12085                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12086                    pw.println(" kB");
12087                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12088                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12089                            pw.print(cachedPss); pw.print(" cached pss + ");
12090                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12091                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12092                } else {
12093                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12094                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12095                            + memInfo.getFreeSizeKb()); pw.print(",");
12096                    pw.println(totalPss - cachedPss);
12097                }
12098            }
12099            if (!isCompact) {
12100                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12101                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12102                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12103                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12104                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12105                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12106                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12107                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12108                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12109                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12110                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12111            }
12112            if (!brief) {
12113                if (memInfo.getZramTotalSizeKb() != 0) {
12114                    if (!isCompact) {
12115                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12116                                pw.print(" kB physical used for ");
12117                                pw.print(memInfo.getSwapTotalSizeKb()
12118                                        - memInfo.getSwapFreeSizeKb());
12119                                pw.print(" kB in swap (");
12120                                pw.print(memInfo.getSwapTotalSizeKb());
12121                                pw.println(" kB total swap)");
12122                    } else {
12123                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12124                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12125                                pw.println(memInfo.getSwapFreeSizeKb());
12126                    }
12127                }
12128                final int[] SINGLE_LONG_FORMAT = new int[] {
12129                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12130                };
12131                long[] longOut = new long[1];
12132                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12133                        SINGLE_LONG_FORMAT, null, longOut, null);
12134                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12135                longOut[0] = 0;
12136                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12137                        SINGLE_LONG_FORMAT, null, longOut, null);
12138                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12139                longOut[0] = 0;
12140                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12141                        SINGLE_LONG_FORMAT, null, longOut, null);
12142                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12143                longOut[0] = 0;
12144                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12145                        SINGLE_LONG_FORMAT, null, longOut, null);
12146                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12147                if (!isCompact) {
12148                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12149                        pw.print("      KSM: "); pw.print(sharing);
12150                                pw.print(" kB saved from shared ");
12151                                pw.print(shared); pw.println(" kB");
12152                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12153                                pw.print(voltile); pw.println(" kB volatile");
12154                    }
12155                    pw.print("   Tuning: ");
12156                    pw.print(ActivityManager.staticGetMemoryClass());
12157                    pw.print(" (large ");
12158                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12159                    pw.print("), oom ");
12160                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12161                    pw.print(" kB");
12162                    pw.print(", restore limit ");
12163                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12164                    pw.print(" kB");
12165                    if (ActivityManager.isLowRamDeviceStatic()) {
12166                        pw.print(" (low-ram)");
12167                    }
12168                    if (ActivityManager.isHighEndGfx()) {
12169                        pw.print(" (high-end-gfx)");
12170                    }
12171                    pw.println();
12172                } else {
12173                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12174                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12175                    pw.println(voltile);
12176                    pw.print("tuning,");
12177                    pw.print(ActivityManager.staticGetMemoryClass());
12178                    pw.print(',');
12179                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12180                    pw.print(',');
12181                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12182                    if (ActivityManager.isLowRamDeviceStatic()) {
12183                        pw.print(",low-ram");
12184                    }
12185                    if (ActivityManager.isHighEndGfx()) {
12186                        pw.print(",high-end-gfx");
12187                    }
12188                    pw.println();
12189                }
12190            }
12191        }
12192    }
12193
12194    /**
12195     * Searches array of arguments for the specified string
12196     * @param args array of argument strings
12197     * @param value value to search for
12198     * @return true if the value is contained in the array
12199     */
12200    private static boolean scanArgs(String[] args, String value) {
12201        if (args != null) {
12202            for (String arg : args) {
12203                if (value.equals(arg)) {
12204                    return true;
12205                }
12206            }
12207        }
12208        return false;
12209    }
12210
12211    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12212            ContentProviderRecord cpr, boolean always) {
12213        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12214
12215        if (!inLaunching || always) {
12216            synchronized (cpr) {
12217                cpr.launchingApp = null;
12218                cpr.notifyAll();
12219            }
12220            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12221            String names[] = cpr.info.authority.split(";");
12222            for (int j = 0; j < names.length; j++) {
12223                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12224            }
12225        }
12226
12227        for (int i=0; i<cpr.connections.size(); i++) {
12228            ContentProviderConnection conn = cpr.connections.get(i);
12229            if (conn.waiting) {
12230                // If this connection is waiting for the provider, then we don't
12231                // need to mess with its process unless we are always removing
12232                // or for some reason the provider is not currently launching.
12233                if (inLaunching && !always) {
12234                    continue;
12235                }
12236            }
12237            ProcessRecord capp = conn.client;
12238            conn.dead = true;
12239            if (conn.stableCount > 0) {
12240                if (!capp.persistent && capp.thread != null
12241                        && capp.pid != 0
12242                        && capp.pid != MY_PID) {
12243                    killUnneededProcessLocked(capp, "depends on provider "
12244                            + cpr.name.flattenToShortString()
12245                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12246                }
12247            } else if (capp.thread != null && conn.provider.provider != null) {
12248                try {
12249                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12250                } catch (RemoteException e) {
12251                }
12252                // In the protocol here, we don't expect the client to correctly
12253                // clean up this connection, we'll just remove it.
12254                cpr.connections.remove(i);
12255                conn.client.conProviders.remove(conn);
12256            }
12257        }
12258
12259        if (inLaunching && always) {
12260            mLaunchingProviders.remove(cpr);
12261        }
12262        return inLaunching;
12263    }
12264
12265    /**
12266     * Main code for cleaning up a process when it has gone away.  This is
12267     * called both as a result of the process dying, or directly when stopping
12268     * a process when running in single process mode.
12269     */
12270    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12271            boolean restarting, boolean allowRestart, int index) {
12272        if (index >= 0) {
12273            removeLruProcessLocked(app);
12274            ProcessList.remove(app.pid);
12275        }
12276
12277        mProcessesToGc.remove(app);
12278        mPendingPssProcesses.remove(app);
12279
12280        // Dismiss any open dialogs.
12281        if (app.crashDialog != null && !app.forceCrashReport) {
12282            app.crashDialog.dismiss();
12283            app.crashDialog = null;
12284        }
12285        if (app.anrDialog != null) {
12286            app.anrDialog.dismiss();
12287            app.anrDialog = null;
12288        }
12289        if (app.waitDialog != null) {
12290            app.waitDialog.dismiss();
12291            app.waitDialog = null;
12292        }
12293
12294        app.crashing = false;
12295        app.notResponding = false;
12296
12297        app.resetPackageList(mProcessStats);
12298        app.unlinkDeathRecipient();
12299        app.makeInactive(mProcessStats);
12300        app.forcingToForeground = null;
12301        app.foregroundServices = false;
12302        app.foregroundActivities = false;
12303        app.hasShownUi = false;
12304        app.hasAboveClient = false;
12305
12306        mServices.killServicesLocked(app, allowRestart);
12307
12308        boolean restart = false;
12309
12310        // Remove published content providers.
12311        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12312            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12313            final boolean always = app.bad || !allowRestart;
12314            if (removeDyingProviderLocked(app, cpr, always) || always) {
12315                // We left the provider in the launching list, need to
12316                // restart it.
12317                restart = true;
12318            }
12319
12320            cpr.provider = null;
12321            cpr.proc = null;
12322        }
12323        app.pubProviders.clear();
12324
12325        // Take care of any launching providers waiting for this process.
12326        if (checkAppInLaunchingProvidersLocked(app, false)) {
12327            restart = true;
12328        }
12329
12330        // Unregister from connected content providers.
12331        if (!app.conProviders.isEmpty()) {
12332            for (int i=0; i<app.conProviders.size(); i++) {
12333                ContentProviderConnection conn = app.conProviders.get(i);
12334                conn.provider.connections.remove(conn);
12335            }
12336            app.conProviders.clear();
12337        }
12338
12339        // At this point there may be remaining entries in mLaunchingProviders
12340        // where we were the only one waiting, so they are no longer of use.
12341        // Look for these and clean up if found.
12342        // XXX Commented out for now.  Trying to figure out a way to reproduce
12343        // the actual situation to identify what is actually going on.
12344        if (false) {
12345            for (int i=0; i<mLaunchingProviders.size(); i++) {
12346                ContentProviderRecord cpr = (ContentProviderRecord)
12347                        mLaunchingProviders.get(i);
12348                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12349                    synchronized (cpr) {
12350                        cpr.launchingApp = null;
12351                        cpr.notifyAll();
12352                    }
12353                }
12354            }
12355        }
12356
12357        skipCurrentReceiverLocked(app);
12358
12359        // Unregister any receivers.
12360        for (int i=app.receivers.size()-1; i>=0; i--) {
12361            removeReceiverLocked(app.receivers.valueAt(i));
12362        }
12363        app.receivers.clear();
12364
12365        // If the app is undergoing backup, tell the backup manager about it
12366        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12367            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12368                    + mBackupTarget.appInfo + " died during backup");
12369            try {
12370                IBackupManager bm = IBackupManager.Stub.asInterface(
12371                        ServiceManager.getService(Context.BACKUP_SERVICE));
12372                bm.agentDisconnected(app.info.packageName);
12373            } catch (RemoteException e) {
12374                // can't happen; backup manager is local
12375            }
12376        }
12377
12378        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12379            ProcessChangeItem item = mPendingProcessChanges.get(i);
12380            if (item.pid == app.pid) {
12381                mPendingProcessChanges.remove(i);
12382                mAvailProcessChanges.add(item);
12383            }
12384        }
12385        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12386
12387        // If the caller is restarting this app, then leave it in its
12388        // current lists and let the caller take care of it.
12389        if (restarting) {
12390            return;
12391        }
12392
12393        if (!app.persistent || app.isolated) {
12394            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12395                    "Removing non-persistent process during cleanup: " + app);
12396            mProcessNames.remove(app.processName, app.uid);
12397            mIsolatedProcesses.remove(app.uid);
12398            if (mHeavyWeightProcess == app) {
12399                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12400                        mHeavyWeightProcess.userId, 0));
12401                mHeavyWeightProcess = null;
12402            }
12403        } else if (!app.removed) {
12404            // This app is persistent, so we need to keep its record around.
12405            // If it is not already on the pending app list, add it there
12406            // and start a new process for it.
12407            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12408                mPersistentStartingProcesses.add(app);
12409                restart = true;
12410            }
12411        }
12412        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12413                "Clean-up removing on hold: " + app);
12414        mProcessesOnHold.remove(app);
12415
12416        if (app == mHomeProcess) {
12417            mHomeProcess = null;
12418        }
12419        if (app == mPreviousProcess) {
12420            mPreviousProcess = null;
12421        }
12422
12423        if (restart && !app.isolated) {
12424            // We have components that still need to be running in the
12425            // process, so re-launch it.
12426            mProcessNames.put(app.processName, app.uid, app);
12427            startProcessLocked(app, "restart", app.processName);
12428        } else if (app.pid > 0 && app.pid != MY_PID) {
12429            // Goodbye!
12430            synchronized (mPidsSelfLocked) {
12431                mPidsSelfLocked.remove(app.pid);
12432                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12433            }
12434            app.setPid(0);
12435        }
12436    }
12437
12438    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12439        // Look through the content providers we are waiting to have launched,
12440        // and if any run in this process then either schedule a restart of
12441        // the process or kill the client waiting for it if this process has
12442        // gone bad.
12443        int NL = mLaunchingProviders.size();
12444        boolean restart = false;
12445        for (int i=0; i<NL; i++) {
12446            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12447            if (cpr.launchingApp == app) {
12448                if (!alwaysBad && !app.bad) {
12449                    restart = true;
12450                } else {
12451                    removeDyingProviderLocked(app, cpr, true);
12452                    // cpr should have been removed from mLaunchingProviders
12453                    NL = mLaunchingProviders.size();
12454                    i--;
12455                }
12456            }
12457        }
12458        return restart;
12459    }
12460
12461    // =========================================================
12462    // SERVICES
12463    // =========================================================
12464
12465    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12466            int flags) {
12467        enforceNotIsolatedCaller("getServices");
12468        synchronized (this) {
12469            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12470        }
12471    }
12472
12473    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12474        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12475        synchronized (this) {
12476            return mServices.getRunningServiceControlPanelLocked(name);
12477        }
12478    }
12479
12480    public ComponentName startService(IApplicationThread caller, Intent service,
12481            String resolvedType, int userId) {
12482        enforceNotIsolatedCaller("startService");
12483        // Refuse possible leaked file descriptors
12484        if (service != null && service.hasFileDescriptors() == true) {
12485            throw new IllegalArgumentException("File descriptors passed in Intent");
12486        }
12487
12488        if (DEBUG_SERVICE)
12489            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12490        synchronized(this) {
12491            final int callingPid = Binder.getCallingPid();
12492            final int callingUid = Binder.getCallingUid();
12493            final long origId = Binder.clearCallingIdentity();
12494            ComponentName res = mServices.startServiceLocked(caller, service,
12495                    resolvedType, callingPid, callingUid, userId);
12496            Binder.restoreCallingIdentity(origId);
12497            return res;
12498        }
12499    }
12500
12501    ComponentName startServiceInPackage(int uid,
12502            Intent service, String resolvedType, int userId) {
12503        synchronized(this) {
12504            if (DEBUG_SERVICE)
12505                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12506            final long origId = Binder.clearCallingIdentity();
12507            ComponentName res = mServices.startServiceLocked(null, service,
12508                    resolvedType, -1, uid, userId);
12509            Binder.restoreCallingIdentity(origId);
12510            return res;
12511        }
12512    }
12513
12514    public int stopService(IApplicationThread caller, Intent service,
12515            String resolvedType, int userId) {
12516        enforceNotIsolatedCaller("stopService");
12517        // Refuse possible leaked file descriptors
12518        if (service != null && service.hasFileDescriptors() == true) {
12519            throw new IllegalArgumentException("File descriptors passed in Intent");
12520        }
12521
12522        synchronized(this) {
12523            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12524        }
12525    }
12526
12527    public IBinder peekService(Intent service, String resolvedType) {
12528        enforceNotIsolatedCaller("peekService");
12529        // Refuse possible leaked file descriptors
12530        if (service != null && service.hasFileDescriptors() == true) {
12531            throw new IllegalArgumentException("File descriptors passed in Intent");
12532        }
12533        synchronized(this) {
12534            return mServices.peekServiceLocked(service, resolvedType);
12535        }
12536    }
12537
12538    public boolean stopServiceToken(ComponentName className, IBinder token,
12539            int startId) {
12540        synchronized(this) {
12541            return mServices.stopServiceTokenLocked(className, token, startId);
12542        }
12543    }
12544
12545    public void setServiceForeground(ComponentName className, IBinder token,
12546            int id, Notification notification, boolean removeNotification) {
12547        synchronized(this) {
12548            mServices.setServiceForegroundLocked(className, token, id, notification,
12549                    removeNotification);
12550        }
12551    }
12552
12553    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12554            boolean requireFull, String name, String callerPackage) {
12555        final int callingUserId = UserHandle.getUserId(callingUid);
12556        if (callingUserId != userId) {
12557            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12558                if ((requireFull || checkComponentPermission(
12559                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12560                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12561                        && checkComponentPermission(
12562                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12563                                callingPid, callingUid, -1, true)
12564                                != PackageManager.PERMISSION_GRANTED) {
12565                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12566                        // In this case, they would like to just execute as their
12567                        // owner user instead of failing.
12568                        userId = callingUserId;
12569                    } else {
12570                        StringBuilder builder = new StringBuilder(128);
12571                        builder.append("Permission Denial: ");
12572                        builder.append(name);
12573                        if (callerPackage != null) {
12574                            builder.append(" from ");
12575                            builder.append(callerPackage);
12576                        }
12577                        builder.append(" asks to run as user ");
12578                        builder.append(userId);
12579                        builder.append(" but is calling from user ");
12580                        builder.append(UserHandle.getUserId(callingUid));
12581                        builder.append("; this requires ");
12582                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12583                        if (!requireFull) {
12584                            builder.append(" or ");
12585                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12586                        }
12587                        String msg = builder.toString();
12588                        Slog.w(TAG, msg);
12589                        throw new SecurityException(msg);
12590                    }
12591                }
12592            }
12593            if (userId == UserHandle.USER_CURRENT
12594                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12595                // Note that we may be accessing this outside of a lock...
12596                // shouldn't be a big deal, if this is being called outside
12597                // of a locked context there is intrinsically a race with
12598                // the value the caller will receive and someone else changing it.
12599                userId = mCurrentUserId;
12600            }
12601            if (!allowAll && userId < 0) {
12602                throw new IllegalArgumentException(
12603                        "Call does not support special user #" + userId);
12604            }
12605        }
12606        return userId;
12607    }
12608
12609    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12610            String className, int flags) {
12611        boolean result = false;
12612        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12613            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12614                if (ActivityManager.checkUidPermission(
12615                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12616                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12617                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12618                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12619                            + " requests FLAG_SINGLE_USER, but app does not hold "
12620                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12621                    Slog.w(TAG, msg);
12622                    throw new SecurityException(msg);
12623                }
12624                result = true;
12625            }
12626        } else if (componentProcessName == aInfo.packageName) {
12627            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12628        } else if ("system".equals(componentProcessName)) {
12629            result = true;
12630        }
12631        if (DEBUG_MU) {
12632            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12633                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12634        }
12635        return result;
12636    }
12637
12638    public int bindService(IApplicationThread caller, IBinder token,
12639            Intent service, String resolvedType,
12640            IServiceConnection connection, int flags, int userId) {
12641        enforceNotIsolatedCaller("bindService");
12642        // Refuse possible leaked file descriptors
12643        if (service != null && service.hasFileDescriptors() == true) {
12644            throw new IllegalArgumentException("File descriptors passed in Intent");
12645        }
12646
12647        synchronized(this) {
12648            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12649                    connection, flags, userId);
12650        }
12651    }
12652
12653    public boolean unbindService(IServiceConnection connection) {
12654        synchronized (this) {
12655            return mServices.unbindServiceLocked(connection);
12656        }
12657    }
12658
12659    public void publishService(IBinder token, Intent intent, IBinder service) {
12660        // Refuse possible leaked file descriptors
12661        if (intent != null && intent.hasFileDescriptors() == true) {
12662            throw new IllegalArgumentException("File descriptors passed in Intent");
12663        }
12664
12665        synchronized(this) {
12666            if (!(token instanceof ServiceRecord)) {
12667                throw new IllegalArgumentException("Invalid service token");
12668            }
12669            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12670        }
12671    }
12672
12673    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12674        // Refuse possible leaked file descriptors
12675        if (intent != null && intent.hasFileDescriptors() == true) {
12676            throw new IllegalArgumentException("File descriptors passed in Intent");
12677        }
12678
12679        synchronized(this) {
12680            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12681        }
12682    }
12683
12684    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12685        synchronized(this) {
12686            if (!(token instanceof ServiceRecord)) {
12687                throw new IllegalArgumentException("Invalid service token");
12688            }
12689            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12690        }
12691    }
12692
12693    // =========================================================
12694    // BACKUP AND RESTORE
12695    // =========================================================
12696
12697    // Cause the target app to be launched if necessary and its backup agent
12698    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12699    // activity manager to announce its creation.
12700    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12701        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12702        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12703
12704        synchronized(this) {
12705            // !!! TODO: currently no check here that we're already bound
12706            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12707            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12708            synchronized (stats) {
12709                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12710            }
12711
12712            // Backup agent is now in use, its package can't be stopped.
12713            try {
12714                AppGlobals.getPackageManager().setPackageStoppedState(
12715                        app.packageName, false, UserHandle.getUserId(app.uid));
12716            } catch (RemoteException e) {
12717            } catch (IllegalArgumentException e) {
12718                Slog.w(TAG, "Failed trying to unstop package "
12719                        + app.packageName + ": " + e);
12720            }
12721
12722            BackupRecord r = new BackupRecord(ss, app, backupMode);
12723            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12724                    ? new ComponentName(app.packageName, app.backupAgentName)
12725                    : new ComponentName("android", "FullBackupAgent");
12726            // startProcessLocked() returns existing proc's record if it's already running
12727            ProcessRecord proc = startProcessLocked(app.processName, app,
12728                    false, 0, "backup", hostingName, false, false, false);
12729            if (proc == null) {
12730                Slog.e(TAG, "Unable to start backup agent process " + r);
12731                return false;
12732            }
12733
12734            r.app = proc;
12735            mBackupTarget = r;
12736            mBackupAppName = app.packageName;
12737
12738            // Try not to kill the process during backup
12739            updateOomAdjLocked(proc);
12740
12741            // If the process is already attached, schedule the creation of the backup agent now.
12742            // If it is not yet live, this will be done when it attaches to the framework.
12743            if (proc.thread != null) {
12744                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12745                try {
12746                    proc.thread.scheduleCreateBackupAgent(app,
12747                            compatibilityInfoForPackageLocked(app), backupMode);
12748                } catch (RemoteException e) {
12749                    // Will time out on the backup manager side
12750                }
12751            } else {
12752                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12753            }
12754            // Invariants: at this point, the target app process exists and the application
12755            // is either already running or in the process of coming up.  mBackupTarget and
12756            // mBackupAppName describe the app, so that when it binds back to the AM we
12757            // know that it's scheduled for a backup-agent operation.
12758        }
12759
12760        return true;
12761    }
12762
12763    @Override
12764    public void clearPendingBackup() {
12765        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12766        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12767
12768        synchronized (this) {
12769            mBackupTarget = null;
12770            mBackupAppName = null;
12771        }
12772    }
12773
12774    // A backup agent has just come up
12775    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12776        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12777                + " = " + agent);
12778
12779        synchronized(this) {
12780            if (!agentPackageName.equals(mBackupAppName)) {
12781                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12782                return;
12783            }
12784        }
12785
12786        long oldIdent = Binder.clearCallingIdentity();
12787        try {
12788            IBackupManager bm = IBackupManager.Stub.asInterface(
12789                    ServiceManager.getService(Context.BACKUP_SERVICE));
12790            bm.agentConnected(agentPackageName, agent);
12791        } catch (RemoteException e) {
12792            // can't happen; the backup manager service is local
12793        } catch (Exception e) {
12794            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12795            e.printStackTrace();
12796        } finally {
12797            Binder.restoreCallingIdentity(oldIdent);
12798        }
12799    }
12800
12801    // done with this agent
12802    public void unbindBackupAgent(ApplicationInfo appInfo) {
12803        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12804        if (appInfo == null) {
12805            Slog.w(TAG, "unbind backup agent for null app");
12806            return;
12807        }
12808
12809        synchronized(this) {
12810            try {
12811                if (mBackupAppName == null) {
12812                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12813                    return;
12814                }
12815
12816                if (!mBackupAppName.equals(appInfo.packageName)) {
12817                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12818                    return;
12819                }
12820
12821                // Not backing this app up any more; reset its OOM adjustment
12822                final ProcessRecord proc = mBackupTarget.app;
12823                updateOomAdjLocked(proc);
12824
12825                // If the app crashed during backup, 'thread' will be null here
12826                if (proc.thread != null) {
12827                    try {
12828                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12829                                compatibilityInfoForPackageLocked(appInfo));
12830                    } catch (Exception e) {
12831                        Slog.e(TAG, "Exception when unbinding backup agent:");
12832                        e.printStackTrace();
12833                    }
12834                }
12835            } finally {
12836                mBackupTarget = null;
12837                mBackupAppName = null;
12838            }
12839        }
12840    }
12841    // =========================================================
12842    // BROADCASTS
12843    // =========================================================
12844
12845    private final List getStickiesLocked(String action, IntentFilter filter,
12846            List cur, int userId) {
12847        final ContentResolver resolver = mContext.getContentResolver();
12848        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12849        if (stickies == null) {
12850            return cur;
12851        }
12852        final ArrayList<Intent> list = stickies.get(action);
12853        if (list == null) {
12854            return cur;
12855        }
12856        int N = list.size();
12857        for (int i=0; i<N; i++) {
12858            Intent intent = list.get(i);
12859            if (filter.match(resolver, intent, true, TAG) >= 0) {
12860                if (cur == null) {
12861                    cur = new ArrayList<Intent>();
12862                }
12863                cur.add(intent);
12864            }
12865        }
12866        return cur;
12867    }
12868
12869    boolean isPendingBroadcastProcessLocked(int pid) {
12870        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12871                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12872    }
12873
12874    void skipPendingBroadcastLocked(int pid) {
12875            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12876            for (BroadcastQueue queue : mBroadcastQueues) {
12877                queue.skipPendingBroadcastLocked(pid);
12878            }
12879    }
12880
12881    // The app just attached; send any pending broadcasts that it should receive
12882    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12883        boolean didSomething = false;
12884        for (BroadcastQueue queue : mBroadcastQueues) {
12885            didSomething |= queue.sendPendingBroadcastsLocked(app);
12886        }
12887        return didSomething;
12888    }
12889
12890    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12891            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12892        enforceNotIsolatedCaller("registerReceiver");
12893        int callingUid;
12894        int callingPid;
12895        synchronized(this) {
12896            ProcessRecord callerApp = null;
12897            if (caller != null) {
12898                callerApp = getRecordForAppLocked(caller);
12899                if (callerApp == null) {
12900                    throw new SecurityException(
12901                            "Unable to find app for caller " + caller
12902                            + " (pid=" + Binder.getCallingPid()
12903                            + ") when registering receiver " + receiver);
12904                }
12905                if (callerApp.info.uid != Process.SYSTEM_UID &&
12906                        !callerApp.pkgList.containsKey(callerPackage) &&
12907                        !"android".equals(callerPackage)) {
12908                    throw new SecurityException("Given caller package " + callerPackage
12909                            + " is not running in process " + callerApp);
12910                }
12911                callingUid = callerApp.info.uid;
12912                callingPid = callerApp.pid;
12913            } else {
12914                callerPackage = null;
12915                callingUid = Binder.getCallingUid();
12916                callingPid = Binder.getCallingPid();
12917            }
12918
12919            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12920                    true, true, "registerReceiver", callerPackage);
12921
12922            List allSticky = null;
12923
12924            // Look for any matching sticky broadcasts...
12925            Iterator actions = filter.actionsIterator();
12926            if (actions != null) {
12927                while (actions.hasNext()) {
12928                    String action = (String)actions.next();
12929                    allSticky = getStickiesLocked(action, filter, allSticky,
12930                            UserHandle.USER_ALL);
12931                    allSticky = getStickiesLocked(action, filter, allSticky,
12932                            UserHandle.getUserId(callingUid));
12933                }
12934            } else {
12935                allSticky = getStickiesLocked(null, filter, allSticky,
12936                        UserHandle.USER_ALL);
12937                allSticky = getStickiesLocked(null, filter, allSticky,
12938                        UserHandle.getUserId(callingUid));
12939            }
12940
12941            // The first sticky in the list is returned directly back to
12942            // the client.
12943            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12944
12945            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12946                    + ": " + sticky);
12947
12948            if (receiver == null) {
12949                return sticky;
12950            }
12951
12952            ReceiverList rl
12953                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12954            if (rl == null) {
12955                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
12956                        userId, receiver);
12957                if (rl.app != null) {
12958                    rl.app.receivers.add(rl);
12959                } else {
12960                    try {
12961                        receiver.asBinder().linkToDeath(rl, 0);
12962                    } catch (RemoteException e) {
12963                        return sticky;
12964                    }
12965                    rl.linkedToDeath = true;
12966                }
12967                mRegisteredReceivers.put(receiver.asBinder(), rl);
12968            } else if (rl.uid != callingUid) {
12969                throw new IllegalArgumentException(
12970                        "Receiver requested to register for uid " + callingUid
12971                        + " was previously registered for uid " + rl.uid);
12972            } else if (rl.pid != callingPid) {
12973                throw new IllegalArgumentException(
12974                        "Receiver requested to register for pid " + callingPid
12975                        + " was previously registered for pid " + rl.pid);
12976            } else if (rl.userId != userId) {
12977                throw new IllegalArgumentException(
12978                        "Receiver requested to register for user " + userId
12979                        + " was previously registered for user " + rl.userId);
12980            }
12981            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
12982                    permission, callingUid, userId);
12983            rl.add(bf);
12984            if (!bf.debugCheck()) {
12985                Slog.w(TAG, "==> For Dynamic broadast");
12986            }
12987            mReceiverResolver.addFilter(bf);
12988
12989            // Enqueue broadcasts for all existing stickies that match
12990            // this filter.
12991            if (allSticky != null) {
12992                ArrayList receivers = new ArrayList();
12993                receivers.add(bf);
12994
12995                int N = allSticky.size();
12996                for (int i=0; i<N; i++) {
12997                    Intent intent = (Intent)allSticky.get(i);
12998                    BroadcastQueue queue = broadcastQueueForIntent(intent);
12999                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13000                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13001                            null, null, false, true, true, -1);
13002                    queue.enqueueParallelBroadcastLocked(r);
13003                    queue.scheduleBroadcastsLocked();
13004                }
13005            }
13006
13007            return sticky;
13008        }
13009    }
13010
13011    public void unregisterReceiver(IIntentReceiver receiver) {
13012        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13013
13014        final long origId = Binder.clearCallingIdentity();
13015        try {
13016            boolean doTrim = false;
13017
13018            synchronized(this) {
13019                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13020                if (rl != null) {
13021                    if (rl.curBroadcast != null) {
13022                        BroadcastRecord r = rl.curBroadcast;
13023                        final boolean doNext = finishReceiverLocked(
13024                                receiver.asBinder(), r.resultCode, r.resultData,
13025                                r.resultExtras, r.resultAbort);
13026                        if (doNext) {
13027                            doTrim = true;
13028                            r.queue.processNextBroadcast(false);
13029                        }
13030                    }
13031
13032                    if (rl.app != null) {
13033                        rl.app.receivers.remove(rl);
13034                    }
13035                    removeReceiverLocked(rl);
13036                    if (rl.linkedToDeath) {
13037                        rl.linkedToDeath = false;
13038                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13039                    }
13040                }
13041            }
13042
13043            // If we actually concluded any broadcasts, we might now be able
13044            // to trim the recipients' apps from our working set
13045            if (doTrim) {
13046                trimApplications();
13047                return;
13048            }
13049
13050        } finally {
13051            Binder.restoreCallingIdentity(origId);
13052        }
13053    }
13054
13055    void removeReceiverLocked(ReceiverList rl) {
13056        mRegisteredReceivers.remove(rl.receiver.asBinder());
13057        int N = rl.size();
13058        for (int i=0; i<N; i++) {
13059            mReceiverResolver.removeFilter(rl.get(i));
13060        }
13061    }
13062
13063    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13064        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13065            ProcessRecord r = mLruProcesses.get(i);
13066            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13067                try {
13068                    r.thread.dispatchPackageBroadcast(cmd, packages);
13069                } catch (RemoteException ex) {
13070                }
13071            }
13072        }
13073    }
13074
13075    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13076            int[] users) {
13077        List<ResolveInfo> receivers = null;
13078        try {
13079            HashSet<ComponentName> singleUserReceivers = null;
13080            boolean scannedFirstReceivers = false;
13081            for (int user : users) {
13082                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13083                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13084                if (user != 0 && newReceivers != null) {
13085                    // If this is not the primary user, we need to check for
13086                    // any receivers that should be filtered out.
13087                    for (int i=0; i<newReceivers.size(); i++) {
13088                        ResolveInfo ri = newReceivers.get(i);
13089                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13090                            newReceivers.remove(i);
13091                            i--;
13092                        }
13093                    }
13094                }
13095                if (newReceivers != null && newReceivers.size() == 0) {
13096                    newReceivers = null;
13097                }
13098                if (receivers == null) {
13099                    receivers = newReceivers;
13100                } else if (newReceivers != null) {
13101                    // We need to concatenate the additional receivers
13102                    // found with what we have do far.  This would be easy,
13103                    // but we also need to de-dup any receivers that are
13104                    // singleUser.
13105                    if (!scannedFirstReceivers) {
13106                        // Collect any single user receivers we had already retrieved.
13107                        scannedFirstReceivers = true;
13108                        for (int i=0; i<receivers.size(); i++) {
13109                            ResolveInfo ri = receivers.get(i);
13110                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13111                                ComponentName cn = new ComponentName(
13112                                        ri.activityInfo.packageName, ri.activityInfo.name);
13113                                if (singleUserReceivers == null) {
13114                                    singleUserReceivers = new HashSet<ComponentName>();
13115                                }
13116                                singleUserReceivers.add(cn);
13117                            }
13118                        }
13119                    }
13120                    // Add the new results to the existing results, tracking
13121                    // and de-dupping single user receivers.
13122                    for (int i=0; i<newReceivers.size(); i++) {
13123                        ResolveInfo ri = newReceivers.get(i);
13124                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13125                            ComponentName cn = new ComponentName(
13126                                    ri.activityInfo.packageName, ri.activityInfo.name);
13127                            if (singleUserReceivers == null) {
13128                                singleUserReceivers = new HashSet<ComponentName>();
13129                            }
13130                            if (!singleUserReceivers.contains(cn)) {
13131                                singleUserReceivers.add(cn);
13132                                receivers.add(ri);
13133                            }
13134                        } else {
13135                            receivers.add(ri);
13136                        }
13137                    }
13138                }
13139            }
13140        } catch (RemoteException ex) {
13141            // pm is in same process, this will never happen.
13142        }
13143        return receivers;
13144    }
13145
13146    private final int broadcastIntentLocked(ProcessRecord callerApp,
13147            String callerPackage, Intent intent, String resolvedType,
13148            IIntentReceiver resultTo, int resultCode, String resultData,
13149            Bundle map, String requiredPermission, int appOp,
13150            boolean ordered, boolean sticky, int callingPid, int callingUid,
13151            int userId) {
13152        intent = new Intent(intent);
13153
13154        // By default broadcasts do not go to stopped apps.
13155        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13156
13157        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13158            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13159            + " ordered=" + ordered + " userid=" + userId);
13160        if ((resultTo != null) && !ordered) {
13161            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13162        }
13163
13164        userId = handleIncomingUser(callingPid, callingUid, userId,
13165                true, false, "broadcast", callerPackage);
13166
13167        // Make sure that the user who is receiving this broadcast is started.
13168        // If not, we will just skip it.
13169        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13170            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13171                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13172                Slog.w(TAG, "Skipping broadcast of " + intent
13173                        + ": user " + userId + " is stopped");
13174                return ActivityManager.BROADCAST_SUCCESS;
13175            }
13176        }
13177
13178        /*
13179         * Prevent non-system code (defined here to be non-persistent
13180         * processes) from sending protected broadcasts.
13181         */
13182        int callingAppId = UserHandle.getAppId(callingUid);
13183        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13184            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13185            callingUid == 0) {
13186            // Always okay.
13187        } else if (callerApp == null || !callerApp.persistent) {
13188            try {
13189                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13190                        intent.getAction())) {
13191                    String msg = "Permission Denial: not allowed to send broadcast "
13192                            + intent.getAction() + " from pid="
13193                            + callingPid + ", uid=" + callingUid;
13194                    Slog.w(TAG, msg);
13195                    throw new SecurityException(msg);
13196                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13197                    // Special case for compatibility: we don't want apps to send this,
13198                    // but historically it has not been protected and apps may be using it
13199                    // to poke their own app widget.  So, instead of making it protected,
13200                    // just limit it to the caller.
13201                    if (callerApp == null) {
13202                        String msg = "Permission Denial: not allowed to send broadcast "
13203                                + intent.getAction() + " from unknown caller.";
13204                        Slog.w(TAG, msg);
13205                        throw new SecurityException(msg);
13206                    } else if (intent.getComponent() != null) {
13207                        // They are good enough to send to an explicit component...  verify
13208                        // it is being sent to the calling app.
13209                        if (!intent.getComponent().getPackageName().equals(
13210                                callerApp.info.packageName)) {
13211                            String msg = "Permission Denial: not allowed to send broadcast "
13212                                    + intent.getAction() + " to "
13213                                    + intent.getComponent().getPackageName() + " from "
13214                                    + callerApp.info.packageName;
13215                            Slog.w(TAG, msg);
13216                            throw new SecurityException(msg);
13217                        }
13218                    } else {
13219                        // Limit broadcast to their own package.
13220                        intent.setPackage(callerApp.info.packageName);
13221                    }
13222                }
13223            } catch (RemoteException e) {
13224                Slog.w(TAG, "Remote exception", e);
13225                return ActivityManager.BROADCAST_SUCCESS;
13226            }
13227        }
13228
13229        // Handle special intents: if this broadcast is from the package
13230        // manager about a package being removed, we need to remove all of
13231        // its activities from the history stack.
13232        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13233                intent.getAction());
13234        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13235                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13236                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13237                || uidRemoved) {
13238            if (checkComponentPermission(
13239                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13240                    callingPid, callingUid, -1, true)
13241                    == PackageManager.PERMISSION_GRANTED) {
13242                if (uidRemoved) {
13243                    final Bundle intentExtras = intent.getExtras();
13244                    final int uid = intentExtras != null
13245                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13246                    if (uid >= 0) {
13247                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13248                        synchronized (bs) {
13249                            bs.removeUidStatsLocked(uid);
13250                        }
13251                        mAppOpsService.uidRemoved(uid);
13252                    }
13253                } else {
13254                    // If resources are unavailable just force stop all
13255                    // those packages and flush the attribute cache as well.
13256                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13257                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13258                        if (list != null && (list.length > 0)) {
13259                            for (String pkg : list) {
13260                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
13261                                        "storage unmount");
13262                            }
13263                            sendPackageBroadcastLocked(
13264                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13265                        }
13266                    } else {
13267                        Uri data = intent.getData();
13268                        String ssp;
13269                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13270                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13271                                    intent.getAction());
13272                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13273                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13274                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13275                                        false, userId, removed ? "pkg removed" : "pkg changed");
13276                            }
13277                            if (removed) {
13278                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13279                                        new String[] {ssp}, userId);
13280                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13281                                    mAppOpsService.packageRemoved(
13282                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13283
13284                                    // Remove all permissions granted from/to this package
13285                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13286                                }
13287                            }
13288                        }
13289                    }
13290                }
13291            } else {
13292                String msg = "Permission Denial: " + intent.getAction()
13293                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13294                        + ", uid=" + callingUid + ")"
13295                        + " requires "
13296                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13297                Slog.w(TAG, msg);
13298                throw new SecurityException(msg);
13299            }
13300
13301        // Special case for adding a package: by default turn on compatibility
13302        // mode.
13303        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13304            Uri data = intent.getData();
13305            String ssp;
13306            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13307                mCompatModePackages.handlePackageAddedLocked(ssp,
13308                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13309            }
13310        }
13311
13312        /*
13313         * If this is the time zone changed action, queue up a message that will reset the timezone
13314         * of all currently running processes. This message will get queued up before the broadcast
13315         * happens.
13316         */
13317        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13318            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13319        }
13320
13321        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13322            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13323        }
13324
13325        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13326            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13327            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13328        }
13329
13330        // Add to the sticky list if requested.
13331        if (sticky) {
13332            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13333                    callingPid, callingUid)
13334                    != PackageManager.PERMISSION_GRANTED) {
13335                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13336                        + callingPid + ", uid=" + callingUid
13337                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13338                Slog.w(TAG, msg);
13339                throw new SecurityException(msg);
13340            }
13341            if (requiredPermission != null) {
13342                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13343                        + " and enforce permission " + requiredPermission);
13344                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13345            }
13346            if (intent.getComponent() != null) {
13347                throw new SecurityException(
13348                        "Sticky broadcasts can't target a specific component");
13349            }
13350            // We use userId directly here, since the "all" target is maintained
13351            // as a separate set of sticky broadcasts.
13352            if (userId != UserHandle.USER_ALL) {
13353                // But first, if this is not a broadcast to all users, then
13354                // make sure it doesn't conflict with an existing broadcast to
13355                // all users.
13356                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13357                        UserHandle.USER_ALL);
13358                if (stickies != null) {
13359                    ArrayList<Intent> list = stickies.get(intent.getAction());
13360                    if (list != null) {
13361                        int N = list.size();
13362                        int i;
13363                        for (i=0; i<N; i++) {
13364                            if (intent.filterEquals(list.get(i))) {
13365                                throw new IllegalArgumentException(
13366                                        "Sticky broadcast " + intent + " for user "
13367                                        + userId + " conflicts with existing global broadcast");
13368                            }
13369                        }
13370                    }
13371                }
13372            }
13373            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13374            if (stickies == null) {
13375                stickies = new ArrayMap<String, ArrayList<Intent>>();
13376                mStickyBroadcasts.put(userId, stickies);
13377            }
13378            ArrayList<Intent> list = stickies.get(intent.getAction());
13379            if (list == null) {
13380                list = new ArrayList<Intent>();
13381                stickies.put(intent.getAction(), list);
13382            }
13383            int N = list.size();
13384            int i;
13385            for (i=0; i<N; i++) {
13386                if (intent.filterEquals(list.get(i))) {
13387                    // This sticky already exists, replace it.
13388                    list.set(i, new Intent(intent));
13389                    break;
13390                }
13391            }
13392            if (i >= N) {
13393                list.add(new Intent(intent));
13394            }
13395        }
13396
13397        int[] users;
13398        if (userId == UserHandle.USER_ALL) {
13399            // Caller wants broadcast to go to all started users.
13400            users = mStartedUserArray;
13401        } else {
13402            // Caller wants broadcast to go to one specific user.
13403            users = new int[] {userId};
13404        }
13405
13406        // Figure out who all will receive this broadcast.
13407        List receivers = null;
13408        List<BroadcastFilter> registeredReceivers = null;
13409        // Need to resolve the intent to interested receivers...
13410        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13411                 == 0) {
13412            receivers = collectReceiverComponents(intent, resolvedType, users);
13413        }
13414        if (intent.getComponent() == null) {
13415            registeredReceivers = mReceiverResolver.queryIntent(intent,
13416                    resolvedType, false, userId);
13417        }
13418
13419        final boolean replacePending =
13420                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13421
13422        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13423                + " replacePending=" + replacePending);
13424
13425        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13426        if (!ordered && NR > 0) {
13427            // If we are not serializing this broadcast, then send the
13428            // registered receivers separately so they don't wait for the
13429            // components to be launched.
13430            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13431            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13432                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13433                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13434                    ordered, sticky, false, userId);
13435            if (DEBUG_BROADCAST) Slog.v(
13436                    TAG, "Enqueueing parallel broadcast " + r);
13437            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13438            if (!replaced) {
13439                queue.enqueueParallelBroadcastLocked(r);
13440                queue.scheduleBroadcastsLocked();
13441            }
13442            registeredReceivers = null;
13443            NR = 0;
13444        }
13445
13446        // Merge into one list.
13447        int ir = 0;
13448        if (receivers != null) {
13449            // A special case for PACKAGE_ADDED: do not allow the package
13450            // being added to see this broadcast.  This prevents them from
13451            // using this as a back door to get run as soon as they are
13452            // installed.  Maybe in the future we want to have a special install
13453            // broadcast or such for apps, but we'd like to deliberately make
13454            // this decision.
13455            String skipPackages[] = null;
13456            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13457                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13458                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13459                Uri data = intent.getData();
13460                if (data != null) {
13461                    String pkgName = data.getSchemeSpecificPart();
13462                    if (pkgName != null) {
13463                        skipPackages = new String[] { pkgName };
13464                    }
13465                }
13466            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13467                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13468            }
13469            if (skipPackages != null && (skipPackages.length > 0)) {
13470                for (String skipPackage : skipPackages) {
13471                    if (skipPackage != null) {
13472                        int NT = receivers.size();
13473                        for (int it=0; it<NT; it++) {
13474                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13475                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13476                                receivers.remove(it);
13477                                it--;
13478                                NT--;
13479                            }
13480                        }
13481                    }
13482                }
13483            }
13484
13485            int NT = receivers != null ? receivers.size() : 0;
13486            int it = 0;
13487            ResolveInfo curt = null;
13488            BroadcastFilter curr = null;
13489            while (it < NT && ir < NR) {
13490                if (curt == null) {
13491                    curt = (ResolveInfo)receivers.get(it);
13492                }
13493                if (curr == null) {
13494                    curr = registeredReceivers.get(ir);
13495                }
13496                if (curr.getPriority() >= curt.priority) {
13497                    // Insert this broadcast record into the final list.
13498                    receivers.add(it, curr);
13499                    ir++;
13500                    curr = null;
13501                    it++;
13502                    NT++;
13503                } else {
13504                    // Skip to the next ResolveInfo in the final list.
13505                    it++;
13506                    curt = null;
13507                }
13508            }
13509        }
13510        while (ir < NR) {
13511            if (receivers == null) {
13512                receivers = new ArrayList();
13513            }
13514            receivers.add(registeredReceivers.get(ir));
13515            ir++;
13516        }
13517
13518        if ((receivers != null && receivers.size() > 0)
13519                || resultTo != null) {
13520            BroadcastQueue queue = broadcastQueueForIntent(intent);
13521            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13522                    callerPackage, callingPid, callingUid, resolvedType,
13523                    requiredPermission, appOp, receivers, resultTo, resultCode,
13524                    resultData, map, ordered, sticky, false, userId);
13525            if (DEBUG_BROADCAST) Slog.v(
13526                    TAG, "Enqueueing ordered broadcast " + r
13527                    + ": prev had " + queue.mOrderedBroadcasts.size());
13528            if (DEBUG_BROADCAST) {
13529                int seq = r.intent.getIntExtra("seq", -1);
13530                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13531            }
13532            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13533            if (!replaced) {
13534                queue.enqueueOrderedBroadcastLocked(r);
13535                queue.scheduleBroadcastsLocked();
13536            }
13537        }
13538
13539        return ActivityManager.BROADCAST_SUCCESS;
13540    }
13541
13542    final Intent verifyBroadcastLocked(Intent intent) {
13543        // Refuse possible leaked file descriptors
13544        if (intent != null && intent.hasFileDescriptors() == true) {
13545            throw new IllegalArgumentException("File descriptors passed in Intent");
13546        }
13547
13548        int flags = intent.getFlags();
13549
13550        if (!mProcessesReady) {
13551            // if the caller really truly claims to know what they're doing, go
13552            // ahead and allow the broadcast without launching any receivers
13553            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13554                intent = new Intent(intent);
13555                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13556            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13557                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13558                        + " before boot completion");
13559                throw new IllegalStateException("Cannot broadcast before boot completed");
13560            }
13561        }
13562
13563        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13564            throw new IllegalArgumentException(
13565                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13566        }
13567
13568        return intent;
13569    }
13570
13571    public final int broadcastIntent(IApplicationThread caller,
13572            Intent intent, String resolvedType, IIntentReceiver resultTo,
13573            int resultCode, String resultData, Bundle map,
13574            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13575        enforceNotIsolatedCaller("broadcastIntent");
13576        synchronized(this) {
13577            intent = verifyBroadcastLocked(intent);
13578
13579            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13580            final int callingPid = Binder.getCallingPid();
13581            final int callingUid = Binder.getCallingUid();
13582            final long origId = Binder.clearCallingIdentity();
13583            int res = broadcastIntentLocked(callerApp,
13584                    callerApp != null ? callerApp.info.packageName : null,
13585                    intent, resolvedType, resultTo,
13586                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13587                    callingPid, callingUid, userId);
13588            Binder.restoreCallingIdentity(origId);
13589            return res;
13590        }
13591    }
13592
13593    int broadcastIntentInPackage(String packageName, int uid,
13594            Intent intent, String resolvedType, IIntentReceiver resultTo,
13595            int resultCode, String resultData, Bundle map,
13596            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13597        synchronized(this) {
13598            intent = verifyBroadcastLocked(intent);
13599
13600            final long origId = Binder.clearCallingIdentity();
13601            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13602                    resultTo, resultCode, resultData, map, requiredPermission,
13603                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13604            Binder.restoreCallingIdentity(origId);
13605            return res;
13606        }
13607    }
13608
13609    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13610        // Refuse possible leaked file descriptors
13611        if (intent != null && intent.hasFileDescriptors() == true) {
13612            throw new IllegalArgumentException("File descriptors passed in Intent");
13613        }
13614
13615        userId = handleIncomingUser(Binder.getCallingPid(),
13616                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13617
13618        synchronized(this) {
13619            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13620                    != PackageManager.PERMISSION_GRANTED) {
13621                String msg = "Permission Denial: unbroadcastIntent() from pid="
13622                        + Binder.getCallingPid()
13623                        + ", uid=" + Binder.getCallingUid()
13624                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13625                Slog.w(TAG, msg);
13626                throw new SecurityException(msg);
13627            }
13628            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13629            if (stickies != null) {
13630                ArrayList<Intent> list = stickies.get(intent.getAction());
13631                if (list != null) {
13632                    int N = list.size();
13633                    int i;
13634                    for (i=0; i<N; i++) {
13635                        if (intent.filterEquals(list.get(i))) {
13636                            list.remove(i);
13637                            break;
13638                        }
13639                    }
13640                    if (list.size() <= 0) {
13641                        stickies.remove(intent.getAction());
13642                    }
13643                }
13644                if (stickies.size() <= 0) {
13645                    mStickyBroadcasts.remove(userId);
13646                }
13647            }
13648        }
13649    }
13650
13651    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13652            String resultData, Bundle resultExtras, boolean resultAbort) {
13653        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13654        if (r == null) {
13655            Slog.w(TAG, "finishReceiver called but not found on queue");
13656            return false;
13657        }
13658
13659        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13660    }
13661
13662    void backgroundServicesFinishedLocked(int userId) {
13663        for (BroadcastQueue queue : mBroadcastQueues) {
13664            queue.backgroundServicesFinishedLocked(userId);
13665        }
13666    }
13667
13668    public void finishReceiver(IBinder who, int resultCode, String resultData,
13669            Bundle resultExtras, boolean resultAbort) {
13670        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13671
13672        // Refuse possible leaked file descriptors
13673        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13674            throw new IllegalArgumentException("File descriptors passed in Bundle");
13675        }
13676
13677        final long origId = Binder.clearCallingIdentity();
13678        try {
13679            boolean doNext = false;
13680            BroadcastRecord r;
13681
13682            synchronized(this) {
13683                r = broadcastRecordForReceiverLocked(who);
13684                if (r != null) {
13685                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13686                        resultData, resultExtras, resultAbort, true);
13687                }
13688            }
13689
13690            if (doNext) {
13691                r.queue.processNextBroadcast(false);
13692            }
13693            trimApplications();
13694        } finally {
13695            Binder.restoreCallingIdentity(origId);
13696        }
13697    }
13698
13699    // =========================================================
13700    // INSTRUMENTATION
13701    // =========================================================
13702
13703    public boolean startInstrumentation(ComponentName className,
13704            String profileFile, int flags, Bundle arguments,
13705            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13706            int userId) {
13707        enforceNotIsolatedCaller("startInstrumentation");
13708        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13709                userId, false, true, "startInstrumentation", null);
13710        // Refuse possible leaked file descriptors
13711        if (arguments != null && arguments.hasFileDescriptors()) {
13712            throw new IllegalArgumentException("File descriptors passed in Bundle");
13713        }
13714
13715        synchronized(this) {
13716            InstrumentationInfo ii = null;
13717            ApplicationInfo ai = null;
13718            try {
13719                ii = mContext.getPackageManager().getInstrumentationInfo(
13720                    className, STOCK_PM_FLAGS);
13721                ai = AppGlobals.getPackageManager().getApplicationInfo(
13722                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13723            } catch (PackageManager.NameNotFoundException e) {
13724            } catch (RemoteException e) {
13725            }
13726            if (ii == null) {
13727                reportStartInstrumentationFailure(watcher, className,
13728                        "Unable to find instrumentation info for: " + className);
13729                return false;
13730            }
13731            if (ai == null) {
13732                reportStartInstrumentationFailure(watcher, className,
13733                        "Unable to find instrumentation target package: " + ii.targetPackage);
13734                return false;
13735            }
13736
13737            int match = mContext.getPackageManager().checkSignatures(
13738                    ii.targetPackage, ii.packageName);
13739            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13740                String msg = "Permission Denial: starting instrumentation "
13741                        + className + " from pid="
13742                        + Binder.getCallingPid()
13743                        + ", uid=" + Binder.getCallingPid()
13744                        + " not allowed because package " + ii.packageName
13745                        + " does not have a signature matching the target "
13746                        + ii.targetPackage;
13747                reportStartInstrumentationFailure(watcher, className, msg);
13748                throw new SecurityException(msg);
13749            }
13750
13751            final long origId = Binder.clearCallingIdentity();
13752            // Instrumentation can kill and relaunch even persistent processes
13753            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
13754                    "start instr");
13755            ProcessRecord app = addAppLocked(ai, false);
13756            app.instrumentationClass = className;
13757            app.instrumentationInfo = ai;
13758            app.instrumentationProfileFile = profileFile;
13759            app.instrumentationArguments = arguments;
13760            app.instrumentationWatcher = watcher;
13761            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13762            app.instrumentationResultClass = className;
13763            Binder.restoreCallingIdentity(origId);
13764        }
13765
13766        return true;
13767    }
13768
13769    /**
13770     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13771     * error to the logs, but if somebody is watching, send the report there too.  This enables
13772     * the "am" command to report errors with more information.
13773     *
13774     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13775     * @param cn The component name of the instrumentation.
13776     * @param report The error report.
13777     */
13778    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13779            ComponentName cn, String report) {
13780        Slog.w(TAG, report);
13781        try {
13782            if (watcher != null) {
13783                Bundle results = new Bundle();
13784                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13785                results.putString("Error", report);
13786                watcher.instrumentationStatus(cn, -1, results);
13787            }
13788        } catch (RemoteException e) {
13789            Slog.w(TAG, e);
13790        }
13791    }
13792
13793    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13794        if (app.instrumentationWatcher != null) {
13795            try {
13796                // NOTE:  IInstrumentationWatcher *must* be oneway here
13797                app.instrumentationWatcher.instrumentationFinished(
13798                    app.instrumentationClass,
13799                    resultCode,
13800                    results);
13801            } catch (RemoteException e) {
13802            }
13803        }
13804        if (app.instrumentationUiAutomationConnection != null) {
13805            try {
13806                app.instrumentationUiAutomationConnection.shutdown();
13807            } catch (RemoteException re) {
13808                /* ignore */
13809            }
13810            // Only a UiAutomation can set this flag and now that
13811            // it is finished we make sure it is reset to its default.
13812            mUserIsMonkey = false;
13813        }
13814        app.instrumentationWatcher = null;
13815        app.instrumentationUiAutomationConnection = null;
13816        app.instrumentationClass = null;
13817        app.instrumentationInfo = null;
13818        app.instrumentationProfileFile = null;
13819        app.instrumentationArguments = null;
13820
13821        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
13822                "finished inst");
13823    }
13824
13825    public void finishInstrumentation(IApplicationThread target,
13826            int resultCode, Bundle results) {
13827        int userId = UserHandle.getCallingUserId();
13828        // Refuse possible leaked file descriptors
13829        if (results != null && results.hasFileDescriptors()) {
13830            throw new IllegalArgumentException("File descriptors passed in Intent");
13831        }
13832
13833        synchronized(this) {
13834            ProcessRecord app = getRecordForAppLocked(target);
13835            if (app == null) {
13836                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13837                return;
13838            }
13839            final long origId = Binder.clearCallingIdentity();
13840            finishInstrumentationLocked(app, resultCode, results);
13841            Binder.restoreCallingIdentity(origId);
13842        }
13843    }
13844
13845    // =========================================================
13846    // CONFIGURATION
13847    // =========================================================
13848
13849    public ConfigurationInfo getDeviceConfigurationInfo() {
13850        ConfigurationInfo config = new ConfigurationInfo();
13851        synchronized (this) {
13852            config.reqTouchScreen = mConfiguration.touchscreen;
13853            config.reqKeyboardType = mConfiguration.keyboard;
13854            config.reqNavigation = mConfiguration.navigation;
13855            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13856                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13857                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13858            }
13859            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13860                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13861                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13862            }
13863            config.reqGlEsVersion = GL_ES_VERSION;
13864        }
13865        return config;
13866    }
13867
13868    ActivityStack getFocusedStack() {
13869        return mStackSupervisor.getFocusedStack();
13870    }
13871
13872    public Configuration getConfiguration() {
13873        Configuration ci;
13874        synchronized(this) {
13875            ci = new Configuration(mConfiguration);
13876        }
13877        return ci;
13878    }
13879
13880    public void updatePersistentConfiguration(Configuration values) {
13881        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13882                "updateConfiguration()");
13883        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13884                "updateConfiguration()");
13885        if (values == null) {
13886            throw new NullPointerException("Configuration must not be null");
13887        }
13888
13889        synchronized(this) {
13890            final long origId = Binder.clearCallingIdentity();
13891            updateConfigurationLocked(values, null, true, false);
13892            Binder.restoreCallingIdentity(origId);
13893        }
13894    }
13895
13896    public void updateConfiguration(Configuration values) {
13897        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13898                "updateConfiguration()");
13899
13900        synchronized(this) {
13901            if (values == null && mWindowManager != null) {
13902                // sentinel: fetch the current configuration from the window manager
13903                values = mWindowManager.computeNewConfiguration();
13904            }
13905
13906            if (mWindowManager != null) {
13907                mProcessList.applyDisplaySize(mWindowManager);
13908            }
13909
13910            final long origId = Binder.clearCallingIdentity();
13911            if (values != null) {
13912                Settings.System.clearConfiguration(values);
13913            }
13914            updateConfigurationLocked(values, null, false, false);
13915            Binder.restoreCallingIdentity(origId);
13916        }
13917    }
13918
13919    /**
13920     * Do either or both things: (1) change the current configuration, and (2)
13921     * make sure the given activity is running with the (now) current
13922     * configuration.  Returns true if the activity has been left running, or
13923     * false if <var>starting</var> is being destroyed to match the new
13924     * configuration.
13925     * @param persistent TODO
13926     */
13927    boolean updateConfigurationLocked(Configuration values,
13928            ActivityRecord starting, boolean persistent, boolean initLocale) {
13929        int changes = 0;
13930
13931        if (values != null) {
13932            Configuration newConfig = new Configuration(mConfiguration);
13933            changes = newConfig.updateFrom(values);
13934            if (changes != 0) {
13935                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13936                    Slog.i(TAG, "Updating configuration to: " + values);
13937                }
13938
13939                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13940
13941                if (values.locale != null && !initLocale) {
13942                    saveLocaleLocked(values.locale,
13943                                     !values.locale.equals(mConfiguration.locale),
13944                                     values.userSetLocale);
13945                }
13946
13947                mConfigurationSeq++;
13948                if (mConfigurationSeq <= 0) {
13949                    mConfigurationSeq = 1;
13950                }
13951                newConfig.seq = mConfigurationSeq;
13952                mConfiguration = newConfig;
13953                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
13954
13955                final Configuration configCopy = new Configuration(mConfiguration);
13956
13957                // TODO: If our config changes, should we auto dismiss any currently
13958                // showing dialogs?
13959                mShowDialogs = shouldShowDialogs(newConfig);
13960
13961                AttributeCache ac = AttributeCache.instance();
13962                if (ac != null) {
13963                    ac.updateConfiguration(configCopy);
13964                }
13965
13966                // Make sure all resources in our process are updated
13967                // right now, so that anyone who is going to retrieve
13968                // resource values after we return will be sure to get
13969                // the new ones.  This is especially important during
13970                // boot, where the first config change needs to guarantee
13971                // all resources have that config before following boot
13972                // code is executed.
13973                mSystemThread.applyConfigurationToResources(configCopy);
13974
13975                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
13976                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
13977                    msg.obj = new Configuration(configCopy);
13978                    mHandler.sendMessage(msg);
13979                }
13980
13981                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13982                    ProcessRecord app = mLruProcesses.get(i);
13983                    try {
13984                        if (app.thread != null) {
13985                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
13986                                    + app.processName + " new config " + mConfiguration);
13987                            app.thread.scheduleConfigurationChanged(configCopy);
13988                        }
13989                    } catch (Exception e) {
13990                    }
13991                }
13992                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
13993                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13994                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
13995                        | Intent.FLAG_RECEIVER_FOREGROUND);
13996                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13997                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
13998                        Process.SYSTEM_UID, UserHandle.USER_ALL);
13999                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14000                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14001                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14002                    broadcastIntentLocked(null, null, intent,
14003                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14004                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14005                }
14006            }
14007        }
14008
14009        boolean kept = true;
14010        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14011        // mainStack is null during startup.
14012        if (mainStack != null) {
14013            if (changes != 0 && starting == null) {
14014                // If the configuration changed, and the caller is not already
14015                // in the process of starting an activity, then find the top
14016                // activity to check if its configuration needs to change.
14017                starting = mainStack.topRunningActivityLocked(null);
14018            }
14019
14020            if (starting != null) {
14021                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14022                // And we need to make sure at this point that all other activities
14023                // are made visible with the correct configuration.
14024                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14025            }
14026        }
14027
14028        if (values != null && mWindowManager != null) {
14029            mWindowManager.setNewConfiguration(mConfiguration);
14030        }
14031
14032        return kept;
14033    }
14034
14035    /**
14036     * Decide based on the configuration whether we should shouw the ANR,
14037     * crash, etc dialogs.  The idea is that if there is no affordnace to
14038     * press the on-screen buttons, we shouldn't show the dialog.
14039     *
14040     * A thought: SystemUI might also want to get told about this, the Power
14041     * dialog / global actions also might want different behaviors.
14042     */
14043    private static final boolean shouldShowDialogs(Configuration config) {
14044        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14045                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14046    }
14047
14048    /**
14049     * Save the locale.  You must be inside a synchronized (this) block.
14050     */
14051    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14052        if(isDiff) {
14053            SystemProperties.set("user.language", l.getLanguage());
14054            SystemProperties.set("user.region", l.getCountry());
14055        }
14056
14057        if(isPersist) {
14058            SystemProperties.set("persist.sys.language", l.getLanguage());
14059            SystemProperties.set("persist.sys.country", l.getCountry());
14060            SystemProperties.set("persist.sys.localevar", l.getVariant());
14061        }
14062    }
14063
14064    @Override
14065    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14066        ActivityRecord srec = ActivityRecord.forToken(token);
14067        return srec != null && srec.task.affinity != null &&
14068                srec.task.affinity.equals(destAffinity);
14069    }
14070
14071    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14072            Intent resultData) {
14073
14074        synchronized (this) {
14075            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14076            if (stack != null) {
14077                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14078            }
14079            return false;
14080        }
14081    }
14082
14083    public int getLaunchedFromUid(IBinder activityToken) {
14084        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14085        if (srec == null) {
14086            return -1;
14087        }
14088        return srec.launchedFromUid;
14089    }
14090
14091    public String getLaunchedFromPackage(IBinder activityToken) {
14092        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14093        if (srec == null) {
14094            return null;
14095        }
14096        return srec.launchedFromPackage;
14097    }
14098
14099    // =========================================================
14100    // LIFETIME MANAGEMENT
14101    // =========================================================
14102
14103    // Returns which broadcast queue the app is the current [or imminent] receiver
14104    // on, or 'null' if the app is not an active broadcast recipient.
14105    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14106        BroadcastRecord r = app.curReceiver;
14107        if (r != null) {
14108            return r.queue;
14109        }
14110
14111        // It's not the current receiver, but it might be starting up to become one
14112        synchronized (this) {
14113            for (BroadcastQueue queue : mBroadcastQueues) {
14114                r = queue.mPendingBroadcast;
14115                if (r != null && r.curApp == app) {
14116                    // found it; report which queue it's in
14117                    return queue;
14118                }
14119            }
14120        }
14121
14122        return null;
14123    }
14124
14125    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14126            boolean doingAll, long now) {
14127        if (mAdjSeq == app.adjSeq) {
14128            // This adjustment has already been computed.
14129            return app.curRawAdj;
14130        }
14131
14132        if (app.thread == null) {
14133            app.adjSeq = mAdjSeq;
14134            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14135            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14136            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14137        }
14138
14139        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14140        app.adjSource = null;
14141        app.adjTarget = null;
14142        app.empty = false;
14143        app.cached = false;
14144
14145        final int activitiesSize = app.activities.size();
14146
14147        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14148            // The max adjustment doesn't allow this app to be anything
14149            // below foreground, so it is not worth doing work for it.
14150            app.adjType = "fixed";
14151            app.adjSeq = mAdjSeq;
14152            app.curRawAdj = app.maxAdj;
14153            app.foregroundActivities = false;
14154            app.keeping = true;
14155            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14156            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14157            // System process can do UI, and when they do we want to have
14158            // them trim their memory after the user leaves the UI.  To
14159            // facilitate this, here we need to determine whether or not it
14160            // is currently showing UI.
14161            app.systemNoUi = true;
14162            if (app == TOP_APP) {
14163                app.systemNoUi = false;
14164            } else if (activitiesSize > 0) {
14165                for (int j = 0; j < activitiesSize; j++) {
14166                    final ActivityRecord r = app.activities.get(j);
14167                    if (r.visible) {
14168                        app.systemNoUi = false;
14169                    }
14170                }
14171            }
14172            if (!app.systemNoUi) {
14173                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14174            }
14175            return (app.curAdj=app.maxAdj);
14176        }
14177
14178        app.keeping = false;
14179        app.systemNoUi = false;
14180
14181        // Determine the importance of the process, starting with most
14182        // important to least, and assign an appropriate OOM adjustment.
14183        int adj;
14184        int schedGroup;
14185        int procState;
14186        boolean foregroundActivities = false;
14187        boolean interesting = false;
14188        BroadcastQueue queue;
14189        if (app == TOP_APP) {
14190            // The last app on the list is the foreground app.
14191            adj = ProcessList.FOREGROUND_APP_ADJ;
14192            schedGroup = Process.THREAD_GROUP_DEFAULT;
14193            app.adjType = "top-activity";
14194            foregroundActivities = true;
14195            interesting = true;
14196            procState = ActivityManager.PROCESS_STATE_TOP;
14197        } else if (app.instrumentationClass != null) {
14198            // Don't want to kill running instrumentation.
14199            adj = ProcessList.FOREGROUND_APP_ADJ;
14200            schedGroup = Process.THREAD_GROUP_DEFAULT;
14201            app.adjType = "instrumentation";
14202            interesting = true;
14203            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14204        } else if ((queue = isReceivingBroadcast(app)) != null) {
14205            // An app that is currently receiving a broadcast also
14206            // counts as being in the foreground for OOM killer purposes.
14207            // It's placed in a sched group based on the nature of the
14208            // broadcast as reflected by which queue it's active in.
14209            adj = ProcessList.FOREGROUND_APP_ADJ;
14210            schedGroup = (queue == mFgBroadcastQueue)
14211                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14212            app.adjType = "broadcast";
14213            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14214        } else if (app.executingServices.size() > 0) {
14215            // An app that is currently executing a service callback also
14216            // counts as being in the foreground.
14217            adj = ProcessList.FOREGROUND_APP_ADJ;
14218            schedGroup = app.execServicesFg ?
14219                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14220            app.adjType = "exec-service";
14221            procState = ActivityManager.PROCESS_STATE_SERVICE;
14222            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14223        } else {
14224            // As far as we know the process is empty.  We may change our mind later.
14225            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14226            // At this point we don't actually know the adjustment.  Use the cached adj
14227            // value that the caller wants us to.
14228            adj = cachedAdj;
14229            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14230            app.cached = true;
14231            app.empty = true;
14232            app.adjType = "cch-empty";
14233        }
14234
14235        // Examine all activities if not already foreground.
14236        if (!foregroundActivities && activitiesSize > 0) {
14237            for (int j = 0; j < activitiesSize; j++) {
14238                final ActivityRecord r = app.activities.get(j);
14239                if (r.app != app) {
14240                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14241                            + app + "?!?");
14242                    continue;
14243                }
14244                if (r.visible) {
14245                    // App has a visible activity; only upgrade adjustment.
14246                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14247                        adj = ProcessList.VISIBLE_APP_ADJ;
14248                        app.adjType = "visible";
14249                    }
14250                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14251                        procState = ActivityManager.PROCESS_STATE_TOP;
14252                    }
14253                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14254                    app.cached = false;
14255                    app.empty = false;
14256                    foregroundActivities = true;
14257                    break;
14258                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14259                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14260                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14261                        app.adjType = "pausing";
14262                    }
14263                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14264                        procState = ActivityManager.PROCESS_STATE_TOP;
14265                    }
14266                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14267                    app.cached = false;
14268                    app.empty = false;
14269                    foregroundActivities = true;
14270                } else if (r.state == ActivityState.STOPPING) {
14271                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14272                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14273                        app.adjType = "stopping";
14274                    }
14275                    // For the process state, we will at this point consider the
14276                    // process to be cached.  It will be cached either as an activity
14277                    // or empty depending on whether the activity is finishing.  We do
14278                    // this so that we can treat the process as cached for purposes of
14279                    // memory trimming (determing current memory level, trim command to
14280                    // send to process) since there can be an arbitrary number of stopping
14281                    // processes and they should soon all go into the cached state.
14282                    if (!r.finishing) {
14283                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14284                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14285                        }
14286                    }
14287                    app.cached = false;
14288                    app.empty = false;
14289                    foregroundActivities = true;
14290                } else {
14291                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14292                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14293                        app.adjType = "cch-act";
14294                    }
14295                }
14296            }
14297        }
14298
14299        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14300            if (app.foregroundServices) {
14301                // The user is aware of this app, so make it visible.
14302                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14303                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14304                app.cached = false;
14305                app.adjType = "fg-service";
14306                schedGroup = Process.THREAD_GROUP_DEFAULT;
14307            } else if (app.forcingToForeground != null) {
14308                // The user is aware of this app, so make it visible.
14309                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14310                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14311                app.cached = false;
14312                app.adjType = "force-fg";
14313                app.adjSource = app.forcingToForeground;
14314                schedGroup = Process.THREAD_GROUP_DEFAULT;
14315            }
14316        }
14317
14318        if (app.foregroundServices) {
14319            interesting = true;
14320        }
14321
14322        if (app == mHeavyWeightProcess) {
14323            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14324                // We don't want to kill the current heavy-weight process.
14325                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14326                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14327                app.cached = false;
14328                app.adjType = "heavy";
14329            }
14330            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14331                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14332            }
14333        }
14334
14335        if (app == mHomeProcess) {
14336            if (adj > ProcessList.HOME_APP_ADJ) {
14337                // This process is hosting what we currently consider to be the
14338                // home app, so we don't want to let it go into the background.
14339                adj = ProcessList.HOME_APP_ADJ;
14340                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14341                app.cached = false;
14342                app.adjType = "home";
14343            }
14344            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14345                procState = ActivityManager.PROCESS_STATE_HOME;
14346            }
14347        }
14348
14349        if (app == mPreviousProcess && app.activities.size() > 0) {
14350            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14351                // This was the previous process that showed UI to the user.
14352                // We want to try to keep it around more aggressively, to give
14353                // a good experience around switching between two apps.
14354                adj = ProcessList.PREVIOUS_APP_ADJ;
14355                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14356                app.cached = false;
14357                app.adjType = "previous";
14358            }
14359            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14360                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14361            }
14362        }
14363
14364        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14365                + " reason=" + app.adjType);
14366
14367        // By default, we use the computed adjustment.  It may be changed if
14368        // there are applications dependent on our services or providers, but
14369        // this gives us a baseline and makes sure we don't get into an
14370        // infinite recursion.
14371        app.adjSeq = mAdjSeq;
14372        app.curRawAdj = adj;
14373        app.hasStartedServices = false;
14374
14375        if (mBackupTarget != null && app == mBackupTarget.app) {
14376            // If possible we want to avoid killing apps while they're being backed up
14377            if (adj > ProcessList.BACKUP_APP_ADJ) {
14378                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14379                adj = ProcessList.BACKUP_APP_ADJ;
14380                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14381                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14382                }
14383                app.adjType = "backup";
14384                app.cached = false;
14385            }
14386            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14387                procState = ActivityManager.PROCESS_STATE_BACKUP;
14388            }
14389        }
14390
14391        boolean mayBeTop = false;
14392
14393        for (int is = app.services.size()-1;
14394                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14395                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14396                        || procState > ActivityManager.PROCESS_STATE_TOP);
14397                is--) {
14398            ServiceRecord s = app.services.valueAt(is);
14399            if (s.startRequested) {
14400                app.hasStartedServices = true;
14401                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14402                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14403                }
14404                if (app.hasShownUi && app != mHomeProcess) {
14405                    // If this process has shown some UI, let it immediately
14406                    // go to the LRU list because it may be pretty heavy with
14407                    // UI stuff.  We'll tag it with a label just to help
14408                    // debug and understand what is going on.
14409                    if (adj > ProcessList.SERVICE_ADJ) {
14410                        app.adjType = "cch-started-ui-services";
14411                    }
14412                } else {
14413                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14414                        // This service has seen some activity within
14415                        // recent memory, so we will keep its process ahead
14416                        // of the background processes.
14417                        if (adj > ProcessList.SERVICE_ADJ) {
14418                            adj = ProcessList.SERVICE_ADJ;
14419                            app.adjType = "started-services";
14420                            app.cached = false;
14421                        }
14422                    }
14423                    // If we have let the service slide into the background
14424                    // state, still have some text describing what it is doing
14425                    // even though the service no longer has an impact.
14426                    if (adj > ProcessList.SERVICE_ADJ) {
14427                        app.adjType = "cch-started-services";
14428                    }
14429                }
14430                // Don't kill this process because it is doing work; it
14431                // has said it is doing work.
14432                app.keeping = true;
14433            }
14434            for (int conni = s.connections.size()-1;
14435                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14436                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14437                            || procState > ActivityManager.PROCESS_STATE_TOP);
14438                    conni--) {
14439                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14440                for (int i = 0;
14441                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14442                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14443                                || procState > ActivityManager.PROCESS_STATE_TOP);
14444                        i++) {
14445                    // XXX should compute this based on the max of
14446                    // all connected clients.
14447                    ConnectionRecord cr = clist.get(i);
14448                    if (cr.binding.client == app) {
14449                        // Binding to ourself is not interesting.
14450                        continue;
14451                    }
14452                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14453                        ProcessRecord client = cr.binding.client;
14454                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14455                                TOP_APP, doingAll, now);
14456                        int clientProcState = client.curProcState;
14457                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14458                            // If the other app is cached for any reason, for purposes here
14459                            // we are going to consider it empty.  The specific cached state
14460                            // doesn't propagate except under certain conditions.
14461                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14462                        }
14463                        String adjType = null;
14464                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14465                            // Not doing bind OOM management, so treat
14466                            // this guy more like a started service.
14467                            if (app.hasShownUi && app != mHomeProcess) {
14468                                // If this process has shown some UI, let it immediately
14469                                // go to the LRU list because it may be pretty heavy with
14470                                // UI stuff.  We'll tag it with a label just to help
14471                                // debug and understand what is going on.
14472                                if (adj > clientAdj) {
14473                                    adjType = "cch-bound-ui-services";
14474                                }
14475                                app.cached = false;
14476                                clientAdj = adj;
14477                                clientProcState = procState;
14478                            } else {
14479                                if (now >= (s.lastActivity
14480                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14481                                    // This service has not seen activity within
14482                                    // recent memory, so allow it to drop to the
14483                                    // LRU list if there is no other reason to keep
14484                                    // it around.  We'll also tag it with a label just
14485                                    // to help debug and undertand what is going on.
14486                                    if (adj > clientAdj) {
14487                                        adjType = "cch-bound-services";
14488                                    }
14489                                    clientAdj = adj;
14490                                }
14491                            }
14492                        }
14493                        if (adj > clientAdj) {
14494                            // If this process has recently shown UI, and
14495                            // the process that is binding to it is less
14496                            // important than being visible, then we don't
14497                            // care about the binding as much as we care
14498                            // about letting this process get into the LRU
14499                            // list to be killed and restarted if needed for
14500                            // memory.
14501                            if (app.hasShownUi && app != mHomeProcess
14502                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14503                                adjType = "cch-bound-ui-services";
14504                            } else {
14505                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14506                                        |Context.BIND_IMPORTANT)) != 0) {
14507                                    adj = clientAdj;
14508                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14509                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14510                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14511                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14512                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14513                                    adj = clientAdj;
14514                                } else {
14515                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14516                                        adj = ProcessList.VISIBLE_APP_ADJ;
14517                                    }
14518                                }
14519                                if (!client.cached) {
14520                                    app.cached = false;
14521                                }
14522                                if (client.keeping) {
14523                                    app.keeping = true;
14524                                }
14525                                adjType = "service";
14526                            }
14527                        }
14528                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14529                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14530                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14531                            }
14532                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14533                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14534                                    // Special handling of clients who are in the top state.
14535                                    // We *may* want to consider this process to be in the
14536                                    // top state as well, but only if there is not another
14537                                    // reason for it to be running.  Being on the top is a
14538                                    // special state, meaning you are specifically running
14539                                    // for the current top app.  If the process is already
14540                                    // running in the background for some other reason, it
14541                                    // is more important to continue considering it to be
14542                                    // in the background state.
14543                                    mayBeTop = true;
14544                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14545                                } else {
14546                                    // Special handling for above-top states (persistent
14547                                    // processes).  These should not bring the current process
14548                                    // into the top state, since they are not on top.  Instead
14549                                    // give them the best state after that.
14550                                    clientProcState =
14551                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14552                                }
14553                            }
14554                        } else {
14555                            if (clientProcState <
14556                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14557                                clientProcState =
14558                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14559                            }
14560                        }
14561                        if (procState > clientProcState) {
14562                            procState = clientProcState;
14563                        }
14564                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14565                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14566                            app.pendingUiClean = true;
14567                        }
14568                        if (adjType != null) {
14569                            app.adjType = adjType;
14570                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14571                                    .REASON_SERVICE_IN_USE;
14572                            app.adjSource = cr.binding.client;
14573                            app.adjSourceOom = clientAdj;
14574                            app.adjTarget = s.name;
14575                        }
14576                    }
14577                    final ActivityRecord a = cr.activity;
14578                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14579                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14580                                (a.visible || a.state == ActivityState.RESUMED
14581                                 || a.state == ActivityState.PAUSING)) {
14582                            adj = ProcessList.FOREGROUND_APP_ADJ;
14583                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14584                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14585                            }
14586                            app.cached = false;
14587                            app.adjType = "service";
14588                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14589                                    .REASON_SERVICE_IN_USE;
14590                            app.adjSource = a;
14591                            app.adjSourceOom = adj;
14592                            app.adjTarget = s.name;
14593                        }
14594                    }
14595                }
14596            }
14597        }
14598
14599        for (int provi = app.pubProviders.size()-1;
14600                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14601                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14602                        || procState > ActivityManager.PROCESS_STATE_TOP);
14603                provi--) {
14604            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14605            for (int i = cpr.connections.size()-1;
14606                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14607                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14608                            || procState > ActivityManager.PROCESS_STATE_TOP);
14609                    i--) {
14610                ContentProviderConnection conn = cpr.connections.get(i);
14611                ProcessRecord client = conn.client;
14612                if (client == app) {
14613                    // Being our own client is not interesting.
14614                    continue;
14615                }
14616                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14617                int clientProcState = client.curProcState;
14618                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14619                    // If the other app is cached for any reason, for purposes here
14620                    // we are going to consider it empty.
14621                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14622                }
14623                if (adj > clientAdj) {
14624                    if (app.hasShownUi && app != mHomeProcess
14625                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14626                        app.adjType = "cch-ui-provider";
14627                    } else {
14628                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14629                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14630                        app.adjType = "provider";
14631                    }
14632                    app.cached &= client.cached;
14633                    app.keeping |= client.keeping;
14634                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14635                            .REASON_PROVIDER_IN_USE;
14636                    app.adjSource = client;
14637                    app.adjSourceOom = clientAdj;
14638                    app.adjTarget = cpr.name;
14639                }
14640                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14641                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14642                        // Special handling of clients who are in the top state.
14643                        // We *may* want to consider this process to be in the
14644                        // top state as well, but only if there is not another
14645                        // reason for it to be running.  Being on the top is a
14646                        // special state, meaning you are specifically running
14647                        // for the current top app.  If the process is already
14648                        // running in the background for some other reason, it
14649                        // is more important to continue considering it to be
14650                        // in the background state.
14651                        mayBeTop = true;
14652                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14653                    } else {
14654                        // Special handling for above-top states (persistent
14655                        // processes).  These should not bring the current process
14656                        // into the top state, since they are not on top.  Instead
14657                        // give them the best state after that.
14658                        clientProcState =
14659                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14660                    }
14661                }
14662                if (procState > clientProcState) {
14663                    procState = clientProcState;
14664                }
14665                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14666                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14667                }
14668            }
14669            // If the provider has external (non-framework) process
14670            // dependencies, ensure that its adjustment is at least
14671            // FOREGROUND_APP_ADJ.
14672            if (cpr.hasExternalProcessHandles()) {
14673                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14674                    adj = ProcessList.FOREGROUND_APP_ADJ;
14675                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14676                    app.cached = false;
14677                    app.keeping = true;
14678                    app.adjType = "provider";
14679                    app.adjTarget = cpr.name;
14680                }
14681                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14682                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14683                }
14684            }
14685        }
14686
14687        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14688            // A client of one of our services or providers is in the top state.  We
14689            // *may* want to be in the top state, but not if we are already running in
14690            // the background for some other reason.  For the decision here, we are going
14691            // to pick out a few specific states that we want to remain in when a client
14692            // is top (states that tend to be longer-term) and otherwise allow it to go
14693            // to the top state.
14694            switch (procState) {
14695                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14696                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14697                case ActivityManager.PROCESS_STATE_SERVICE:
14698                    // These all are longer-term states, so pull them up to the top
14699                    // of the background states, but not all the way to the top state.
14700                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14701                    break;
14702                default:
14703                    // Otherwise, top is a better choice, so take it.
14704                    procState = ActivityManager.PROCESS_STATE_TOP;
14705                    break;
14706            }
14707        }
14708
14709        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14710            // This is a cached process, but with client activities.  Mark it so.
14711            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14712            app.adjType = "cch-client-act";
14713        }
14714
14715        if (adj == ProcessList.SERVICE_ADJ) {
14716            if (doingAll) {
14717                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14718                mNewNumServiceProcs++;
14719                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14720                if (!app.serviceb) {
14721                    // This service isn't far enough down on the LRU list to
14722                    // normally be a B service, but if we are low on RAM and it
14723                    // is large we want to force it down since we would prefer to
14724                    // keep launcher over it.
14725                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14726                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14727                        app.serviceHighRam = true;
14728                        app.serviceb = true;
14729                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14730                    } else {
14731                        mNewNumAServiceProcs++;
14732                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14733                    }
14734                } else {
14735                    app.serviceHighRam = false;
14736                }
14737            }
14738            if (app.serviceb) {
14739                adj = ProcessList.SERVICE_B_ADJ;
14740            }
14741        }
14742
14743        app.curRawAdj = adj;
14744
14745        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14746        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14747        if (adj > app.maxAdj) {
14748            adj = app.maxAdj;
14749            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14750                schedGroup = Process.THREAD_GROUP_DEFAULT;
14751            }
14752        }
14753        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14754            app.keeping = true;
14755        }
14756
14757        // Do final modification to adj.  Everything we do between here and applying
14758        // the final setAdj must be done in this function, because we will also use
14759        // it when computing the final cached adj later.  Note that we don't need to
14760        // worry about this for max adj above, since max adj will always be used to
14761        // keep it out of the cached vaues.
14762        adj = app.modifyRawOomAdj(adj);
14763
14764        app.curProcState = procState;
14765
14766        int importance = app.memImportance;
14767        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14768            app.curAdj = adj;
14769            app.curSchedGroup = schedGroup;
14770            if (!interesting) {
14771                // For this reporting, if there is not something explicitly
14772                // interesting in this process then we will push it to the
14773                // background importance.
14774                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14775            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14776                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14777            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14778                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14779            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14780                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14781            } else if (adj >= ProcessList.SERVICE_ADJ) {
14782                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14783            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14784                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14785            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14786                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14787            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14788                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14789            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14790                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14791            } else {
14792                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14793            }
14794        }
14795
14796        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14797        if (foregroundActivities != app.foregroundActivities) {
14798            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14799        }
14800        if (changes != 0) {
14801            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14802            app.memImportance = importance;
14803            app.foregroundActivities = foregroundActivities;
14804            int i = mPendingProcessChanges.size()-1;
14805            ProcessChangeItem item = null;
14806            while (i >= 0) {
14807                item = mPendingProcessChanges.get(i);
14808                if (item.pid == app.pid) {
14809                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14810                    break;
14811                }
14812                i--;
14813            }
14814            if (i < 0) {
14815                // No existing item in pending changes; need a new one.
14816                final int NA = mAvailProcessChanges.size();
14817                if (NA > 0) {
14818                    item = mAvailProcessChanges.remove(NA-1);
14819                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14820                } else {
14821                    item = new ProcessChangeItem();
14822                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14823                }
14824                item.changes = 0;
14825                item.pid = app.pid;
14826                item.uid = app.info.uid;
14827                if (mPendingProcessChanges.size() == 0) {
14828                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14829                            "*** Enqueueing dispatch processes changed!");
14830                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14831                }
14832                mPendingProcessChanges.add(item);
14833            }
14834            item.changes |= changes;
14835            item.importance = importance;
14836            item.foregroundActivities = foregroundActivities;
14837            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14838                    + Integer.toHexString(System.identityHashCode(item))
14839                    + " " + app.toShortString() + ": changes=" + item.changes
14840                    + " importance=" + item.importance
14841                    + " foreground=" + item.foregroundActivities
14842                    + " type=" + app.adjType + " source=" + app.adjSource
14843                    + " target=" + app.adjTarget);
14844        }
14845
14846        return app.curRawAdj;
14847    }
14848
14849    /**
14850     * Schedule PSS collection of a process.
14851     */
14852    void requestPssLocked(ProcessRecord proc, int procState) {
14853        if (mPendingPssProcesses.contains(proc)) {
14854            return;
14855        }
14856        if (mPendingPssProcesses.size() == 0) {
14857            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14858        }
14859        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14860        proc.pssProcState = procState;
14861        mPendingPssProcesses.add(proc);
14862    }
14863
14864    /**
14865     * Schedule PSS collection of all processes.
14866     */
14867    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14868        if (!always) {
14869            if (now < (mLastFullPssTime +
14870                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14871                return;
14872            }
14873        }
14874        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14875        mLastFullPssTime = now;
14876        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14877        mPendingPssProcesses.clear();
14878        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14879            ProcessRecord app = mLruProcesses.get(i);
14880            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14881                app.pssProcState = app.setProcState;
14882                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14883                        mSleeping, now);
14884                mPendingPssProcesses.add(app);
14885            }
14886        }
14887        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14888    }
14889
14890    /**
14891     * Ask a given process to GC right now.
14892     */
14893    final void performAppGcLocked(ProcessRecord app) {
14894        try {
14895            app.lastRequestedGc = SystemClock.uptimeMillis();
14896            if (app.thread != null) {
14897                if (app.reportLowMemory) {
14898                    app.reportLowMemory = false;
14899                    app.thread.scheduleLowMemory();
14900                } else {
14901                    app.thread.processInBackground();
14902                }
14903            }
14904        } catch (Exception e) {
14905            // whatever.
14906        }
14907    }
14908
14909    /**
14910     * Returns true if things are idle enough to perform GCs.
14911     */
14912    private final boolean canGcNowLocked() {
14913        boolean processingBroadcasts = false;
14914        for (BroadcastQueue q : mBroadcastQueues) {
14915            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14916                processingBroadcasts = true;
14917            }
14918        }
14919        return !processingBroadcasts
14920                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14921    }
14922
14923    /**
14924     * Perform GCs on all processes that are waiting for it, but only
14925     * if things are idle.
14926     */
14927    final void performAppGcsLocked() {
14928        final int N = mProcessesToGc.size();
14929        if (N <= 0) {
14930            return;
14931        }
14932        if (canGcNowLocked()) {
14933            while (mProcessesToGc.size() > 0) {
14934                ProcessRecord proc = mProcessesToGc.remove(0);
14935                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14936                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14937                            <= SystemClock.uptimeMillis()) {
14938                        // To avoid spamming the system, we will GC processes one
14939                        // at a time, waiting a few seconds between each.
14940                        performAppGcLocked(proc);
14941                        scheduleAppGcsLocked();
14942                        return;
14943                    } else {
14944                        // It hasn't been long enough since we last GCed this
14945                        // process...  put it in the list to wait for its time.
14946                        addProcessToGcListLocked(proc);
14947                        break;
14948                    }
14949                }
14950            }
14951
14952            scheduleAppGcsLocked();
14953        }
14954    }
14955
14956    /**
14957     * If all looks good, perform GCs on all processes waiting for them.
14958     */
14959    final void performAppGcsIfAppropriateLocked() {
14960        if (canGcNowLocked()) {
14961            performAppGcsLocked();
14962            return;
14963        }
14964        // Still not idle, wait some more.
14965        scheduleAppGcsLocked();
14966    }
14967
14968    /**
14969     * Schedule the execution of all pending app GCs.
14970     */
14971    final void scheduleAppGcsLocked() {
14972        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
14973
14974        if (mProcessesToGc.size() > 0) {
14975            // Schedule a GC for the time to the next process.
14976            ProcessRecord proc = mProcessesToGc.get(0);
14977            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14978
14979            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
14980            long now = SystemClock.uptimeMillis();
14981            if (when < (now+GC_TIMEOUT)) {
14982                when = now + GC_TIMEOUT;
14983            }
14984            mHandler.sendMessageAtTime(msg, when);
14985        }
14986    }
14987
14988    /**
14989     * Add a process to the array of processes waiting to be GCed.  Keeps the
14990     * list in sorted order by the last GC time.  The process can't already be
14991     * on the list.
14992     */
14993    final void addProcessToGcListLocked(ProcessRecord proc) {
14994        boolean added = false;
14995        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14996            if (mProcessesToGc.get(i).lastRequestedGc <
14997                    proc.lastRequestedGc) {
14998                added = true;
14999                mProcessesToGc.add(i+1, proc);
15000                break;
15001            }
15002        }
15003        if (!added) {
15004            mProcessesToGc.add(0, proc);
15005        }
15006    }
15007
15008    /**
15009     * Set up to ask a process to GC itself.  This will either do it
15010     * immediately, or put it on the list of processes to gc the next
15011     * time things are idle.
15012     */
15013    final void scheduleAppGcLocked(ProcessRecord app) {
15014        long now = SystemClock.uptimeMillis();
15015        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15016            return;
15017        }
15018        if (!mProcessesToGc.contains(app)) {
15019            addProcessToGcListLocked(app);
15020            scheduleAppGcsLocked();
15021        }
15022    }
15023
15024    final void checkExcessivePowerUsageLocked(boolean doKills) {
15025        updateCpuStatsNow();
15026
15027        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15028        boolean doWakeKills = doKills;
15029        boolean doCpuKills = doKills;
15030        if (mLastPowerCheckRealtime == 0) {
15031            doWakeKills = false;
15032        }
15033        if (mLastPowerCheckUptime == 0) {
15034            doCpuKills = false;
15035        }
15036        if (stats.isScreenOn()) {
15037            doWakeKills = false;
15038        }
15039        final long curRealtime = SystemClock.elapsedRealtime();
15040        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15041        final long curUptime = SystemClock.uptimeMillis();
15042        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15043        mLastPowerCheckRealtime = curRealtime;
15044        mLastPowerCheckUptime = curUptime;
15045        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15046            doWakeKills = false;
15047        }
15048        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15049            doCpuKills = false;
15050        }
15051        int i = mLruProcesses.size();
15052        while (i > 0) {
15053            i--;
15054            ProcessRecord app = mLruProcesses.get(i);
15055            if (!app.keeping) {
15056                long wtime;
15057                synchronized (stats) {
15058                    wtime = stats.getProcessWakeTime(app.info.uid,
15059                            app.pid, curRealtime);
15060                }
15061                long wtimeUsed = wtime - app.lastWakeTime;
15062                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15063                if (DEBUG_POWER) {
15064                    StringBuilder sb = new StringBuilder(128);
15065                    sb.append("Wake for ");
15066                    app.toShortString(sb);
15067                    sb.append(": over ");
15068                    TimeUtils.formatDuration(realtimeSince, sb);
15069                    sb.append(" used ");
15070                    TimeUtils.formatDuration(wtimeUsed, sb);
15071                    sb.append(" (");
15072                    sb.append((wtimeUsed*100)/realtimeSince);
15073                    sb.append("%)");
15074                    Slog.i(TAG, sb.toString());
15075                    sb.setLength(0);
15076                    sb.append("CPU for ");
15077                    app.toShortString(sb);
15078                    sb.append(": over ");
15079                    TimeUtils.formatDuration(uptimeSince, sb);
15080                    sb.append(" used ");
15081                    TimeUtils.formatDuration(cputimeUsed, sb);
15082                    sb.append(" (");
15083                    sb.append((cputimeUsed*100)/uptimeSince);
15084                    sb.append("%)");
15085                    Slog.i(TAG, sb.toString());
15086                }
15087                // If a process has held a wake lock for more
15088                // than 50% of the time during this period,
15089                // that sounds bad.  Kill!
15090                if (doWakeKills && realtimeSince > 0
15091                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15092                    synchronized (stats) {
15093                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15094                                realtimeSince, wtimeUsed);
15095                    }
15096                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15097                            + " during " + realtimeSince);
15098                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15099                } else if (doCpuKills && uptimeSince > 0
15100                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15101                    synchronized (stats) {
15102                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15103                                uptimeSince, cputimeUsed);
15104                    }
15105                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15106                            + " during " + uptimeSince);
15107                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15108                } else {
15109                    app.lastWakeTime = wtime;
15110                    app.lastCpuTime = app.curCpuTime;
15111                }
15112            }
15113        }
15114    }
15115
15116    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15117            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15118        boolean success = true;
15119
15120        if (app.curRawAdj != app.setRawAdj) {
15121            if (wasKeeping && !app.keeping) {
15122                // This app is no longer something we want to keep.  Note
15123                // its current wake lock time to later know to kill it if
15124                // it is not behaving well.
15125                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15126                synchronized (stats) {
15127                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15128                            app.pid, SystemClock.elapsedRealtime());
15129                }
15130                app.lastCpuTime = app.curCpuTime;
15131            }
15132
15133            app.setRawAdj = app.curRawAdj;
15134        }
15135
15136        if (app.curAdj != app.setAdj) {
15137            ProcessList.setOomAdj(app.pid, app.curAdj);
15138            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15139                TAG, "Set " + app.pid + " " + app.processName +
15140                " adj " + app.curAdj + ": " + app.adjType);
15141            app.setAdj = app.curAdj;
15142        }
15143
15144        if (app.setSchedGroup != app.curSchedGroup) {
15145            app.setSchedGroup = app.curSchedGroup;
15146            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15147                    "Setting process group of " + app.processName
15148                    + " to " + app.curSchedGroup);
15149            if (app.waitingToKill != null &&
15150                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15151                killUnneededProcessLocked(app, app.waitingToKill);
15152                success = false;
15153            } else {
15154                if (true) {
15155                    long oldId = Binder.clearCallingIdentity();
15156                    try {
15157                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15158                    } catch (Exception e) {
15159                        Slog.w(TAG, "Failed setting process group of " + app.pid
15160                                + " to " + app.curSchedGroup);
15161                        e.printStackTrace();
15162                    } finally {
15163                        Binder.restoreCallingIdentity(oldId);
15164                    }
15165                } else {
15166                    if (app.thread != null) {
15167                        try {
15168                            app.thread.setSchedulingGroup(app.curSchedGroup);
15169                        } catch (RemoteException e) {
15170                        }
15171                    }
15172                }
15173                Process.setSwappiness(app.pid,
15174                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15175            }
15176        }
15177        if (app.repProcState != app.curProcState) {
15178            app.repProcState = app.curProcState;
15179            if (!reportingProcessState && app.thread != null) {
15180                try {
15181                    if (false) {
15182                        //RuntimeException h = new RuntimeException("here");
15183                        Slog.i(TAG, "Sending new process state " + app.repProcState
15184                                + " to " + app /*, h*/);
15185                    }
15186                    app.thread.setProcessState(app.repProcState);
15187                } catch (RemoteException e) {
15188                }
15189            }
15190        }
15191        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15192                app.setProcState)) {
15193            app.lastStateTime = now;
15194            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15195                    mSleeping, now);
15196            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15197                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15198                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15199                    + (app.nextPssTime-now) + ": " + app);
15200        } else {
15201            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15202                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15203                requestPssLocked(app, app.setProcState);
15204                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15205                        mSleeping, now);
15206            } else if (false && DEBUG_PSS) {
15207                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15208            }
15209        }
15210        if (app.setProcState != app.curProcState) {
15211            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15212                    "Proc state change of " + app.processName
15213                    + " to " + app.curProcState);
15214            app.setProcState = app.curProcState;
15215            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15216                app.notCachedSinceIdle = false;
15217            }
15218            if (!doingAll) {
15219                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15220            } else {
15221                app.procStateChanged = true;
15222            }
15223        }
15224        return success;
15225    }
15226
15227    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15228        if (proc.thread != null && proc.baseProcessTracker != null) {
15229            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15230        }
15231    }
15232
15233    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15234            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15235        if (app.thread == null) {
15236            return false;
15237        }
15238
15239        final boolean wasKeeping = app.keeping;
15240
15241        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15242
15243        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15244                reportingProcessState, now);
15245    }
15246
15247    private final ActivityRecord resumedAppLocked() {
15248        return mStackSupervisor.resumedAppLocked();
15249    }
15250
15251    final boolean updateOomAdjLocked(ProcessRecord app) {
15252        return updateOomAdjLocked(app, false);
15253    }
15254
15255    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15256        final ActivityRecord TOP_ACT = resumedAppLocked();
15257        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15258        final boolean wasCached = app.cached;
15259
15260        mAdjSeq++;
15261
15262        // This is the desired cached adjusment we want to tell it to use.
15263        // If our app is currently cached, we know it, and that is it.  Otherwise,
15264        // we don't know it yet, and it needs to now be cached we will then
15265        // need to do a complete oom adj.
15266        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15267                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15268        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15269                SystemClock.uptimeMillis());
15270        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15271            // Changed to/from cached state, so apps after it in the LRU
15272            // list may also be changed.
15273            updateOomAdjLocked();
15274        }
15275        return success;
15276    }
15277
15278    final void updateOomAdjLocked() {
15279        final ActivityRecord TOP_ACT = resumedAppLocked();
15280        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15281        final long now = SystemClock.uptimeMillis();
15282        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15283        final int N = mLruProcesses.size();
15284
15285        if (false) {
15286            RuntimeException e = new RuntimeException();
15287            e.fillInStackTrace();
15288            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15289        }
15290
15291        mAdjSeq++;
15292        mNewNumServiceProcs = 0;
15293        mNewNumAServiceProcs = 0;
15294
15295        final int emptyProcessLimit;
15296        final int cachedProcessLimit;
15297        if (mProcessLimit <= 0) {
15298            emptyProcessLimit = cachedProcessLimit = 0;
15299        } else if (mProcessLimit == 1) {
15300            emptyProcessLimit = 1;
15301            cachedProcessLimit = 0;
15302        } else {
15303            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15304            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15305        }
15306
15307        // Let's determine how many processes we have running vs.
15308        // how many slots we have for background processes; we may want
15309        // to put multiple processes in a slot of there are enough of
15310        // them.
15311        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15312                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15313        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15314        if (numEmptyProcs > cachedProcessLimit) {
15315            // If there are more empty processes than our limit on cached
15316            // processes, then use the cached process limit for the factor.
15317            // This ensures that the really old empty processes get pushed
15318            // down to the bottom, so if we are running low on memory we will
15319            // have a better chance at keeping around more cached processes
15320            // instead of a gazillion empty processes.
15321            numEmptyProcs = cachedProcessLimit;
15322        }
15323        int emptyFactor = numEmptyProcs/numSlots;
15324        if (emptyFactor < 1) emptyFactor = 1;
15325        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15326        if (cachedFactor < 1) cachedFactor = 1;
15327        int stepCached = 0;
15328        int stepEmpty = 0;
15329        int numCached = 0;
15330        int numEmpty = 0;
15331        int numTrimming = 0;
15332
15333        mNumNonCachedProcs = 0;
15334        mNumCachedHiddenProcs = 0;
15335
15336        // First update the OOM adjustment for each of the
15337        // application processes based on their current state.
15338        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15339        int nextCachedAdj = curCachedAdj+1;
15340        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15341        int nextEmptyAdj = curEmptyAdj+2;
15342        for (int i=N-1; i>=0; i--) {
15343            ProcessRecord app = mLruProcesses.get(i);
15344            if (!app.killedByAm && app.thread != null) {
15345                app.procStateChanged = false;
15346                final boolean wasKeeping = app.keeping;
15347                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15348
15349                // If we haven't yet assigned the final cached adj
15350                // to the process, do that now.
15351                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15352                    switch (app.curProcState) {
15353                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15354                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15355                            // This process is a cached process holding activities...
15356                            // assign it the next cached value for that type, and then
15357                            // step that cached level.
15358                            app.curRawAdj = curCachedAdj;
15359                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15360                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15361                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15362                                    + ")");
15363                            if (curCachedAdj != nextCachedAdj) {
15364                                stepCached++;
15365                                if (stepCached >= cachedFactor) {
15366                                    stepCached = 0;
15367                                    curCachedAdj = nextCachedAdj;
15368                                    nextCachedAdj += 2;
15369                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15370                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15371                                    }
15372                                }
15373                            }
15374                            break;
15375                        default:
15376                            // For everything else, assign next empty cached process
15377                            // level and bump that up.  Note that this means that
15378                            // long-running services that have dropped down to the
15379                            // cached level will be treated as empty (since their process
15380                            // state is still as a service), which is what we want.
15381                            app.curRawAdj = curEmptyAdj;
15382                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15383                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15384                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15385                                    + ")");
15386                            if (curEmptyAdj != nextEmptyAdj) {
15387                                stepEmpty++;
15388                                if (stepEmpty >= emptyFactor) {
15389                                    stepEmpty = 0;
15390                                    curEmptyAdj = nextEmptyAdj;
15391                                    nextEmptyAdj += 2;
15392                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15393                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15394                                    }
15395                                }
15396                            }
15397                            break;
15398                    }
15399                }
15400
15401                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15402
15403                // Count the number of process types.
15404                switch (app.curProcState) {
15405                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15406                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15407                        mNumCachedHiddenProcs++;
15408                        numCached++;
15409                        if (numCached > cachedProcessLimit) {
15410                            killUnneededProcessLocked(app, "cached #" + numCached);
15411                        }
15412                        break;
15413                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15414                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15415                                && app.lastActivityTime < oldTime) {
15416                            killUnneededProcessLocked(app, "empty for "
15417                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15418                                    / 1000) + "s");
15419                        } else {
15420                            numEmpty++;
15421                            if (numEmpty > emptyProcessLimit) {
15422                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15423                            }
15424                        }
15425                        break;
15426                    default:
15427                        mNumNonCachedProcs++;
15428                        break;
15429                }
15430
15431                if (app.isolated && app.services.size() <= 0) {
15432                    // If this is an isolated process, and there are no
15433                    // services running in it, then the process is no longer
15434                    // needed.  We agressively kill these because we can by
15435                    // definition not re-use the same process again, and it is
15436                    // good to avoid having whatever code was running in them
15437                    // left sitting around after no longer needed.
15438                    killUnneededProcessLocked(app, "isolated not needed");
15439                }
15440
15441                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15442                        && !app.killedByAm) {
15443                    numTrimming++;
15444                }
15445            }
15446        }
15447
15448        mNumServiceProcs = mNewNumServiceProcs;
15449
15450        // Now determine the memory trimming level of background processes.
15451        // Unfortunately we need to start at the back of the list to do this
15452        // properly.  We only do this if the number of background apps we
15453        // are managing to keep around is less than half the maximum we desire;
15454        // if we are keeping a good number around, we'll let them use whatever
15455        // memory they want.
15456        final int numCachedAndEmpty = numCached + numEmpty;
15457        int memFactor;
15458        if (numCached <= ProcessList.TRIM_CACHED_APPS
15459                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15460            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15461                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15462            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15463                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15464            } else {
15465                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15466            }
15467        } else {
15468            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15469        }
15470        // We always allow the memory level to go up (better).  We only allow it to go
15471        // down if we are in a state where that is allowed, *and* the total number of processes
15472        // has gone down since last time.
15473        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15474                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15475                + " last=" + mLastNumProcesses);
15476        if (memFactor > mLastMemoryLevel) {
15477            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15478                memFactor = mLastMemoryLevel;
15479                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15480            }
15481        }
15482        mLastMemoryLevel = memFactor;
15483        mLastNumProcesses = mLruProcesses.size();
15484        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15485        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15486        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15487            if (mLowRamStartTime == 0) {
15488                mLowRamStartTime = now;
15489            }
15490            int step = 0;
15491            int fgTrimLevel;
15492            switch (memFactor) {
15493                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15494                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15495                    break;
15496                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15497                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15498                    break;
15499                default:
15500                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15501                    break;
15502            }
15503            int factor = numTrimming/3;
15504            int minFactor = 2;
15505            if (mHomeProcess != null) minFactor++;
15506            if (mPreviousProcess != null) minFactor++;
15507            if (factor < minFactor) factor = minFactor;
15508            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15509            for (int i=N-1; i>=0; i--) {
15510                ProcessRecord app = mLruProcesses.get(i);
15511                if (allChanged || app.procStateChanged) {
15512                    setProcessTrackerState(app, trackerMemFactor, now);
15513                    app.procStateChanged = false;
15514                }
15515                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15516                        && !app.killedByAm) {
15517                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15518                        try {
15519                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15520                                    "Trimming memory of " + app.processName
15521                                    + " to " + curLevel);
15522                            app.thread.scheduleTrimMemory(curLevel);
15523                        } catch (RemoteException e) {
15524                        }
15525                        if (false) {
15526                            // For now we won't do this; our memory trimming seems
15527                            // to be good enough at this point that destroying
15528                            // activities causes more harm than good.
15529                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15530                                    && app != mHomeProcess && app != mPreviousProcess) {
15531                                // Need to do this on its own message because the stack may not
15532                                // be in a consistent state at this point.
15533                                // For these apps we will also finish their activities
15534                                // to help them free memory.
15535                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15536                            }
15537                        }
15538                    }
15539                    app.trimMemoryLevel = curLevel;
15540                    step++;
15541                    if (step >= factor) {
15542                        step = 0;
15543                        switch (curLevel) {
15544                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15545                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15546                                break;
15547                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15548                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15549                                break;
15550                        }
15551                    }
15552                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15553                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15554                            && app.thread != null) {
15555                        try {
15556                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15557                                    "Trimming memory of heavy-weight " + app.processName
15558                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15559                            app.thread.scheduleTrimMemory(
15560                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15561                        } catch (RemoteException e) {
15562                        }
15563                    }
15564                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15565                } else {
15566                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15567                            || app.systemNoUi) && app.pendingUiClean) {
15568                        // If this application is now in the background and it
15569                        // had done UI, then give it the special trim level to
15570                        // have it free UI resources.
15571                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15572                        if (app.trimMemoryLevel < level && app.thread != null) {
15573                            try {
15574                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15575                                        "Trimming memory of bg-ui " + app.processName
15576                                        + " to " + level);
15577                                app.thread.scheduleTrimMemory(level);
15578                            } catch (RemoteException e) {
15579                            }
15580                        }
15581                        app.pendingUiClean = false;
15582                    }
15583                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15584                        try {
15585                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15586                                    "Trimming memory of fg " + app.processName
15587                                    + " to " + fgTrimLevel);
15588                            app.thread.scheduleTrimMemory(fgTrimLevel);
15589                        } catch (RemoteException e) {
15590                        }
15591                    }
15592                    app.trimMemoryLevel = fgTrimLevel;
15593                }
15594            }
15595        } else {
15596            if (mLowRamStartTime != 0) {
15597                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15598                mLowRamStartTime = 0;
15599            }
15600            for (int i=N-1; i>=0; i--) {
15601                ProcessRecord app = mLruProcesses.get(i);
15602                if (allChanged || app.procStateChanged) {
15603                    setProcessTrackerState(app, trackerMemFactor, now);
15604                    app.procStateChanged = false;
15605                }
15606                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15607                        || app.systemNoUi) && app.pendingUiClean) {
15608                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15609                            && app.thread != null) {
15610                        try {
15611                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15612                                    "Trimming memory of ui hidden " + app.processName
15613                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15614                            app.thread.scheduleTrimMemory(
15615                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15616                        } catch (RemoteException e) {
15617                        }
15618                    }
15619                    app.pendingUiClean = false;
15620                }
15621                app.trimMemoryLevel = 0;
15622            }
15623        }
15624
15625        if (mAlwaysFinishActivities) {
15626            // Need to do this on its own message because the stack may not
15627            // be in a consistent state at this point.
15628            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15629        }
15630
15631        if (allChanged) {
15632            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15633        }
15634
15635        if (mProcessStats.shouldWriteNowLocked(now)) {
15636            mHandler.post(new Runnable() {
15637                @Override public void run() {
15638                    synchronized (ActivityManagerService.this) {
15639                        mProcessStats.writeStateAsyncLocked();
15640                    }
15641                }
15642            });
15643        }
15644
15645        if (DEBUG_OOM_ADJ) {
15646            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15647        }
15648    }
15649
15650    final void trimApplications() {
15651        synchronized (this) {
15652            int i;
15653
15654            // First remove any unused application processes whose package
15655            // has been removed.
15656            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15657                final ProcessRecord app = mRemovedProcesses.get(i);
15658                if (app.activities.size() == 0
15659                        && app.curReceiver == null && app.services.size() == 0) {
15660                    Slog.i(
15661                        TAG, "Exiting empty application process "
15662                        + app.processName + " ("
15663                        + (app.thread != null ? app.thread.asBinder() : null)
15664                        + ")\n");
15665                    if (app.pid > 0 && app.pid != MY_PID) {
15666                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15667                                app.processName, app.setAdj, "empty");
15668                        app.killedByAm = true;
15669                        Process.killProcessQuiet(app.pid);
15670                    } else {
15671                        try {
15672                            app.thread.scheduleExit();
15673                        } catch (Exception e) {
15674                            // Ignore exceptions.
15675                        }
15676                    }
15677                    cleanUpApplicationRecordLocked(app, false, true, -1);
15678                    mRemovedProcesses.remove(i);
15679
15680                    if (app.persistent) {
15681                        if (app.persistent) {
15682                            addAppLocked(app.info, false);
15683                        }
15684                    }
15685                }
15686            }
15687
15688            // Now update the oom adj for all processes.
15689            updateOomAdjLocked();
15690        }
15691    }
15692
15693    /** This method sends the specified signal to each of the persistent apps */
15694    public void signalPersistentProcesses(int sig) throws RemoteException {
15695        if (sig != Process.SIGNAL_USR1) {
15696            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15697        }
15698
15699        synchronized (this) {
15700            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15701                    != PackageManager.PERMISSION_GRANTED) {
15702                throw new SecurityException("Requires permission "
15703                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15704            }
15705
15706            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15707                ProcessRecord r = mLruProcesses.get(i);
15708                if (r.thread != null && r.persistent) {
15709                    Process.sendSignal(r.pid, sig);
15710                }
15711            }
15712        }
15713    }
15714
15715    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15716        if (proc == null || proc == mProfileProc) {
15717            proc = mProfileProc;
15718            path = mProfileFile;
15719            profileType = mProfileType;
15720            clearProfilerLocked();
15721        }
15722        if (proc == null) {
15723            return;
15724        }
15725        try {
15726            proc.thread.profilerControl(false, path, null, profileType);
15727        } catch (RemoteException e) {
15728            throw new IllegalStateException("Process disappeared");
15729        }
15730    }
15731
15732    private void clearProfilerLocked() {
15733        if (mProfileFd != null) {
15734            try {
15735                mProfileFd.close();
15736            } catch (IOException e) {
15737            }
15738        }
15739        mProfileApp = null;
15740        mProfileProc = null;
15741        mProfileFile = null;
15742        mProfileType = 0;
15743        mAutoStopProfiler = false;
15744    }
15745
15746    public boolean profileControl(String process, int userId, boolean start,
15747            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15748
15749        try {
15750            synchronized (this) {
15751                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15752                // its own permission.
15753                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15754                        != PackageManager.PERMISSION_GRANTED) {
15755                    throw new SecurityException("Requires permission "
15756                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15757                }
15758
15759                if (start && fd == null) {
15760                    throw new IllegalArgumentException("null fd");
15761                }
15762
15763                ProcessRecord proc = null;
15764                if (process != null) {
15765                    proc = findProcessLocked(process, userId, "profileControl");
15766                }
15767
15768                if (start && (proc == null || proc.thread == null)) {
15769                    throw new IllegalArgumentException("Unknown process: " + process);
15770                }
15771
15772                if (start) {
15773                    stopProfilerLocked(null, null, 0);
15774                    setProfileApp(proc.info, proc.processName, path, fd, false);
15775                    mProfileProc = proc;
15776                    mProfileType = profileType;
15777                    try {
15778                        fd = fd.dup();
15779                    } catch (IOException e) {
15780                        fd = null;
15781                    }
15782                    proc.thread.profilerControl(start, path, fd, profileType);
15783                    fd = null;
15784                    mProfileFd = null;
15785                } else {
15786                    stopProfilerLocked(proc, path, profileType);
15787                    if (fd != null) {
15788                        try {
15789                            fd.close();
15790                        } catch (IOException e) {
15791                        }
15792                    }
15793                }
15794
15795                return true;
15796            }
15797        } catch (RemoteException e) {
15798            throw new IllegalStateException("Process disappeared");
15799        } finally {
15800            if (fd != null) {
15801                try {
15802                    fd.close();
15803                } catch (IOException e) {
15804                }
15805            }
15806        }
15807    }
15808
15809    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15810        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15811                userId, true, true, callName, null);
15812        ProcessRecord proc = null;
15813        try {
15814            int pid = Integer.parseInt(process);
15815            synchronized (mPidsSelfLocked) {
15816                proc = mPidsSelfLocked.get(pid);
15817            }
15818        } catch (NumberFormatException e) {
15819        }
15820
15821        if (proc == null) {
15822            ArrayMap<String, SparseArray<ProcessRecord>> all
15823                    = mProcessNames.getMap();
15824            SparseArray<ProcessRecord> procs = all.get(process);
15825            if (procs != null && procs.size() > 0) {
15826                proc = procs.valueAt(0);
15827                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15828                    for (int i=1; i<procs.size(); i++) {
15829                        ProcessRecord thisProc = procs.valueAt(i);
15830                        if (thisProc.userId == userId) {
15831                            proc = thisProc;
15832                            break;
15833                        }
15834                    }
15835                }
15836            }
15837        }
15838
15839        return proc;
15840    }
15841
15842    public boolean dumpHeap(String process, int userId, boolean managed,
15843            String path, ParcelFileDescriptor fd) throws RemoteException {
15844
15845        try {
15846            synchronized (this) {
15847                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15848                // its own permission (same as profileControl).
15849                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15850                        != PackageManager.PERMISSION_GRANTED) {
15851                    throw new SecurityException("Requires permission "
15852                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15853                }
15854
15855                if (fd == null) {
15856                    throw new IllegalArgumentException("null fd");
15857                }
15858
15859                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15860                if (proc == null || proc.thread == null) {
15861                    throw new IllegalArgumentException("Unknown process: " + process);
15862                }
15863
15864                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15865                if (!isDebuggable) {
15866                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15867                        throw new SecurityException("Process not debuggable: " + proc);
15868                    }
15869                }
15870
15871                proc.thread.dumpHeap(managed, path, fd);
15872                fd = null;
15873                return true;
15874            }
15875        } catch (RemoteException e) {
15876            throw new IllegalStateException("Process disappeared");
15877        } finally {
15878            if (fd != null) {
15879                try {
15880                    fd.close();
15881                } catch (IOException e) {
15882                }
15883            }
15884        }
15885    }
15886
15887    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15888    public void monitor() {
15889        synchronized (this) { }
15890    }
15891
15892    void onCoreSettingsChange(Bundle settings) {
15893        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15894            ProcessRecord processRecord = mLruProcesses.get(i);
15895            try {
15896                if (processRecord.thread != null) {
15897                    processRecord.thread.setCoreSettings(settings);
15898                }
15899            } catch (RemoteException re) {
15900                /* ignore */
15901            }
15902        }
15903    }
15904
15905    // Multi-user methods
15906
15907    @Override
15908    public boolean switchUser(final int userId) {
15909        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15910                != PackageManager.PERMISSION_GRANTED) {
15911            String msg = "Permission Denial: switchUser() from pid="
15912                    + Binder.getCallingPid()
15913                    + ", uid=" + Binder.getCallingUid()
15914                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15915            Slog.w(TAG, msg);
15916            throw new SecurityException(msg);
15917        }
15918
15919        final long ident = Binder.clearCallingIdentity();
15920        try {
15921            synchronized (this) {
15922                final int oldUserId = mCurrentUserId;
15923                if (oldUserId == userId) {
15924                    return true;
15925                }
15926
15927                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15928                if (userInfo == null) {
15929                    Slog.w(TAG, "No user info for user #" + userId);
15930                    return false;
15931                }
15932
15933                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15934                        R.anim.screen_user_enter);
15935
15936                boolean needStart = false;
15937
15938                // If the user we are switching to is not currently started, then
15939                // we need to start it now.
15940                if (mStartedUsers.get(userId) == null) {
15941                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
15942                    updateStartedUserArrayLocked();
15943                    needStart = true;
15944                }
15945
15946                mCurrentUserId = userId;
15947                final Integer userIdInt = Integer.valueOf(userId);
15948                mUserLru.remove(userIdInt);
15949                mUserLru.add(userIdInt);
15950
15951                mWindowManager.setCurrentUser(userId);
15952
15953                // Once the internal notion of the active user has switched, we lock the device
15954                // with the option to show the user switcher on the keyguard.
15955                mWindowManager.lockNow(null);
15956
15957                final UserStartedState uss = mStartedUsers.get(userId);
15958
15959                // Make sure user is in the started state.  If it is currently
15960                // stopping, we need to knock that off.
15961                if (uss.mState == UserStartedState.STATE_STOPPING) {
15962                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
15963                    // so we can just fairly silently bring the user back from
15964                    // the almost-dead.
15965                    uss.mState = UserStartedState.STATE_RUNNING;
15966                    updateStartedUserArrayLocked();
15967                    needStart = true;
15968                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
15969                    // This means ACTION_SHUTDOWN has been sent, so we will
15970                    // need to treat this as a new boot of the user.
15971                    uss.mState = UserStartedState.STATE_BOOTING;
15972                    updateStartedUserArrayLocked();
15973                    needStart = true;
15974                }
15975
15976                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
15977                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
15978                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
15979                        oldUserId, userId, uss));
15980                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
15981                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
15982                if (needStart) {
15983                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
15984                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15985                            | Intent.FLAG_RECEIVER_FOREGROUND);
15986                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
15987                    broadcastIntentLocked(null, null, intent,
15988                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15989                            false, false, MY_PID, Process.SYSTEM_UID, userId);
15990                }
15991
15992                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
15993                    if (userId != 0) {
15994                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
15995                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15996                        broadcastIntentLocked(null, null, intent, null,
15997                                new IIntentReceiver.Stub() {
15998                                    public void performReceive(Intent intent, int resultCode,
15999                                            String data, Bundle extras, boolean ordered,
16000                                            boolean sticky, int sendingUser) {
16001                                        userInitialized(uss, userId);
16002                                    }
16003                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16004                                true, false, MY_PID, Process.SYSTEM_UID,
16005                                userId);
16006                        uss.initializing = true;
16007                    } else {
16008                        getUserManagerLocked().makeInitialized(userInfo.id);
16009                    }
16010                }
16011
16012                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16013                if (homeInFront) {
16014                    startHomeActivityLocked(userId);
16015                } else {
16016                    mStackSupervisor.resumeTopActivitiesLocked();
16017                }
16018
16019                EventLogTags.writeAmSwitchUser(userId);
16020                getUserManagerLocked().userForeground(userId);
16021                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16022                if (needStart) {
16023                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16024                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16025                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16026                    broadcastIntentLocked(null, null, intent,
16027                            null, new IIntentReceiver.Stub() {
16028                                @Override
16029                                public void performReceive(Intent intent, int resultCode, String data,
16030                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16031                                        throws RemoteException {
16032                                }
16033                            }, 0, null, null,
16034                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16035                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16036                }
16037            }
16038        } finally {
16039            Binder.restoreCallingIdentity(ident);
16040        }
16041
16042        return true;
16043    }
16044
16045    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16046        long ident = Binder.clearCallingIdentity();
16047        try {
16048            Intent intent;
16049            if (oldUserId >= 0) {
16050                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16051                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16052                        | Intent.FLAG_RECEIVER_FOREGROUND);
16053                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16054                broadcastIntentLocked(null, null, intent,
16055                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16056                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16057            }
16058            if (newUserId >= 0) {
16059                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16060                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16061                        | Intent.FLAG_RECEIVER_FOREGROUND);
16062                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16063                broadcastIntentLocked(null, null, intent,
16064                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16065                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16066                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16067                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16068                        | Intent.FLAG_RECEIVER_FOREGROUND);
16069                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16070                broadcastIntentLocked(null, null, intent,
16071                        null, null, 0, null, null,
16072                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16073                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16074            }
16075        } finally {
16076            Binder.restoreCallingIdentity(ident);
16077        }
16078    }
16079
16080    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16081            final int newUserId) {
16082        final int N = mUserSwitchObservers.beginBroadcast();
16083        if (N > 0) {
16084            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16085                int mCount = 0;
16086                @Override
16087                public void sendResult(Bundle data) throws RemoteException {
16088                    synchronized (ActivityManagerService.this) {
16089                        if (mCurUserSwitchCallback == this) {
16090                            mCount++;
16091                            if (mCount == N) {
16092                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16093                            }
16094                        }
16095                    }
16096                }
16097            };
16098            synchronized (this) {
16099                uss.switching = true;
16100                mCurUserSwitchCallback = callback;
16101            }
16102            for (int i=0; i<N; i++) {
16103                try {
16104                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16105                            newUserId, callback);
16106                } catch (RemoteException e) {
16107                }
16108            }
16109        } else {
16110            synchronized (this) {
16111                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16112            }
16113        }
16114        mUserSwitchObservers.finishBroadcast();
16115    }
16116
16117    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16118        synchronized (this) {
16119            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16120            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16121        }
16122    }
16123
16124    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16125        mCurUserSwitchCallback = null;
16126        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16127        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16128                oldUserId, newUserId, uss));
16129    }
16130
16131    void userInitialized(UserStartedState uss, int newUserId) {
16132        completeSwitchAndInitalize(uss, newUserId, true, false);
16133    }
16134
16135    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16136        completeSwitchAndInitalize(uss, newUserId, false, true);
16137    }
16138
16139    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16140            boolean clearInitializing, boolean clearSwitching) {
16141        boolean unfrozen = false;
16142        synchronized (this) {
16143            if (clearInitializing) {
16144                uss.initializing = false;
16145                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16146            }
16147            if (clearSwitching) {
16148                uss.switching = false;
16149            }
16150            if (!uss.switching && !uss.initializing) {
16151                mWindowManager.stopFreezingScreen();
16152                unfrozen = true;
16153            }
16154        }
16155        if (unfrozen) {
16156            final int N = mUserSwitchObservers.beginBroadcast();
16157            for (int i=0; i<N; i++) {
16158                try {
16159                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16160                } catch (RemoteException e) {
16161                }
16162            }
16163            mUserSwitchObservers.finishBroadcast();
16164        }
16165    }
16166
16167    void finishUserSwitch(UserStartedState uss) {
16168        synchronized (this) {
16169            if (uss.mState == UserStartedState.STATE_BOOTING
16170                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16171                uss.mState = UserStartedState.STATE_RUNNING;
16172                final int userId = uss.mHandle.getIdentifier();
16173                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16174                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16175                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16176                broadcastIntentLocked(null, null, intent,
16177                        null, null, 0, null, null,
16178                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16179                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16180            }
16181            int num = mUserLru.size();
16182            int i = 0;
16183            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16184                Integer oldUserId = mUserLru.get(i);
16185                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16186                if (oldUss == null) {
16187                    // Shouldn't happen, but be sane if it does.
16188                    mUserLru.remove(i);
16189                    num--;
16190                    continue;
16191                }
16192                if (oldUss.mState == UserStartedState.STATE_STOPPING
16193                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16194                    // This user is already stopping, doesn't count.
16195                    num--;
16196                    i++;
16197                    continue;
16198                }
16199                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16200                    // Owner and current can't be stopped, but count as running.
16201                    i++;
16202                    continue;
16203                }
16204                // This is a user to be stopped.
16205                stopUserLocked(oldUserId, null);
16206                num--;
16207                i++;
16208            }
16209        }
16210    }
16211
16212    @Override
16213    public int stopUser(final int userId, final IStopUserCallback callback) {
16214        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16215                != PackageManager.PERMISSION_GRANTED) {
16216            String msg = "Permission Denial: switchUser() from pid="
16217                    + Binder.getCallingPid()
16218                    + ", uid=" + Binder.getCallingUid()
16219                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16220            Slog.w(TAG, msg);
16221            throw new SecurityException(msg);
16222        }
16223        if (userId <= 0) {
16224            throw new IllegalArgumentException("Can't stop primary user " + userId);
16225        }
16226        synchronized (this) {
16227            return stopUserLocked(userId, callback);
16228        }
16229    }
16230
16231    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16232        if (mCurrentUserId == userId) {
16233            return ActivityManager.USER_OP_IS_CURRENT;
16234        }
16235
16236        final UserStartedState uss = mStartedUsers.get(userId);
16237        if (uss == null) {
16238            // User is not started, nothing to do...  but we do need to
16239            // callback if requested.
16240            if (callback != null) {
16241                mHandler.post(new Runnable() {
16242                    @Override
16243                    public void run() {
16244                        try {
16245                            callback.userStopped(userId);
16246                        } catch (RemoteException e) {
16247                        }
16248                    }
16249                });
16250            }
16251            return ActivityManager.USER_OP_SUCCESS;
16252        }
16253
16254        if (callback != null) {
16255            uss.mStopCallbacks.add(callback);
16256        }
16257
16258        if (uss.mState != UserStartedState.STATE_STOPPING
16259                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16260            uss.mState = UserStartedState.STATE_STOPPING;
16261            updateStartedUserArrayLocked();
16262
16263            long ident = Binder.clearCallingIdentity();
16264            try {
16265                // We are going to broadcast ACTION_USER_STOPPING and then
16266                // once that is done send a final ACTION_SHUTDOWN and then
16267                // stop the user.
16268                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16269                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16270                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16271                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16272                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16273                // This is the result receiver for the final shutdown broadcast.
16274                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16275                    @Override
16276                    public void performReceive(Intent intent, int resultCode, String data,
16277                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16278                        finishUserStop(uss);
16279                    }
16280                };
16281                // This is the result receiver for the initial stopping broadcast.
16282                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16283                    @Override
16284                    public void performReceive(Intent intent, int resultCode, String data,
16285                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16286                        // On to the next.
16287                        synchronized (ActivityManagerService.this) {
16288                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16289                                // Whoops, we are being started back up.  Abort, abort!
16290                                return;
16291                            }
16292                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16293                        }
16294                        broadcastIntentLocked(null, null, shutdownIntent,
16295                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16296                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16297                    }
16298                };
16299                // Kick things off.
16300                broadcastIntentLocked(null, null, stoppingIntent,
16301                        null, stoppingReceiver, 0, null, null,
16302                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16303                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16304            } finally {
16305                Binder.restoreCallingIdentity(ident);
16306            }
16307        }
16308
16309        return ActivityManager.USER_OP_SUCCESS;
16310    }
16311
16312    void finishUserStop(UserStartedState uss) {
16313        final int userId = uss.mHandle.getIdentifier();
16314        boolean stopped;
16315        ArrayList<IStopUserCallback> callbacks;
16316        synchronized (this) {
16317            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16318            if (mStartedUsers.get(userId) != uss) {
16319                stopped = false;
16320            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16321                stopped = false;
16322            } else {
16323                stopped = true;
16324                // User can no longer run.
16325                mStartedUsers.remove(userId);
16326                mUserLru.remove(Integer.valueOf(userId));
16327                updateStartedUserArrayLocked();
16328
16329                // Clean up all state and processes associated with the user.
16330                // Kill all the processes for the user.
16331                forceStopUserLocked(userId, "finish user");
16332            }
16333        }
16334
16335        for (int i=0; i<callbacks.size(); i++) {
16336            try {
16337                if (stopped) callbacks.get(i).userStopped(userId);
16338                else callbacks.get(i).userStopAborted(userId);
16339            } catch (RemoteException e) {
16340            }
16341        }
16342
16343        mStackSupervisor.removeUserLocked(userId);
16344    }
16345
16346    @Override
16347    public UserInfo getCurrentUser() {
16348        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16349                != PackageManager.PERMISSION_GRANTED) && (
16350                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16351                != PackageManager.PERMISSION_GRANTED)) {
16352            String msg = "Permission Denial: getCurrentUser() from pid="
16353                    + Binder.getCallingPid()
16354                    + ", uid=" + Binder.getCallingUid()
16355                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16356            Slog.w(TAG, msg);
16357            throw new SecurityException(msg);
16358        }
16359        synchronized (this) {
16360            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16361        }
16362    }
16363
16364    int getCurrentUserIdLocked() {
16365        return mCurrentUserId;
16366    }
16367
16368    @Override
16369    public boolean isUserRunning(int userId, boolean orStopped) {
16370        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16371                != PackageManager.PERMISSION_GRANTED) {
16372            String msg = "Permission Denial: isUserRunning() from pid="
16373                    + Binder.getCallingPid()
16374                    + ", uid=" + Binder.getCallingUid()
16375                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16376            Slog.w(TAG, msg);
16377            throw new SecurityException(msg);
16378        }
16379        synchronized (this) {
16380            return isUserRunningLocked(userId, orStopped);
16381        }
16382    }
16383
16384    boolean isUserRunningLocked(int userId, boolean orStopped) {
16385        UserStartedState state = mStartedUsers.get(userId);
16386        if (state == null) {
16387            return false;
16388        }
16389        if (orStopped) {
16390            return true;
16391        }
16392        return state.mState != UserStartedState.STATE_STOPPING
16393                && state.mState != UserStartedState.STATE_SHUTDOWN;
16394    }
16395
16396    @Override
16397    public int[] getRunningUserIds() {
16398        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16399                != PackageManager.PERMISSION_GRANTED) {
16400            String msg = "Permission Denial: isUserRunning() from pid="
16401                    + Binder.getCallingPid()
16402                    + ", uid=" + Binder.getCallingUid()
16403                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16404            Slog.w(TAG, msg);
16405            throw new SecurityException(msg);
16406        }
16407        synchronized (this) {
16408            return mStartedUserArray;
16409        }
16410    }
16411
16412    private void updateStartedUserArrayLocked() {
16413        int num = 0;
16414        for (int i=0; i<mStartedUsers.size();  i++) {
16415            UserStartedState uss = mStartedUsers.valueAt(i);
16416            // This list does not include stopping users.
16417            if (uss.mState != UserStartedState.STATE_STOPPING
16418                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16419                num++;
16420            }
16421        }
16422        mStartedUserArray = new int[num];
16423        num = 0;
16424        for (int i=0; i<mStartedUsers.size();  i++) {
16425            UserStartedState uss = mStartedUsers.valueAt(i);
16426            if (uss.mState != UserStartedState.STATE_STOPPING
16427                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16428                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16429                num++;
16430            }
16431        }
16432    }
16433
16434    @Override
16435    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16436        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16437                != PackageManager.PERMISSION_GRANTED) {
16438            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16439                    + Binder.getCallingPid()
16440                    + ", uid=" + Binder.getCallingUid()
16441                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16442            Slog.w(TAG, msg);
16443            throw new SecurityException(msg);
16444        }
16445
16446        mUserSwitchObservers.register(observer);
16447    }
16448
16449    @Override
16450    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16451        mUserSwitchObservers.unregister(observer);
16452    }
16453
16454    private boolean userExists(int userId) {
16455        if (userId == 0) {
16456            return true;
16457        }
16458        UserManagerService ums = getUserManagerLocked();
16459        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16460    }
16461
16462    int[] getUsersLocked() {
16463        UserManagerService ums = getUserManagerLocked();
16464        return ums != null ? ums.getUserIds() : new int[] { 0 };
16465    }
16466
16467    UserManagerService getUserManagerLocked() {
16468        if (mUserManager == null) {
16469            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16470            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16471        }
16472        return mUserManager;
16473    }
16474
16475    private int applyUserId(int uid, int userId) {
16476        return UserHandle.getUid(userId, uid);
16477    }
16478
16479    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16480        if (info == null) return null;
16481        ApplicationInfo newInfo = new ApplicationInfo(info);
16482        newInfo.uid = applyUserId(info.uid, userId);
16483        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16484                + info.packageName;
16485        return newInfo;
16486    }
16487
16488    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16489        if (aInfo == null
16490                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16491            return aInfo;
16492        }
16493
16494        ActivityInfo info = new ActivityInfo(aInfo);
16495        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16496        return info;
16497    }
16498
16499    private final class LocalService extends ActivityManagerInternal {
16500        @Override
16501        public void goingToSleep() {
16502            ActivityManagerService.this.goingToSleep();
16503        }
16504
16505        @Override
16506        public void wakingUp() {
16507            ActivityManagerService.this.wakingUp();
16508        }
16509    }
16510}
16511