ActivityManagerService.java revision 95da1087ed3c7b9983b571bc5409827ae390f15f
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27
28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
29
30import android.app.AppOpsManager;
31import android.app.IActivityContainer;
32import android.app.IActivityContainerCallback;
33import android.appwidget.AppWidgetManager;
34import android.graphics.Rect;
35import android.util.ArrayMap;
36import com.android.internal.R;
37import com.android.internal.annotations.GuardedBy;
38import com.android.internal.app.IAppOpsService;
39import com.android.internal.app.ProcessMap;
40import com.android.internal.app.ProcessStats;
41import com.android.internal.os.BackgroundThread;
42import com.android.internal.os.BatteryStatsImpl;
43import com.android.internal.os.ProcessCpuTracker;
44import com.android.internal.os.TransferPipe;
45import com.android.internal.util.FastPrintWriter;
46import com.android.internal.util.FastXmlSerializer;
47import com.android.internal.util.MemInfoReader;
48import com.android.internal.util.Preconditions;
49import com.android.server.AppOpsService;
50import com.android.server.AttributeCache;
51import com.android.server.IntentResolver;
52import com.android.server.ServiceThread;
53import com.android.server.SystemService;
54import com.android.server.Watchdog;
55import com.android.server.am.ActivityStack.ActivityState;
56import com.android.server.firewall.IntentFirewall;
57import com.android.server.pm.UserManagerService;
58import com.android.server.wm.AppTransition;
59import com.android.server.wm.WindowManagerService;
60import com.google.android.collect.Lists;
61import com.google.android.collect.Maps;
62
63import dalvik.system.Zygote;
64
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.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.ApplicationErrorReport;
81import android.app.Dialog;
82import android.app.IActivityController;
83import android.app.IApplicationThread;
84import android.app.IInstrumentationWatcher;
85import android.app.INotificationManager;
86import android.app.IProcessObserver;
87import android.app.IServiceConnection;
88import android.app.IStopUserCallback;
89import android.app.IThumbnailReceiver;
90import android.app.IUiAutomationConnection;
91import android.app.IUserSwitchObserver;
92import android.app.Instrumentation;
93import android.app.Notification;
94import android.app.NotificationManager;
95import android.app.PendingIntent;
96import android.app.backup.IBackupManager;
97import android.content.ActivityNotFoundException;
98import android.content.BroadcastReceiver;
99import android.content.ClipData;
100import android.content.ComponentCallbacks2;
101import android.content.ComponentName;
102import android.content.ContentProvider;
103import android.content.ContentResolver;
104import android.content.Context;
105import android.content.DialogInterface;
106import android.content.IContentProvider;
107import android.content.IIntentReceiver;
108import android.content.IIntentSender;
109import android.content.Intent;
110import android.content.IntentFilter;
111import android.content.IntentSender;
112import android.content.pm.ActivityInfo;
113import android.content.pm.ApplicationInfo;
114import android.content.pm.ConfigurationInfo;
115import android.content.pm.IPackageDataObserver;
116import android.content.pm.IPackageManager;
117import android.content.pm.InstrumentationInfo;
118import android.content.pm.PackageInfo;
119import android.content.pm.PackageManager;
120import android.content.pm.ParceledListSlice;
121import android.content.pm.UserInfo;
122import android.content.pm.PackageManager.NameNotFoundException;
123import android.content.pm.PathPermission;
124import android.content.pm.ProviderInfo;
125import android.content.pm.ResolveInfo;
126import android.content.pm.ServiceInfo;
127import android.content.res.CompatibilityInfo;
128import android.content.res.Configuration;
129import android.graphics.Bitmap;
130import android.net.Proxy;
131import android.net.ProxyProperties;
132import android.net.Uri;
133import android.os.Binder;
134import android.os.Build;
135import android.os.Bundle;
136import android.os.Debug;
137import android.os.DropBoxManager;
138import android.os.Environment;
139import android.os.FactoryTest;
140import android.os.FileObserver;
141import android.os.FileUtils;
142import android.os.Handler;
143import android.os.IBinder;
144import android.os.IPermissionController;
145import android.os.IRemoteCallback;
146import android.os.IUserManager;
147import android.os.Looper;
148import android.os.Message;
149import android.os.Parcel;
150import android.os.ParcelFileDescriptor;
151import android.os.Process;
152import android.os.RemoteCallbackList;
153import android.os.RemoteException;
154import android.os.SELinux;
155import android.os.ServiceManager;
156import android.os.StrictMode;
157import android.os.SystemClock;
158import android.os.SystemProperties;
159import android.os.UpdateLock;
160import android.os.UserHandle;
161import android.provider.Settings;
162import android.text.format.DateUtils;
163import android.text.format.Time;
164import android.util.AtomicFile;
165import android.util.EventLog;
166import android.util.Log;
167import android.util.Pair;
168import android.util.PrintWriterPrinter;
169import android.util.Slog;
170import android.util.SparseArray;
171import android.util.TimeUtils;
172import android.util.Xml;
173import android.view.Gravity;
174import android.view.LayoutInflater;
175import android.view.View;
176import android.view.WindowManager;
177
178import java.io.BufferedInputStream;
179import java.io.BufferedOutputStream;
180import java.io.DataInputStream;
181import java.io.DataOutputStream;
182import java.io.File;
183import java.io.FileDescriptor;
184import java.io.FileInputStream;
185import java.io.FileNotFoundException;
186import java.io.FileOutputStream;
187import java.io.IOException;
188import java.io.InputStreamReader;
189import java.io.PrintWriter;
190import java.io.StringWriter;
191import java.lang.ref.WeakReference;
192import java.util.ArrayList;
193import java.util.Arrays;
194import java.util.Collections;
195import java.util.Comparator;
196import java.util.HashMap;
197import java.util.HashSet;
198import java.util.Iterator;
199import java.util.List;
200import java.util.Locale;
201import java.util.Map;
202import java.util.Set;
203import java.util.concurrent.atomic.AtomicBoolean;
204import java.util.concurrent.atomic.AtomicLong;
205
206public final class ActivityManagerService extends ActivityManagerNative
207        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
208    private static final String USER_DATA_DIR = "/data/user/";
209    static final String TAG = "ActivityManager";
210    static final String TAG_MU = "ActivityManagerServiceMU";
211    static final boolean DEBUG = false;
212    static final boolean localLOGV = DEBUG;
213    static final boolean DEBUG_BACKUP = localLOGV || false;
214    static final boolean DEBUG_BROADCAST = localLOGV || false;
215    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
216    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_CLEANUP = localLOGV || false;
218    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
219    static final boolean DEBUG_FOCUS = false;
220    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
221    static final boolean DEBUG_MU = localLOGV || false;
222    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
223    static final boolean DEBUG_LRU = localLOGV || false;
224    static final boolean DEBUG_PAUSE = localLOGV || false;
225    static final boolean DEBUG_POWER = localLOGV || false;
226    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
227    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
228    static final boolean DEBUG_PROCESSES = localLOGV || false;
229    static final boolean DEBUG_PROVIDER = localLOGV || false;
230    static final boolean DEBUG_RESULTS = localLOGV || false;
231    static final boolean DEBUG_SERVICE = localLOGV || false;
232    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
233    static final boolean DEBUG_STACK = localLOGV || false;
234    static final boolean DEBUG_SWITCH = localLOGV || false;
235    static final boolean DEBUG_TASKS = localLOGV || false;
236    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
237    static final boolean DEBUG_TRANSITION = localLOGV || false;
238    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
239    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
240    static final boolean DEBUG_VISBILITY = localLOGV || false;
241    static final boolean DEBUG_PSS = localLOGV || false;
242    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
243    static final boolean VALIDATE_TOKENS = false;
244    static final boolean SHOW_ACTIVITY_START_TIME = true;
245
246    // Control over CPU and battery monitoring.
247    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
248    static final boolean MONITOR_CPU_USAGE = true;
249    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
250    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
251    static final boolean MONITOR_THREAD_CPU_USAGE = false;
252
253    // The flags that are set for all calls we make to the package manager.
254    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
255
256    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
257
258    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
259
260    // Maximum number of recent tasks that we can remember.
261    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
262
263    // Amount of time after a call to stopAppSwitches() during which we will
264    // prevent further untrusted switches from happening.
265    static final long APP_SWITCH_DELAY_TIME = 5*1000;
266
267    // How long we wait for a launched process to attach to the activity manager
268    // before we decide it's never going to come up for real.
269    static final int PROC_START_TIMEOUT = 10*1000;
270
271    // How long we wait for a launched process to attach to the activity manager
272    // before we decide it's never going to come up for real, when the process was
273    // started with a wrapper for instrumentation (such as Valgrind) because it
274    // could take much longer than usual.
275    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
276
277    // How long to wait after going idle before forcing apps to GC.
278    static final int GC_TIMEOUT = 5*1000;
279
280    // The minimum amount of time between successive GC requests for a process.
281    static final int GC_MIN_INTERVAL = 60*1000;
282
283    // The minimum amount of time between successive PSS requests for a process.
284    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
285
286    // The minimum amount of time between successive PSS requests for a process
287    // when the request is due to the memory state being lowered.
288    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
289
290    // The rate at which we check for apps using excessive power -- 15 mins.
291    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
292
293    // The minimum sample duration we will allow before deciding we have
294    // enough data on wake locks to start killing things.
295    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
296
297    // The minimum sample duration we will allow before deciding we have
298    // enough data on CPU usage to start killing things.
299    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
300
301    // How long we allow a receiver to run before giving up on it.
302    static final int BROADCAST_FG_TIMEOUT = 10*1000;
303    static final int BROADCAST_BG_TIMEOUT = 60*1000;
304
305    // How long we wait until we timeout on key dispatching.
306    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
307
308    // How long we wait until we timeout on key dispatching during instrumentation.
309    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
310
311    // Amount of time we wait for observers to handle a user switch before
312    // giving up on them and unfreezing the screen.
313    static final int USER_SWITCH_TIMEOUT = 2*1000;
314
315    // Maximum number of users we allow to be running at a time.
316    static final int MAX_RUNNING_USERS = 3;
317
318    // How long to wait in getAssistContextExtras for the activity and foreground services
319    // to respond with the result.
320    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
321
322    // Maximum number of persisted Uri grants a package is allowed
323    static final int MAX_PERSISTED_URI_GRANTS = 128;
324
325    static final int MY_PID = Process.myPid();
326
327    static final String[] EMPTY_STRING_ARRAY = new String[0];
328
329    // How many bytes to write into the dropbox log before truncating
330    static final int DROPBOX_MAX_SIZE = 256 * 1024;
331
332    /** Run all ActivityStacks through this */
333    ActivityStackSupervisor mStackSupervisor;
334
335    public IntentFirewall mIntentFirewall;
336
337    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
338    // default actuion automatically.  Important for devices without direct input
339    // devices.
340    private boolean mShowDialogs = true;
341
342    /**
343     * Description of a request to start a new activity, which has been held
344     * due to app switches being disabled.
345     */
346    static class PendingActivityLaunch {
347        final ActivityRecord r;
348        final ActivityRecord sourceRecord;
349        final int startFlags;
350        final ActivityStack stack;
351
352        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
353                int _startFlags, ActivityStack _stack) {
354            r = _r;
355            sourceRecord = _sourceRecord;
356            startFlags = _startFlags;
357            stack = _stack;
358        }
359    }
360
361    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
362            = new ArrayList<PendingActivityLaunch>();
363
364    BroadcastQueue mFgBroadcastQueue;
365    BroadcastQueue mBgBroadcastQueue;
366    // Convenient for easy iteration over the queues. Foreground is first
367    // so that dispatch of foreground broadcasts gets precedence.
368    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
369
370    BroadcastQueue broadcastQueueForIntent(Intent intent) {
371        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
372        if (DEBUG_BACKGROUND_BROADCAST) {
373            Slog.i(TAG, "Broadcast intent " + intent + " on "
374                    + (isFg ? "foreground" : "background")
375                    + " queue");
376        }
377        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
378    }
379
380    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
381        for (BroadcastQueue queue : mBroadcastQueues) {
382            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
383            if (r != null) {
384                return r;
385            }
386        }
387        return null;
388    }
389
390    /**
391     * Activity we have told the window manager to have key focus.
392     */
393    ActivityRecord mFocusedActivity = null;
394
395    /**
396     * List of intents that were used to start the most recent tasks.
397     */
398    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
399
400    public class PendingAssistExtras extends Binder implements Runnable {
401        public final ActivityRecord activity;
402        public boolean haveResult = false;
403        public Bundle result = null;
404        public PendingAssistExtras(ActivityRecord _activity) {
405            activity = _activity;
406        }
407        @Override
408        public void run() {
409            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
410            synchronized (this) {
411                haveResult = true;
412                notifyAll();
413            }
414        }
415    }
416
417    final ArrayList<PendingAssistExtras> mPendingAssistExtras
418            = new ArrayList<PendingAssistExtras>();
419
420    /**
421     * Process management.
422     */
423    final ProcessList mProcessList = new ProcessList();
424
425    /**
426     * All of the applications we currently have running organized by name.
427     * The keys are strings of the application package name (as
428     * returned by the package manager), and the keys are ApplicationRecord
429     * objects.
430     */
431    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
432
433    /**
434     * Tracking long-term execution of processes to look for abuse and other
435     * bad app behavior.
436     */
437    final ProcessStatsService mProcessStats;
438
439    /**
440     * The currently running isolated processes.
441     */
442    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
443
444    /**
445     * Counter for assigning isolated process uids, to avoid frequently reusing the
446     * same ones.
447     */
448    int mNextIsolatedProcessUid = 0;
449
450    /**
451     * The currently running heavy-weight process, if any.
452     */
453    ProcessRecord mHeavyWeightProcess = null;
454
455    /**
456     * The last time that various processes have crashed.
457     */
458    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
459
460    /**
461     * Information about a process that is currently marked as bad.
462     */
463    static final class BadProcessInfo {
464        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
465            this.time = time;
466            this.shortMsg = shortMsg;
467            this.longMsg = longMsg;
468            this.stack = stack;
469        }
470
471        final long time;
472        final String shortMsg;
473        final String longMsg;
474        final String stack;
475    }
476
477    /**
478     * Set of applications that we consider to be bad, and will reject
479     * incoming broadcasts from (which the user has no control over).
480     * Processes are added to this set when they have crashed twice within
481     * a minimum amount of time; they are removed from it when they are
482     * later restarted (hopefully due to some user action).  The value is the
483     * time it was added to the list.
484     */
485    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
486
487    /**
488     * All of the processes we currently have running organized by pid.
489     * The keys are the pid running the application.
490     *
491     * <p>NOTE: This object is protected by its own lock, NOT the global
492     * activity manager lock!
493     */
494    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
495
496    /**
497     * All of the processes that have been forced to be foreground.  The key
498     * is the pid of the caller who requested it (we hold a death
499     * link on it).
500     */
501    abstract class ForegroundToken implements IBinder.DeathRecipient {
502        int pid;
503        IBinder token;
504    }
505    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
506
507    /**
508     * List of records for processes that someone had tried to start before the
509     * system was ready.  We don't start them at that point, but ensure they
510     * are started by the time booting is complete.
511     */
512    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
513
514    /**
515     * List of persistent applications that are in the process
516     * of being started.
517     */
518    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
519
520    /**
521     * Processes that are being forcibly torn down.
522     */
523    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
524
525    /**
526     * List of running applications, sorted by recent usage.
527     * The first entry in the list is the least recently used.
528     */
529    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
530
531    /**
532     * Where in mLruProcesses that the processes hosting activities start.
533     */
534    int mLruProcessActivityStart = 0;
535
536    /**
537     * Where in mLruProcesses that the processes hosting services start.
538     * This is after (lower index) than mLruProcessesActivityStart.
539     */
540    int mLruProcessServiceStart = 0;
541
542    /**
543     * List of processes that should gc as soon as things are idle.
544     */
545    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
546
547    /**
548     * Processes we want to collect PSS data from.
549     */
550    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
551
552    /**
553     * Last time we requested PSS data of all processes.
554     */
555    long mLastFullPssTime = SystemClock.uptimeMillis();
556
557    /**
558     * This is the process holding what we currently consider to be
559     * the "home" activity.
560     */
561    ProcessRecord mHomeProcess;
562
563    /**
564     * This is the process holding the activity the user last visited that
565     * is in a different process from the one they are currently in.
566     */
567    ProcessRecord mPreviousProcess;
568
569    /**
570     * The time at which the previous process was last visible.
571     */
572    long mPreviousProcessVisibleTime;
573
574    /**
575     * Which uses have been started, so are allowed to run code.
576     */
577    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
578
579    /**
580     * LRU list of history of current users.  Most recently current is at the end.
581     */
582    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
583
584    /**
585     * Constant array of the users that are currently started.
586     */
587    int[] mStartedUserArray = new int[] { 0 };
588
589    /**
590     * Registered observers of the user switching mechanics.
591     */
592    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
593            = new RemoteCallbackList<IUserSwitchObserver>();
594
595    /**
596     * Currently active user switch.
597     */
598    Object mCurUserSwitchCallback;
599
600    /**
601     * Packages that the user has asked to have run in screen size
602     * compatibility mode instead of filling the screen.
603     */
604    final CompatModePackages mCompatModePackages;
605
606    /**
607     * Set of IntentSenderRecord objects that are currently active.
608     */
609    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
610            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
611
612    /**
613     * Fingerprints (hashCode()) of stack traces that we've
614     * already logged DropBox entries for.  Guarded by itself.  If
615     * something (rogue user app) forces this over
616     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
617     */
618    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
619    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
620
621    /**
622     * Strict Mode background batched logging state.
623     *
624     * The string buffer is guarded by itself, and its lock is also
625     * used to determine if another batched write is already
626     * in-flight.
627     */
628    private final StringBuilder mStrictModeBuffer = new StringBuilder();
629
630    /**
631     * Keeps track of all IIntentReceivers that have been registered for
632     * broadcasts.  Hash keys are the receiver IBinder, hash value is
633     * a ReceiverList.
634     */
635    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
636            new HashMap<IBinder, ReceiverList>();
637
638    /**
639     * Resolver for broadcast intents to registered receivers.
640     * Holds BroadcastFilter (subclass of IntentFilter).
641     */
642    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
643            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
644        @Override
645        protected boolean allowFilterResult(
646                BroadcastFilter filter, List<BroadcastFilter> dest) {
647            IBinder target = filter.receiverList.receiver.asBinder();
648            for (int i=dest.size()-1; i>=0; i--) {
649                if (dest.get(i).receiverList.receiver.asBinder() == target) {
650                    return false;
651                }
652            }
653            return true;
654        }
655
656        @Override
657        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
658            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
659                    || userId == filter.owningUserId) {
660                return super.newResult(filter, match, userId);
661            }
662            return null;
663        }
664
665        @Override
666        protected BroadcastFilter[] newArray(int size) {
667            return new BroadcastFilter[size];
668        }
669
670        @Override
671        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
672            return packageName.equals(filter.packageName);
673        }
674    };
675
676    /**
677     * State of all active sticky broadcasts per user.  Keys are the action of the
678     * sticky Intent, values are an ArrayList of all broadcasted intents with
679     * that action (which should usually be one).  The SparseArray is keyed
680     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
681     * for stickies that are sent to all users.
682     */
683    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
684            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
685
686    final ActiveServices mServices;
687
688    /**
689     * Backup/restore process management
690     */
691    String mBackupAppName = null;
692    BackupRecord mBackupTarget = null;
693
694    /**
695     * List of PendingThumbnailsRecord objects of clients who are still
696     * waiting to receive all of the thumbnails for a task.
697     */
698    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
699            new ArrayList<PendingThumbnailsRecord>();
700
701    final ProviderMap mProviderMap;
702
703    /**
704     * List of content providers who have clients waiting for them.  The
705     * application is currently being launched and the provider will be
706     * removed from this list once it is published.
707     */
708    final ArrayList<ContentProviderRecord> mLaunchingProviders
709            = new ArrayList<ContentProviderRecord>();
710
711    /**
712     * File storing persisted {@link #mGrantedUriPermissions}.
713     */
714    private final AtomicFile mGrantFile;
715
716    /** XML constants used in {@link #mGrantFile} */
717    private static final String TAG_URI_GRANTS = "uri-grants";
718    private static final String TAG_URI_GRANT = "uri-grant";
719    private static final String ATTR_USER_HANDLE = "userHandle";
720    private static final String ATTR_SOURCE_PKG = "sourcePkg";
721    private static final String ATTR_TARGET_PKG = "targetPkg";
722    private static final String ATTR_URI = "uri";
723    private static final String ATTR_MODE_FLAGS = "modeFlags";
724    private static final String ATTR_CREATED_TIME = "createdTime";
725
726    /**
727     * Global set of specific {@link Uri} permissions that have been granted.
728     * This optimized lookup structure maps from {@link UriPermission#targetUid}
729     * to {@link UriPermission#uri} to {@link UriPermission}.
730     */
731    @GuardedBy("this")
732    private final SparseArray<ArrayMap<Uri, UriPermission>>
733            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
734
735    CoreSettingsObserver mCoreSettingsObserver;
736
737    /**
738     * Thread-local storage used to carry caller permissions over through
739     * indirect content-provider access.
740     */
741    private class Identity {
742        public int pid;
743        public int uid;
744
745        Identity(int _pid, int _uid) {
746            pid = _pid;
747            uid = _uid;
748        }
749    }
750
751    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
752
753    /**
754     * All information we have collected about the runtime performance of
755     * any user id that can impact battery performance.
756     */
757    final BatteryStatsService mBatteryStatsService;
758
759    /**
760     * Information about component usage
761     */
762    final UsageStatsService mUsageStatsService;
763
764    /**
765     * Information about and control over application operations
766     */
767    final AppOpsService mAppOpsService;
768
769    /**
770     * Current configuration information.  HistoryRecord objects are given
771     * a reference to this object to indicate which configuration they are
772     * currently running in, so this object must be kept immutable.
773     */
774    Configuration mConfiguration = new Configuration();
775
776    /**
777     * Current sequencing integer of the configuration, for skipping old
778     * configurations.
779     */
780    int mConfigurationSeq = 0;
781
782    /**
783     * Hardware-reported OpenGLES version.
784     */
785    final int GL_ES_VERSION;
786
787    /**
788     * List of initialization arguments to pass to all processes when binding applications to them.
789     * For example, references to the commonly used services.
790     */
791    HashMap<String, IBinder> mAppBindArgs;
792
793    /**
794     * Temporary to avoid allocations.  Protected by main lock.
795     */
796    final StringBuilder mStringBuilder = new StringBuilder(256);
797
798    /**
799     * Used to control how we initialize the service.
800     */
801    boolean mStartRunning = false;
802    ComponentName mTopComponent;
803    String mTopAction;
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        startRunning(null, null, null, null);
1989    }
1990
1991    @Override
1992    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1993            throws RemoteException {
1994        if (code == SYSPROPS_TRANSACTION) {
1995            // We need to tell all apps about the system property change.
1996            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1997            synchronized(this) {
1998                final int NP = mProcessNames.getMap().size();
1999                for (int ip=0; ip<NP; ip++) {
2000                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2001                    final int NA = apps.size();
2002                    for (int ia=0; ia<NA; ia++) {
2003                        ProcessRecord app = apps.valueAt(ia);
2004                        if (app.thread != null) {
2005                            procs.add(app.thread.asBinder());
2006                        }
2007                    }
2008                }
2009            }
2010
2011            int N = procs.size();
2012            for (int i=0; i<N; i++) {
2013                Parcel data2 = Parcel.obtain();
2014                try {
2015                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2016                } catch (RemoteException e) {
2017                }
2018                data2.recycle();
2019            }
2020        }
2021        try {
2022            return super.onTransact(code, data, reply, flags);
2023        } catch (RuntimeException e) {
2024            // The activity manager only throws security exceptions, so let's
2025            // log all others.
2026            if (!(e instanceof SecurityException)) {
2027                Slog.wtf(TAG, "Activity Manager Crash", e);
2028            }
2029            throw e;
2030        }
2031    }
2032
2033    void updateCpuStats() {
2034        final long now = SystemClock.uptimeMillis();
2035        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2036            return;
2037        }
2038        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2039            synchronized (mProcessCpuThread) {
2040                mProcessCpuThread.notify();
2041            }
2042        }
2043    }
2044
2045    void updateCpuStatsNow() {
2046        synchronized (mProcessCpuThread) {
2047            mProcessCpuMutexFree.set(false);
2048            final long now = SystemClock.uptimeMillis();
2049            boolean haveNewCpuStats = false;
2050
2051            if (MONITOR_CPU_USAGE &&
2052                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2053                mLastCpuTime.set(now);
2054                haveNewCpuStats = true;
2055                mProcessCpuTracker.update();
2056                //Slog.i(TAG, mProcessCpu.printCurrentState());
2057                //Slog.i(TAG, "Total CPU usage: "
2058                //        + mProcessCpu.getTotalCpuPercent() + "%");
2059
2060                // Slog the cpu usage if the property is set.
2061                if ("true".equals(SystemProperties.get("events.cpu"))) {
2062                    int user = mProcessCpuTracker.getLastUserTime();
2063                    int system = mProcessCpuTracker.getLastSystemTime();
2064                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2065                    int irq = mProcessCpuTracker.getLastIrqTime();
2066                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2067                    int idle = mProcessCpuTracker.getLastIdleTime();
2068
2069                    int total = user + system + iowait + irq + softIrq + idle;
2070                    if (total == 0) total = 1;
2071
2072                    EventLog.writeEvent(EventLogTags.CPU,
2073                            ((user+system+iowait+irq+softIrq) * 100) / total,
2074                            (user * 100) / total,
2075                            (system * 100) / total,
2076                            (iowait * 100) / total,
2077                            (irq * 100) / total,
2078                            (softIrq * 100) / total);
2079                }
2080            }
2081
2082            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2083            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2084            synchronized(bstats) {
2085                synchronized(mPidsSelfLocked) {
2086                    if (haveNewCpuStats) {
2087                        if (mOnBattery) {
2088                            int perc = bstats.startAddingCpuLocked();
2089                            int totalUTime = 0;
2090                            int totalSTime = 0;
2091                            final int N = mProcessCpuTracker.countStats();
2092                            for (int i=0; i<N; i++) {
2093                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2094                                if (!st.working) {
2095                                    continue;
2096                                }
2097                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2098                                int otherUTime = (st.rel_utime*perc)/100;
2099                                int otherSTime = (st.rel_stime*perc)/100;
2100                                totalUTime += otherUTime;
2101                                totalSTime += otherSTime;
2102                                if (pr != null) {
2103                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
2104                                            st.name, st.pid);
2105                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2106                                            st.rel_stime-otherSTime);
2107                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2108                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2109                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
2110                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2111                                    if (ps == null) {
2112                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
2113                                                "(Unknown)");
2114                                    }
2115                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2116                                            st.rel_stime-otherSTime);
2117                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2118                                } else {
2119                                    BatteryStatsImpl.Uid.Proc ps =
2120                                            bstats.getProcessStatsLocked(st.name, st.pid);
2121                                    if (ps != null) {
2122                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2123                                                st.rel_stime-otherSTime);
2124                                        ps.addSpeedStepTimes(cpuSpeedTimes);
2125                                    }
2126                                }
2127                            }
2128                            bstats.finishAddingCpuLocked(perc, totalUTime,
2129                                    totalSTime, cpuSpeedTimes);
2130                        }
2131                    }
2132                }
2133
2134                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2135                    mLastWriteTime = now;
2136                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2137                }
2138            }
2139        }
2140    }
2141
2142    @Override
2143    public void batteryNeedsCpuUpdate() {
2144        updateCpuStatsNow();
2145    }
2146
2147    @Override
2148    public void batteryPowerChanged(boolean onBattery) {
2149        // When plugging in, update the CPU stats first before changing
2150        // the plug state.
2151        updateCpuStatsNow();
2152        synchronized (this) {
2153            synchronized(mPidsSelfLocked) {
2154                mOnBattery = DEBUG_POWER ? true : onBattery;
2155            }
2156        }
2157    }
2158
2159    /**
2160     * Initialize the application bind args. These are passed to each
2161     * process when the bindApplication() IPC is sent to the process. They're
2162     * lazily setup to make sure the services are running when they're asked for.
2163     */
2164    private HashMap<String, IBinder> getCommonServicesLocked() {
2165        if (mAppBindArgs == null) {
2166            mAppBindArgs = new HashMap<String, IBinder>();
2167
2168            // Setup the application init args
2169            mAppBindArgs.put("package", ServiceManager.getService("package"));
2170            mAppBindArgs.put("window", ServiceManager.getService("window"));
2171            mAppBindArgs.put(Context.ALARM_SERVICE,
2172                    ServiceManager.getService(Context.ALARM_SERVICE));
2173        }
2174        return mAppBindArgs;
2175    }
2176
2177    final void setFocusedActivityLocked(ActivityRecord r) {
2178        if (mFocusedActivity != r) {
2179            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2180            mFocusedActivity = r;
2181            mStackSupervisor.setFocusedStack(r);
2182            if (r != null) {
2183                mWindowManager.setFocusedApp(r.appToken, true);
2184            }
2185            applyUpdateLockStateLocked(r);
2186        }
2187    }
2188
2189    @Override
2190    public void setFocusedStack(int stackId) {
2191        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2192        synchronized (ActivityManagerService.this) {
2193            ActivityStack stack = mStackSupervisor.getStack(stackId);
2194            if (stack != null) {
2195                ActivityRecord r = stack.topRunningActivityLocked(null);
2196                if (r != null) {
2197                    setFocusedActivityLocked(r);
2198                }
2199            }
2200        }
2201    }
2202
2203    @Override
2204    public void notifyActivityDrawn(IBinder token) {
2205        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2206        synchronized (this) {
2207            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2208            if (r != null) {
2209                r.task.stack.notifyActivityDrawnLocked(r);
2210            }
2211        }
2212    }
2213
2214    final void applyUpdateLockStateLocked(ActivityRecord r) {
2215        // Modifications to the UpdateLock state are done on our handler, outside
2216        // the activity manager's locks.  The new state is determined based on the
2217        // state *now* of the relevant activity record.  The object is passed to
2218        // the handler solely for logging detail, not to be consulted/modified.
2219        final boolean nextState = r != null && r.immersive;
2220        mHandler.sendMessage(
2221                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2222    }
2223
2224    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2225        Message msg = Message.obtain();
2226        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2227        msg.obj = r.task.askedCompatMode ? null : r;
2228        mHandler.sendMessage(msg);
2229    }
2230
2231    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2232            String what, Object obj, ProcessRecord srcApp) {
2233        app.lastActivityTime = now;
2234
2235        if (app.activities.size() > 0) {
2236            // Don't want to touch dependent processes that are hosting activities.
2237            return index;
2238        }
2239
2240        int lrui = mLruProcesses.lastIndexOf(app);
2241        if (lrui < 0) {
2242            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2243                    + what + " " + obj + " from " + srcApp);
2244            return index;
2245        }
2246
2247        if (lrui >= index) {
2248            // Don't want to cause this to move dependent processes *back* in the
2249            // list as if they were less frequently used.
2250            return index;
2251        }
2252
2253        if (lrui >= mLruProcessActivityStart) {
2254            // Don't want to touch dependent processes that are hosting activities.
2255            return index;
2256        }
2257
2258        mLruProcesses.remove(lrui);
2259        if (index > 0) {
2260            index--;
2261        }
2262        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2263                + " in LRU list: " + app);
2264        mLruProcesses.add(index, app);
2265        return index;
2266    }
2267
2268    final void removeLruProcessLocked(ProcessRecord app) {
2269        int lrui = mLruProcesses.lastIndexOf(app);
2270        if (lrui >= 0) {
2271            if (lrui <= mLruProcessActivityStart) {
2272                mLruProcessActivityStart--;
2273            }
2274            if (lrui <= mLruProcessServiceStart) {
2275                mLruProcessServiceStart--;
2276            }
2277            mLruProcesses.remove(lrui);
2278        }
2279    }
2280
2281    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2282            ProcessRecord client) {
2283        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2284        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2285        if (!activityChange && hasActivity) {
2286            // The process has activties, so we are only going to allow activity-based
2287            // adjustments move it.  It should be kept in the front of the list with other
2288            // processes that have activities, and we don't want those to change their
2289            // order except due to activity operations.
2290            return;
2291        }
2292
2293        mLruSeq++;
2294        final long now = SystemClock.uptimeMillis();
2295        app.lastActivityTime = now;
2296
2297        // First a quick reject: if the app is already at the position we will
2298        // put it, then there is nothing to do.
2299        if (hasActivity) {
2300            final int N = mLruProcesses.size();
2301            if (N > 0 && mLruProcesses.get(N-1) == app) {
2302                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2303                return;
2304            }
2305        } else {
2306            if (mLruProcessServiceStart > 0
2307                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2308                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2309                return;
2310            }
2311        }
2312
2313        int lrui = mLruProcesses.lastIndexOf(app);
2314
2315        if (app.persistent && lrui >= 0) {
2316            // We don't care about the position of persistent processes, as long as
2317            // they are in the list.
2318            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2319            return;
2320        }
2321
2322        /* In progress: compute new position first, so we can avoid doing work
2323           if the process is not actually going to move.  Not yet working.
2324        int addIndex;
2325        int nextIndex;
2326        boolean inActivity = false, inService = false;
2327        if (hasActivity) {
2328            // Process has activities, put it at the very tipsy-top.
2329            addIndex = mLruProcesses.size();
2330            nextIndex = mLruProcessServiceStart;
2331            inActivity = true;
2332        } else if (hasService) {
2333            // Process has services, put it at the top of the service list.
2334            addIndex = mLruProcessActivityStart;
2335            nextIndex = mLruProcessServiceStart;
2336            inActivity = true;
2337            inService = true;
2338        } else  {
2339            // Process not otherwise of interest, it goes to the top of the non-service area.
2340            addIndex = mLruProcessServiceStart;
2341            if (client != null) {
2342                int clientIndex = mLruProcesses.lastIndexOf(client);
2343                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2344                        + app);
2345                if (clientIndex >= 0 && addIndex > clientIndex) {
2346                    addIndex = clientIndex;
2347                }
2348            }
2349            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2350        }
2351
2352        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2353                + mLruProcessActivityStart + "): " + app);
2354        */
2355
2356        if (lrui >= 0) {
2357            if (lrui < mLruProcessActivityStart) {
2358                mLruProcessActivityStart--;
2359            }
2360            if (lrui < mLruProcessServiceStart) {
2361                mLruProcessServiceStart--;
2362            }
2363            /*
2364            if (addIndex > lrui) {
2365                addIndex--;
2366            }
2367            if (nextIndex > lrui) {
2368                nextIndex--;
2369            }
2370            */
2371            mLruProcesses.remove(lrui);
2372        }
2373
2374        /*
2375        mLruProcesses.add(addIndex, app);
2376        if (inActivity) {
2377            mLruProcessActivityStart++;
2378        }
2379        if (inService) {
2380            mLruProcessActivityStart++;
2381        }
2382        */
2383
2384        int nextIndex;
2385        if (hasActivity) {
2386            final int N = mLruProcesses.size();
2387            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2388                // Process doesn't have activities, but has clients with
2389                // activities...  move it up, but one below the top (the top
2390                // should always have a real activity).
2391                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2392                mLruProcesses.add(N-1, app);
2393                // To keep it from spamming the LRU list (by making a bunch of clients),
2394                // we will push down any other entries owned by the app.
2395                final int uid = app.info.uid;
2396                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2397                    ProcessRecord subProc = mLruProcesses.get(i);
2398                    if (subProc.info.uid == uid) {
2399                        // We want to push this one down the list.  If the process after
2400                        // it is for the same uid, however, don't do so, because we don't
2401                        // want them internally to be re-ordered.
2402                        if (mLruProcesses.get(i-1).info.uid != uid) {
2403                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2404                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2405                            ProcessRecord tmp = mLruProcesses.get(i);
2406                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2407                            mLruProcesses.set(i-1, tmp);
2408                            i--;
2409                        }
2410                    } else {
2411                        // A gap, we can stop here.
2412                        break;
2413                    }
2414                }
2415            } else {
2416                // Process has activities, put it at the very tipsy-top.
2417                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2418                mLruProcesses.add(app);
2419            }
2420            nextIndex = mLruProcessServiceStart;
2421        } else if (hasService) {
2422            // Process has services, put it at the top of the service list.
2423            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2424            mLruProcesses.add(mLruProcessActivityStart, app);
2425            nextIndex = mLruProcessServiceStart;
2426            mLruProcessActivityStart++;
2427        } else  {
2428            // Process not otherwise of interest, it goes to the top of the non-service area.
2429            int index = mLruProcessServiceStart;
2430            if (client != null) {
2431                // If there is a client, don't allow the process to be moved up higher
2432                // in the list than that client.
2433                int clientIndex = mLruProcesses.lastIndexOf(client);
2434                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2435                        + " when updating " + app);
2436                if (clientIndex <= lrui) {
2437                    // Don't allow the client index restriction to push it down farther in the
2438                    // list than it already is.
2439                    clientIndex = lrui;
2440                }
2441                if (clientIndex >= 0 && index > clientIndex) {
2442                    index = clientIndex;
2443                }
2444            }
2445            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2446            mLruProcesses.add(index, app);
2447            nextIndex = index-1;
2448            mLruProcessActivityStart++;
2449            mLruProcessServiceStart++;
2450        }
2451
2452        // If the app is currently using a content provider or service,
2453        // bump those processes as well.
2454        for (int j=app.connections.size()-1; j>=0; j--) {
2455            ConnectionRecord cr = app.connections.valueAt(j);
2456            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2457                    && cr.binding.service.app != null
2458                    && cr.binding.service.app.lruSeq != mLruSeq
2459                    && !cr.binding.service.app.persistent) {
2460                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2461                        "service connection", cr, app);
2462            }
2463        }
2464        for (int j=app.conProviders.size()-1; j>=0; j--) {
2465            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2466            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2467                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2468                        "provider reference", cpr, app);
2469            }
2470        }
2471    }
2472
2473    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2474        if (uid == Process.SYSTEM_UID) {
2475            // The system gets to run in any process.  If there are multiple
2476            // processes with the same uid, just pick the first (this
2477            // should never happen).
2478            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2479            if (procs == null) return null;
2480            final int N = procs.size();
2481            for (int i = 0; i < N; i++) {
2482                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2483            }
2484        }
2485        ProcessRecord proc = mProcessNames.get(processName, uid);
2486        if (false && proc != null && !keepIfLarge
2487                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2488                && proc.lastCachedPss >= 4000) {
2489            // Turn this condition on to cause killing to happen regularly, for testing.
2490            if (proc.baseProcessTracker != null) {
2491                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2492            }
2493            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2494                    + "k from cached");
2495        } else if (proc != null && !keepIfLarge
2496                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2497                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2498            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2499            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2500                if (proc.baseProcessTracker != null) {
2501                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2502                }
2503                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2504                        + "k from cached");
2505            }
2506        }
2507        return proc;
2508    }
2509
2510    void ensurePackageDexOpt(String packageName) {
2511        IPackageManager pm = AppGlobals.getPackageManager();
2512        try {
2513            if (pm.performDexOpt(packageName)) {
2514                mDidDexOpt = true;
2515            }
2516        } catch (RemoteException e) {
2517        }
2518    }
2519
2520    boolean isNextTransitionForward() {
2521        int transit = mWindowManager.getPendingAppTransition();
2522        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2523                || transit == AppTransition.TRANSIT_TASK_OPEN
2524                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2525    }
2526
2527    final ProcessRecord startProcessLocked(String processName,
2528            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2529            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2530            boolean isolated, boolean keepIfLarge) {
2531        ProcessRecord app;
2532        if (!isolated) {
2533            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2534        } else {
2535            // If this is an isolated process, it can't re-use an existing process.
2536            app = null;
2537        }
2538        // We don't have to do anything more if:
2539        // (1) There is an existing application record; and
2540        // (2) The caller doesn't think it is dead, OR there is no thread
2541        //     object attached to it so we know it couldn't have crashed; and
2542        // (3) There is a pid assigned to it, so it is either starting or
2543        //     already running.
2544        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2545                + " app=" + app + " knownToBeDead=" + knownToBeDead
2546                + " thread=" + (app != null ? app.thread : null)
2547                + " pid=" + (app != null ? app.pid : -1));
2548        if (app != null && app.pid > 0) {
2549            if (!knownToBeDead || app.thread == null) {
2550                // We already have the app running, or are waiting for it to
2551                // come up (we have a pid but not yet its thread), so keep it.
2552                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2553                // If this is a new package in the process, add the package to the list
2554                app.addPackage(info.packageName, mProcessStats);
2555                return app;
2556            }
2557
2558            // An application record is attached to a previous process,
2559            // clean it up now.
2560            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2561            handleAppDiedLocked(app, true, true);
2562        }
2563
2564        String hostingNameStr = hostingName != null
2565                ? hostingName.flattenToShortString() : null;
2566
2567        if (!isolated) {
2568            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2569                // If we are in the background, then check to see if this process
2570                // is bad.  If so, we will just silently fail.
2571                if (mBadProcesses.get(info.processName, info.uid) != null) {
2572                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2573                            + "/" + info.processName);
2574                    return null;
2575                }
2576            } else {
2577                // When the user is explicitly starting a process, then clear its
2578                // crash count so that we won't make it bad until they see at
2579                // least one crash dialog again, and make the process good again
2580                // if it had been bad.
2581                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2582                        + "/" + info.processName);
2583                mProcessCrashTimes.remove(info.processName, info.uid);
2584                if (mBadProcesses.get(info.processName, info.uid) != null) {
2585                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2586                            UserHandle.getUserId(info.uid), info.uid,
2587                            info.processName);
2588                    mBadProcesses.remove(info.processName, info.uid);
2589                    if (app != null) {
2590                        app.bad = false;
2591                    }
2592                }
2593            }
2594        }
2595
2596        if (app == null) {
2597            app = newProcessRecordLocked(info, processName, isolated);
2598            if (app == null) {
2599                Slog.w(TAG, "Failed making new process record for "
2600                        + processName + "/" + info.uid + " isolated=" + isolated);
2601                return null;
2602            }
2603            mProcessNames.put(processName, app.uid, app);
2604            if (isolated) {
2605                mIsolatedProcesses.put(app.uid, app);
2606            }
2607        } else {
2608            // If this is a new package in the process, add the package to the list
2609            app.addPackage(info.packageName, mProcessStats);
2610        }
2611
2612        // If the system is not ready yet, then hold off on starting this
2613        // process until it is.
2614        if (!mProcessesReady
2615                && !isAllowedWhileBooting(info)
2616                && !allowWhileBooting) {
2617            if (!mProcessesOnHold.contains(app)) {
2618                mProcessesOnHold.add(app);
2619            }
2620            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2621            return app;
2622        }
2623
2624        startProcessLocked(app, hostingType, hostingNameStr);
2625        return (app.pid != 0) ? app : null;
2626    }
2627
2628    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2629        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2630    }
2631
2632    private final void startProcessLocked(ProcessRecord app,
2633            String hostingType, String hostingNameStr) {
2634        if (app.pid > 0 && app.pid != MY_PID) {
2635            synchronized (mPidsSelfLocked) {
2636                mPidsSelfLocked.remove(app.pid);
2637                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2638            }
2639            app.setPid(0);
2640        }
2641
2642        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2643                "startProcessLocked removing on hold: " + app);
2644        mProcessesOnHold.remove(app);
2645
2646        updateCpuStats();
2647
2648        try {
2649            int uid = app.uid;
2650
2651            int[] gids = null;
2652            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2653            if (!app.isolated) {
2654                int[] permGids = null;
2655                try {
2656                    final PackageManager pm = mContext.getPackageManager();
2657                    permGids = pm.getPackageGids(app.info.packageName);
2658
2659                    if (Environment.isExternalStorageEmulated()) {
2660                        if (pm.checkPermission(
2661                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2662                                app.info.packageName) == PERMISSION_GRANTED) {
2663                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2664                        } else {
2665                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2666                        }
2667                    }
2668                } catch (PackageManager.NameNotFoundException e) {
2669                    Slog.w(TAG, "Unable to retrieve gids", e);
2670                }
2671
2672                /*
2673                 * Add shared application GID so applications can share some
2674                 * resources like shared libraries
2675                 */
2676                if (permGids == null) {
2677                    gids = new int[1];
2678                } else {
2679                    gids = new int[permGids.length + 1];
2680                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2681                }
2682                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2683            }
2684            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2685                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2686                        && mTopComponent != null
2687                        && app.processName.equals(mTopComponent.getPackageName())) {
2688                    uid = 0;
2689                }
2690                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2691                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2692                    uid = 0;
2693                }
2694            }
2695            int debugFlags = 0;
2696            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2697                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2698                // Also turn on CheckJNI for debuggable apps. It's quite
2699                // awkward to turn on otherwise.
2700                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2701            }
2702            // Run the app in safe mode if its manifest requests so or the
2703            // system is booted in safe mode.
2704            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2705                Zygote.systemInSafeMode == true) {
2706                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2707            }
2708            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2709                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2710            }
2711            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2712                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2713            }
2714            if ("1".equals(SystemProperties.get("debug.assert"))) {
2715                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2716            }
2717
2718            // Start the process.  It will either succeed and return a result containing
2719            // the PID of the new process, or else throw a RuntimeException.
2720            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2721                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2722                    app.info.targetSdkVersion, app.info.seinfo, null);
2723
2724            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2725            synchronized (bs) {
2726                if (bs.isOnBattery()) {
2727                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2728                }
2729            }
2730
2731            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2732                    UserHandle.getUserId(uid), startResult.pid, uid,
2733                    app.processName, hostingType,
2734                    hostingNameStr != null ? hostingNameStr : "");
2735
2736            if (app.persistent) {
2737                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2738            }
2739
2740            StringBuilder buf = mStringBuilder;
2741            buf.setLength(0);
2742            buf.append("Start proc ");
2743            buf.append(app.processName);
2744            buf.append(" for ");
2745            buf.append(hostingType);
2746            if (hostingNameStr != null) {
2747                buf.append(" ");
2748                buf.append(hostingNameStr);
2749            }
2750            buf.append(": pid=");
2751            buf.append(startResult.pid);
2752            buf.append(" uid=");
2753            buf.append(uid);
2754            buf.append(" gids={");
2755            if (gids != null) {
2756                for (int gi=0; gi<gids.length; gi++) {
2757                    if (gi != 0) buf.append(", ");
2758                    buf.append(gids[gi]);
2759
2760                }
2761            }
2762            buf.append("}");
2763            Slog.i(TAG, buf.toString());
2764            app.setPid(startResult.pid);
2765            app.usingWrapper = startResult.usingWrapper;
2766            app.removed = false;
2767            synchronized (mPidsSelfLocked) {
2768                this.mPidsSelfLocked.put(startResult.pid, app);
2769                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2770                msg.obj = app;
2771                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2772                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2773            }
2774        } catch (RuntimeException e) {
2775            // XXX do better error recovery.
2776            app.setPid(0);
2777            Slog.e(TAG, "Failure starting process " + app.processName, e);
2778        }
2779    }
2780
2781    void updateUsageStats(ActivityRecord component, boolean resumed) {
2782        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2783        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2784        if (resumed) {
2785            mUsageStatsService.noteResumeComponent(component.realActivity);
2786            synchronized (stats) {
2787                stats.noteActivityResumedLocked(component.app.uid);
2788            }
2789        } else {
2790            mUsageStatsService.notePauseComponent(component.realActivity);
2791            synchronized (stats) {
2792                stats.noteActivityPausedLocked(component.app.uid);
2793            }
2794        }
2795    }
2796
2797    Intent getHomeIntent() {
2798        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2799        intent.setComponent(mTopComponent);
2800        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2801            intent.addCategory(Intent.CATEGORY_HOME);
2802        }
2803        return intent;
2804    }
2805
2806    boolean startHomeActivityLocked(int userId) {
2807        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2808                && mTopAction == null) {
2809            // We are running in factory test mode, but unable to find
2810            // the factory test app, so just sit around displaying the
2811            // error message and don't try to start anything.
2812            return false;
2813        }
2814        Intent intent = getHomeIntent();
2815        ActivityInfo aInfo =
2816            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2817        if (aInfo != null) {
2818            intent.setComponent(new ComponentName(
2819                    aInfo.applicationInfo.packageName, aInfo.name));
2820            // Don't do this if the home app is currently being
2821            // instrumented.
2822            aInfo = new ActivityInfo(aInfo);
2823            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2824            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2825                    aInfo.applicationInfo.uid, true);
2826            if (app == null || app.instrumentationClass == null) {
2827                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2828                mStackSupervisor.startHomeActivity(intent, aInfo);
2829            }
2830        }
2831
2832        return true;
2833    }
2834
2835    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2836        ActivityInfo ai = null;
2837        ComponentName comp = intent.getComponent();
2838        try {
2839            if (comp != null) {
2840                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2841            } else {
2842                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2843                        intent,
2844                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2845                            flags, userId);
2846
2847                if (info != null) {
2848                    ai = info.activityInfo;
2849                }
2850            }
2851        } catch (RemoteException e) {
2852            // ignore
2853        }
2854
2855        return ai;
2856    }
2857
2858    /**
2859     * Starts the "new version setup screen" if appropriate.
2860     */
2861    void startSetupActivityLocked() {
2862        // Only do this once per boot.
2863        if (mCheckedForSetup) {
2864            return;
2865        }
2866
2867        // We will show this screen if the current one is a different
2868        // version than the last one shown, and we are not running in
2869        // low-level factory test mode.
2870        final ContentResolver resolver = mContext.getContentResolver();
2871        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2872                Settings.Global.getInt(resolver,
2873                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2874            mCheckedForSetup = true;
2875
2876            // See if we should be showing the platform update setup UI.
2877            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2878            List<ResolveInfo> ris = mContext.getPackageManager()
2879                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2880
2881            // We don't allow third party apps to replace this.
2882            ResolveInfo ri = null;
2883            for (int i=0; ris != null && i<ris.size(); i++) {
2884                if ((ris.get(i).activityInfo.applicationInfo.flags
2885                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2886                    ri = ris.get(i);
2887                    break;
2888                }
2889            }
2890
2891            if (ri != null) {
2892                String vers = ri.activityInfo.metaData != null
2893                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2894                        : null;
2895                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2896                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2897                            Intent.METADATA_SETUP_VERSION);
2898                }
2899                String lastVers = Settings.Secure.getString(
2900                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2901                if (vers != null && !vers.equals(lastVers)) {
2902                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2903                    intent.setComponent(new ComponentName(
2904                            ri.activityInfo.packageName, ri.activityInfo.name));
2905                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2906                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2907                }
2908            }
2909        }
2910    }
2911
2912    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2913        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2914    }
2915
2916    void enforceNotIsolatedCaller(String caller) {
2917        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2918            throw new SecurityException("Isolated process not allowed to call " + caller);
2919        }
2920    }
2921
2922    @Override
2923    public int getFrontActivityScreenCompatMode() {
2924        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2925        synchronized (this) {
2926            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2927        }
2928    }
2929
2930    @Override
2931    public void setFrontActivityScreenCompatMode(int mode) {
2932        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2933                "setFrontActivityScreenCompatMode");
2934        synchronized (this) {
2935            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2936        }
2937    }
2938
2939    @Override
2940    public int getPackageScreenCompatMode(String packageName) {
2941        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2942        synchronized (this) {
2943            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2944        }
2945    }
2946
2947    @Override
2948    public void setPackageScreenCompatMode(String packageName, int mode) {
2949        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2950                "setPackageScreenCompatMode");
2951        synchronized (this) {
2952            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2953        }
2954    }
2955
2956    @Override
2957    public boolean getPackageAskScreenCompat(String packageName) {
2958        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2959        synchronized (this) {
2960            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2961        }
2962    }
2963
2964    @Override
2965    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2966        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2967                "setPackageAskScreenCompat");
2968        synchronized (this) {
2969            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2970        }
2971    }
2972
2973    private void dispatchProcessesChanged() {
2974        int N;
2975        synchronized (this) {
2976            N = mPendingProcessChanges.size();
2977            if (mActiveProcessChanges.length < N) {
2978                mActiveProcessChanges = new ProcessChangeItem[N];
2979            }
2980            mPendingProcessChanges.toArray(mActiveProcessChanges);
2981            mAvailProcessChanges.addAll(mPendingProcessChanges);
2982            mPendingProcessChanges.clear();
2983            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2984        }
2985
2986        int i = mProcessObservers.beginBroadcast();
2987        while (i > 0) {
2988            i--;
2989            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2990            if (observer != null) {
2991                try {
2992                    for (int j=0; j<N; j++) {
2993                        ProcessChangeItem item = mActiveProcessChanges[j];
2994                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2995                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2996                                    + item.pid + " uid=" + item.uid + ": "
2997                                    + item.foregroundActivities);
2998                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2999                                    item.foregroundActivities);
3000                        }
3001                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3002                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3003                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3004                            observer.onImportanceChanged(item.pid, item.uid,
3005                                    item.importance);
3006                        }
3007                    }
3008                } catch (RemoteException e) {
3009                }
3010            }
3011        }
3012        mProcessObservers.finishBroadcast();
3013    }
3014
3015    private void dispatchProcessDied(int pid, int uid) {
3016        int i = mProcessObservers.beginBroadcast();
3017        while (i > 0) {
3018            i--;
3019            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3020            if (observer != null) {
3021                try {
3022                    observer.onProcessDied(pid, uid);
3023                } catch (RemoteException e) {
3024                }
3025            }
3026        }
3027        mProcessObservers.finishBroadcast();
3028    }
3029
3030    final void doPendingActivityLaunchesLocked(boolean doResume) {
3031        final int N = mPendingActivityLaunches.size();
3032        if (N <= 0) {
3033            return;
3034        }
3035        for (int i=0; i<N; i++) {
3036            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3037            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3038                    doResume && i == (N-1), null);
3039        }
3040        mPendingActivityLaunches.clear();
3041    }
3042
3043    @Override
3044    public final int startActivity(IApplicationThread caller, String callingPackage,
3045            Intent intent, String resolvedType, IBinder resultTo,
3046            String resultWho, int requestCode, int startFlags,
3047            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3048        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3049                resultWho, requestCode,
3050                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3051    }
3052
3053    @Override
3054    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3055            Intent intent, String resolvedType, IBinder resultTo,
3056            String resultWho, int requestCode, int startFlags,
3057            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3058        enforceNotIsolatedCaller("startActivity");
3059        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3060                false, true, "startActivity", null);
3061        // TODO: Switch to user app stacks here.
3062        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3063                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3064                null, null, options, userId, null);
3065    }
3066
3067    @Override
3068    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3069            Intent intent, String resolvedType, IBinder resultTo,
3070            String resultWho, int requestCode, int startFlags, String profileFile,
3071            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3072        enforceNotIsolatedCaller("startActivityAndWait");
3073        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3074                false, true, "startActivityAndWait", null);
3075        WaitResult res = new WaitResult();
3076        // TODO: Switch to user app stacks here.
3077        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3078                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3079                res, null, options, UserHandle.getCallingUserId(), null);
3080        return res;
3081    }
3082
3083    @Override
3084    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3085            Intent intent, String resolvedType, IBinder resultTo,
3086            String resultWho, int requestCode, int startFlags, Configuration config,
3087            Bundle options, int userId) {
3088        enforceNotIsolatedCaller("startActivityWithConfig");
3089        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3090                false, true, "startActivityWithConfig", null);
3091        // TODO: Switch to user app stacks here.
3092        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3093                resolvedType, resultTo, resultWho, requestCode, startFlags,
3094                null, null, null, config, options, userId, null);
3095        return ret;
3096    }
3097
3098    @Override
3099    public int startActivityIntentSender(IApplicationThread caller,
3100            IntentSender intent, Intent fillInIntent, String resolvedType,
3101            IBinder resultTo, String resultWho, int requestCode,
3102            int flagsMask, int flagsValues, Bundle options) {
3103        enforceNotIsolatedCaller("startActivityIntentSender");
3104        // Refuse possible leaked file descriptors
3105        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3106            throw new IllegalArgumentException("File descriptors passed in Intent");
3107        }
3108
3109        IIntentSender sender = intent.getTarget();
3110        if (!(sender instanceof PendingIntentRecord)) {
3111            throw new IllegalArgumentException("Bad PendingIntent object");
3112        }
3113
3114        PendingIntentRecord pir = (PendingIntentRecord)sender;
3115
3116        synchronized (this) {
3117            // If this is coming from the currently resumed activity, it is
3118            // effectively saying that app switches are allowed at this point.
3119            final ActivityStack stack = getFocusedStack();
3120            if (stack.mResumedActivity != null &&
3121                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3122                mAppSwitchesAllowedTime = 0;
3123            }
3124        }
3125        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3126                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3127        return ret;
3128    }
3129
3130    @Override
3131    public boolean startNextMatchingActivity(IBinder callingActivity,
3132            Intent intent, Bundle options) {
3133        // Refuse possible leaked file descriptors
3134        if (intent != null && intent.hasFileDescriptors() == true) {
3135            throw new IllegalArgumentException("File descriptors passed in Intent");
3136        }
3137
3138        synchronized (this) {
3139            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3140            if (r == null) {
3141                ActivityOptions.abort(options);
3142                return false;
3143            }
3144            if (r.app == null || r.app.thread == null) {
3145                // The caller is not running...  d'oh!
3146                ActivityOptions.abort(options);
3147                return false;
3148            }
3149            intent = new Intent(intent);
3150            // The caller is not allowed to change the data.
3151            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3152            // And we are resetting to find the next component...
3153            intent.setComponent(null);
3154
3155            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3156
3157            ActivityInfo aInfo = null;
3158            try {
3159                List<ResolveInfo> resolves =
3160                    AppGlobals.getPackageManager().queryIntentActivities(
3161                            intent, r.resolvedType,
3162                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3163                            UserHandle.getCallingUserId());
3164
3165                // Look for the original activity in the list...
3166                final int N = resolves != null ? resolves.size() : 0;
3167                for (int i=0; i<N; i++) {
3168                    ResolveInfo rInfo = resolves.get(i);
3169                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3170                            && rInfo.activityInfo.name.equals(r.info.name)) {
3171                        // We found the current one...  the next matching is
3172                        // after it.
3173                        i++;
3174                        if (i<N) {
3175                            aInfo = resolves.get(i).activityInfo;
3176                        }
3177                        if (debug) {
3178                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3179                                    + "/" + r.info.name);
3180                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3181                                    + "/" + aInfo.name);
3182                        }
3183                        break;
3184                    }
3185                }
3186            } catch (RemoteException e) {
3187            }
3188
3189            if (aInfo == null) {
3190                // Nobody who is next!
3191                ActivityOptions.abort(options);
3192                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3193                return false;
3194            }
3195
3196            intent.setComponent(new ComponentName(
3197                    aInfo.applicationInfo.packageName, aInfo.name));
3198            intent.setFlags(intent.getFlags()&~(
3199                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3200                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3201                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3202                    Intent.FLAG_ACTIVITY_NEW_TASK));
3203
3204            // Okay now we need to start the new activity, replacing the
3205            // currently running activity.  This is a little tricky because
3206            // we want to start the new one as if the current one is finished,
3207            // but not finish the current one first so that there is no flicker.
3208            // And thus...
3209            final boolean wasFinishing = r.finishing;
3210            r.finishing = true;
3211
3212            // Propagate reply information over to the new activity.
3213            final ActivityRecord resultTo = r.resultTo;
3214            final String resultWho = r.resultWho;
3215            final int requestCode = r.requestCode;
3216            r.resultTo = null;
3217            if (resultTo != null) {
3218                resultTo.removeResultsLocked(r, resultWho, requestCode);
3219            }
3220
3221            final long origId = Binder.clearCallingIdentity();
3222            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3223                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3224                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3225                    options, false, null, null);
3226            Binder.restoreCallingIdentity(origId);
3227
3228            r.finishing = wasFinishing;
3229            if (res != ActivityManager.START_SUCCESS) {
3230                return false;
3231            }
3232            return true;
3233        }
3234    }
3235
3236    final int startActivityInPackage(int uid, String callingPackage,
3237            Intent intent, String resolvedType, IBinder resultTo,
3238            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3239                    IActivityContainer container) {
3240
3241        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3242                false, true, "startActivityInPackage", null);
3243
3244        // TODO: Switch to user app stacks here.
3245        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3246                resultTo, resultWho, requestCode, startFlags,
3247                null, null, null, null, options, userId, container);
3248        return ret;
3249    }
3250
3251    @Override
3252    public final int startActivities(IApplicationThread caller, String callingPackage,
3253            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3254            int userId) {
3255        enforceNotIsolatedCaller("startActivities");
3256        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3257                false, true, "startActivity", null);
3258        // TODO: Switch to user app stacks here.
3259        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3260                resolvedTypes, resultTo, options, userId);
3261        return ret;
3262    }
3263
3264    final int startActivitiesInPackage(int uid, String callingPackage,
3265            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3266            Bundle options, int userId) {
3267
3268        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3269                false, true, "startActivityInPackage", null);
3270        // TODO: Switch to user app stacks here.
3271        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3272                resultTo, options, userId);
3273        return ret;
3274    }
3275
3276    final void addRecentTaskLocked(TaskRecord task) {
3277        int N = mRecentTasks.size();
3278        // Quick case: check if the top-most recent task is the same.
3279        if (N > 0 && mRecentTasks.get(0) == task) {
3280            return;
3281        }
3282        // Remove any existing entries that are the same kind of task.
3283        for (int i=0; i<N; i++) {
3284            TaskRecord tr = mRecentTasks.get(i);
3285            if (task.userId == tr.userId
3286                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3287                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3288                tr.disposeThumbnail();
3289                mRecentTasks.remove(i);
3290                i--;
3291                N--;
3292                if (task.intent == null) {
3293                    // If the new recent task we are adding is not fully
3294                    // specified, then replace it with the existing recent task.
3295                    task = tr;
3296                }
3297            }
3298        }
3299        if (N >= MAX_RECENT_TASKS) {
3300            mRecentTasks.remove(N-1).disposeThumbnail();
3301        }
3302        mRecentTasks.add(0, task);
3303    }
3304
3305    @Override
3306    public void reportActivityFullyDrawn(IBinder token) {
3307        synchronized (this) {
3308            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3309            if (r == null) {
3310                return;
3311            }
3312            r.reportFullyDrawnLocked();
3313        }
3314    }
3315
3316    @Override
3317    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3318        synchronized (this) {
3319            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3320            if (r == null) {
3321                return;
3322            }
3323            final long origId = Binder.clearCallingIdentity();
3324            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3325            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3326                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3327            if (config != null) {
3328                r.frozenBeforeDestroy = true;
3329                if (!updateConfigurationLocked(config, r, false, false)) {
3330                    mStackSupervisor.resumeTopActivitiesLocked();
3331                }
3332            }
3333            Binder.restoreCallingIdentity(origId);
3334        }
3335    }
3336
3337    @Override
3338    public int getRequestedOrientation(IBinder token) {
3339        synchronized (this) {
3340            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3341            if (r == null) {
3342                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3343            }
3344            return mWindowManager.getAppOrientation(r.appToken);
3345        }
3346    }
3347
3348    /**
3349     * This is the internal entry point for handling Activity.finish().
3350     *
3351     * @param token The Binder token referencing the Activity we want to finish.
3352     * @param resultCode Result code, if any, from this Activity.
3353     * @param resultData Result data (Intent), if any, from this Activity.
3354     *
3355     * @return Returns true if the activity successfully finished, or false if it is still running.
3356     */
3357    @Override
3358    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3359        // Refuse possible leaked file descriptors
3360        if (resultData != null && resultData.hasFileDescriptors() == true) {
3361            throw new IllegalArgumentException("File descriptors passed in Intent");
3362        }
3363
3364        synchronized(this) {
3365            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3366            if (r == null) {
3367                return true;
3368            }
3369            if (mController != null) {
3370                // Find the first activity that is not finishing.
3371                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3372                if (next != null) {
3373                    // ask watcher if this is allowed
3374                    boolean resumeOK = true;
3375                    try {
3376                        resumeOK = mController.activityResuming(next.packageName);
3377                    } catch (RemoteException e) {
3378                        mController = null;
3379                        Watchdog.getInstance().setActivityController(null);
3380                    }
3381
3382                    if (!resumeOK) {
3383                        return false;
3384                    }
3385                }
3386            }
3387            final long origId = Binder.clearCallingIdentity();
3388            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3389                    resultData, "app-request", true);
3390            Binder.restoreCallingIdentity(origId);
3391            return res;
3392        }
3393    }
3394
3395    @Override
3396    public final void finishHeavyWeightApp() {
3397        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3398                != PackageManager.PERMISSION_GRANTED) {
3399            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3400                    + Binder.getCallingPid()
3401                    + ", uid=" + Binder.getCallingUid()
3402                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3403            Slog.w(TAG, msg);
3404            throw new SecurityException(msg);
3405        }
3406
3407        synchronized(this) {
3408            if (mHeavyWeightProcess == null) {
3409                return;
3410            }
3411
3412            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3413                    mHeavyWeightProcess.activities);
3414            for (int i=0; i<activities.size(); i++) {
3415                ActivityRecord r = activities.get(i);
3416                if (!r.finishing) {
3417                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3418                            null, "finish-heavy", true);
3419                }
3420            }
3421
3422            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3423                    mHeavyWeightProcess.userId, 0));
3424            mHeavyWeightProcess = null;
3425        }
3426    }
3427
3428    @Override
3429    public void crashApplication(int uid, int initialPid, String packageName,
3430            String message) {
3431        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3432                != PackageManager.PERMISSION_GRANTED) {
3433            String msg = "Permission Denial: crashApplication() from pid="
3434                    + Binder.getCallingPid()
3435                    + ", uid=" + Binder.getCallingUid()
3436                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3437            Slog.w(TAG, msg);
3438            throw new SecurityException(msg);
3439        }
3440
3441        synchronized(this) {
3442            ProcessRecord proc = null;
3443
3444            // Figure out which process to kill.  We don't trust that initialPid
3445            // still has any relation to current pids, so must scan through the
3446            // list.
3447            synchronized (mPidsSelfLocked) {
3448                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3449                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3450                    if (p.uid != uid) {
3451                        continue;
3452                    }
3453                    if (p.pid == initialPid) {
3454                        proc = p;
3455                        break;
3456                    }
3457                    if (p.pkgList.containsKey(packageName)) {
3458                        proc = p;
3459                    }
3460                }
3461            }
3462
3463            if (proc == null) {
3464                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3465                        + " initialPid=" + initialPid
3466                        + " packageName=" + packageName);
3467                return;
3468            }
3469
3470            if (proc.thread != null) {
3471                if (proc.pid == Process.myPid()) {
3472                    Log.w(TAG, "crashApplication: trying to crash self!");
3473                    return;
3474                }
3475                long ident = Binder.clearCallingIdentity();
3476                try {
3477                    proc.thread.scheduleCrash(message);
3478                } catch (RemoteException e) {
3479                }
3480                Binder.restoreCallingIdentity(ident);
3481            }
3482        }
3483    }
3484
3485    @Override
3486    public final void finishSubActivity(IBinder token, String resultWho,
3487            int requestCode) {
3488        synchronized(this) {
3489            final long origId = Binder.clearCallingIdentity();
3490            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3491            if (r != null) {
3492                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3493            }
3494            Binder.restoreCallingIdentity(origId);
3495        }
3496    }
3497
3498    @Override
3499    public boolean finishActivityAffinity(IBinder token) {
3500        synchronized(this) {
3501            final long origId = Binder.clearCallingIdentity();
3502            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3503            boolean res = false;
3504            if (r != null) {
3505                res = r.task.stack.finishActivityAffinityLocked(r);
3506            }
3507            Binder.restoreCallingIdentity(origId);
3508            return res;
3509        }
3510    }
3511
3512    @Override
3513    public boolean willActivityBeVisible(IBinder token) {
3514        synchronized(this) {
3515            ActivityStack stack = ActivityRecord.getStackLocked(token);
3516            if (stack != null) {
3517                return stack.willActivityBeVisibleLocked(token);
3518            }
3519            return false;
3520        }
3521    }
3522
3523    @Override
3524    public void overridePendingTransition(IBinder token, String packageName,
3525            int enterAnim, int exitAnim) {
3526        synchronized(this) {
3527            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3528            if (self == null) {
3529                return;
3530            }
3531
3532            final long origId = Binder.clearCallingIdentity();
3533
3534            if (self.state == ActivityState.RESUMED
3535                    || self.state == ActivityState.PAUSING) {
3536                mWindowManager.overridePendingAppTransition(packageName,
3537                        enterAnim, exitAnim, null);
3538            }
3539
3540            Binder.restoreCallingIdentity(origId);
3541        }
3542    }
3543
3544    /**
3545     * Main function for removing an existing process from the activity manager
3546     * as a result of that process going away.  Clears out all connections
3547     * to the process.
3548     */
3549    private final void handleAppDiedLocked(ProcessRecord app,
3550            boolean restarting, boolean allowRestart) {
3551        int pid = app.pid;
3552        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3553        if (!restarting) {
3554            removeLruProcessLocked(app);
3555            if (pid > 0) {
3556                ProcessList.remove(pid);
3557            }
3558        }
3559
3560        if (mProfileProc == app) {
3561            clearProfilerLocked();
3562        }
3563
3564        // Remove this application's activities from active lists.
3565        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3566
3567        app.activities.clear();
3568
3569        if (app.instrumentationClass != null) {
3570            Slog.w(TAG, "Crash of app " + app.processName
3571                  + " running instrumentation " + app.instrumentationClass);
3572            Bundle info = new Bundle();
3573            info.putString("shortMsg", "Process crashed.");
3574            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3575        }
3576
3577        if (!restarting) {
3578            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3579                // If there was nothing to resume, and we are not already
3580                // restarting this process, but there is a visible activity that
3581                // is hosted by the process...  then make sure all visible
3582                // activities are running, taking care of restarting this
3583                // process.
3584                if (hasVisibleActivities) {
3585                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3586                }
3587            }
3588        }
3589    }
3590
3591    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3592        IBinder threadBinder = thread.asBinder();
3593        // Find the application record.
3594        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3595            ProcessRecord rec = mLruProcesses.get(i);
3596            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3597                return i;
3598            }
3599        }
3600        return -1;
3601    }
3602
3603    final ProcessRecord getRecordForAppLocked(
3604            IApplicationThread thread) {
3605        if (thread == null) {
3606            return null;
3607        }
3608
3609        int appIndex = getLRURecordIndexForAppLocked(thread);
3610        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3611    }
3612
3613    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3614        // If there are no longer any background processes running,
3615        // and the app that died was not running instrumentation,
3616        // then tell everyone we are now low on memory.
3617        boolean haveBg = false;
3618        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3619            ProcessRecord rec = mLruProcesses.get(i);
3620            if (rec.thread != null
3621                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3622                haveBg = true;
3623                break;
3624            }
3625        }
3626
3627        if (!haveBg) {
3628            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3629            if (doReport) {
3630                long now = SystemClock.uptimeMillis();
3631                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3632                    doReport = false;
3633                } else {
3634                    mLastMemUsageReportTime = now;
3635                }
3636            }
3637            final ArrayList<ProcessMemInfo> memInfos
3638                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3639            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3640            long now = SystemClock.uptimeMillis();
3641            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3642                ProcessRecord rec = mLruProcesses.get(i);
3643                if (rec == dyingProc || rec.thread == null) {
3644                    continue;
3645                }
3646                if (doReport) {
3647                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3648                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3649                }
3650                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3651                    // The low memory report is overriding any current
3652                    // state for a GC request.  Make sure to do
3653                    // heavy/important/visible/foreground processes first.
3654                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3655                        rec.lastRequestedGc = 0;
3656                    } else {
3657                        rec.lastRequestedGc = rec.lastLowMemory;
3658                    }
3659                    rec.reportLowMemory = true;
3660                    rec.lastLowMemory = now;
3661                    mProcessesToGc.remove(rec);
3662                    addProcessToGcListLocked(rec);
3663                }
3664            }
3665            if (doReport) {
3666                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3667                mHandler.sendMessage(msg);
3668            }
3669            scheduleAppGcsLocked();
3670        }
3671    }
3672
3673    final void appDiedLocked(ProcessRecord app, int pid,
3674            IApplicationThread thread) {
3675
3676        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3677        synchronized (stats) {
3678            stats.noteProcessDiedLocked(app.info.uid, pid);
3679        }
3680
3681        // Clean up already done if the process has been re-started.
3682        if (app.pid == pid && app.thread != null &&
3683                app.thread.asBinder() == thread.asBinder()) {
3684            boolean doLowMem = app.instrumentationClass == null;
3685            boolean doOomAdj = doLowMem;
3686            if (!app.killedByAm) {
3687                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3688                        + ") has died.");
3689                mAllowLowerMemLevel = true;
3690            } else {
3691                // Note that we always want to do oom adj to update our state with the
3692                // new number of procs.
3693                mAllowLowerMemLevel = false;
3694                doLowMem = false;
3695            }
3696            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3697            if (DEBUG_CLEANUP) Slog.v(
3698                TAG, "Dying app: " + app + ", pid: " + pid
3699                + ", thread: " + thread.asBinder());
3700            handleAppDiedLocked(app, false, true);
3701
3702            if (doOomAdj) {
3703                updateOomAdjLocked();
3704            }
3705            if (doLowMem) {
3706                doLowMemReportIfNeededLocked(app);
3707            }
3708        } else if (app.pid != pid) {
3709            // A new process has already been started.
3710            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3711                    + ") has died and restarted (pid " + app.pid + ").");
3712            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3713        } else if (DEBUG_PROCESSES) {
3714            Slog.d(TAG, "Received spurious death notification for thread "
3715                    + thread.asBinder());
3716        }
3717    }
3718
3719    /**
3720     * If a stack trace dump file is configured, dump process stack traces.
3721     * @param clearTraces causes the dump file to be erased prior to the new
3722     *    traces being written, if true; when false, the new traces will be
3723     *    appended to any existing file content.
3724     * @param firstPids of dalvik VM processes to dump stack traces for first
3725     * @param lastPids of dalvik VM processes to dump stack traces for last
3726     * @param nativeProcs optional list of native process names to dump stack crawls
3727     * @return file containing stack traces, or null if no dump file is configured
3728     */
3729    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3730            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3731        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3732        if (tracesPath == null || tracesPath.length() == 0) {
3733            return null;
3734        }
3735
3736        File tracesFile = new File(tracesPath);
3737        try {
3738            File tracesDir = tracesFile.getParentFile();
3739            if (!tracesDir.exists()) {
3740                tracesFile.mkdirs();
3741                if (!SELinux.restorecon(tracesDir)) {
3742                    return null;
3743                }
3744            }
3745            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3746
3747            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3748            tracesFile.createNewFile();
3749            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3750        } catch (IOException e) {
3751            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3752            return null;
3753        }
3754
3755        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3756        return tracesFile;
3757    }
3758
3759    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3760            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3761        // Use a FileObserver to detect when traces finish writing.
3762        // The order of traces is considered important to maintain for legibility.
3763        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3764            @Override
3765            public synchronized void onEvent(int event, String path) { notify(); }
3766        };
3767
3768        try {
3769            observer.startWatching();
3770
3771            // First collect all of the stacks of the most important pids.
3772            if (firstPids != null) {
3773                try {
3774                    int num = firstPids.size();
3775                    for (int i = 0; i < num; i++) {
3776                        synchronized (observer) {
3777                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3778                            observer.wait(200);  // Wait for write-close, give up after 200msec
3779                        }
3780                    }
3781                } catch (InterruptedException e) {
3782                    Log.wtf(TAG, e);
3783                }
3784            }
3785
3786            // Next collect the stacks of the native pids
3787            if (nativeProcs != null) {
3788                int[] pids = Process.getPidsForCommands(nativeProcs);
3789                if (pids != null) {
3790                    for (int pid : pids) {
3791                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3792                    }
3793                }
3794            }
3795
3796            // Lastly, measure CPU usage.
3797            if (processCpuTracker != null) {
3798                processCpuTracker.init();
3799                System.gc();
3800                processCpuTracker.update();
3801                try {
3802                    synchronized (processCpuTracker) {
3803                        processCpuTracker.wait(500); // measure over 1/2 second.
3804                    }
3805                } catch (InterruptedException e) {
3806                }
3807                processCpuTracker.update();
3808
3809                // We'll take the stack crawls of just the top apps using CPU.
3810                final int N = processCpuTracker.countWorkingStats();
3811                int numProcs = 0;
3812                for (int i=0; i<N && numProcs<5; i++) {
3813                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3814                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3815                        numProcs++;
3816                        try {
3817                            synchronized (observer) {
3818                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3819                                observer.wait(200);  // Wait for write-close, give up after 200msec
3820                            }
3821                        } catch (InterruptedException e) {
3822                            Log.wtf(TAG, e);
3823                        }
3824
3825                    }
3826                }
3827            }
3828        } finally {
3829            observer.stopWatching();
3830        }
3831    }
3832
3833    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3834        if (true || IS_USER_BUILD) {
3835            return;
3836        }
3837        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3838        if (tracesPath == null || tracesPath.length() == 0) {
3839            return;
3840        }
3841
3842        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3843        StrictMode.allowThreadDiskWrites();
3844        try {
3845            final File tracesFile = new File(tracesPath);
3846            final File tracesDir = tracesFile.getParentFile();
3847            final File tracesTmp = new File(tracesDir, "__tmp__");
3848            try {
3849                if (!tracesDir.exists()) {
3850                    tracesFile.mkdirs();
3851                    if (!SELinux.restorecon(tracesDir.getPath())) {
3852                        return;
3853                    }
3854                }
3855                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3856
3857                if (tracesFile.exists()) {
3858                    tracesTmp.delete();
3859                    tracesFile.renameTo(tracesTmp);
3860                }
3861                StringBuilder sb = new StringBuilder();
3862                Time tobj = new Time();
3863                tobj.set(System.currentTimeMillis());
3864                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3865                sb.append(": ");
3866                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3867                sb.append(" since ");
3868                sb.append(msg);
3869                FileOutputStream fos = new FileOutputStream(tracesFile);
3870                fos.write(sb.toString().getBytes());
3871                if (app == null) {
3872                    fos.write("\n*** No application process!".getBytes());
3873                }
3874                fos.close();
3875                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3876            } catch (IOException e) {
3877                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3878                return;
3879            }
3880
3881            if (app != null) {
3882                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3883                firstPids.add(app.pid);
3884                dumpStackTraces(tracesPath, firstPids, null, null, null);
3885            }
3886
3887            File lastTracesFile = null;
3888            File curTracesFile = null;
3889            for (int i=9; i>=0; i--) {
3890                String name = String.format(Locale.US, "slow%02d.txt", i);
3891                curTracesFile = new File(tracesDir, name);
3892                if (curTracesFile.exists()) {
3893                    if (lastTracesFile != null) {
3894                        curTracesFile.renameTo(lastTracesFile);
3895                    } else {
3896                        curTracesFile.delete();
3897                    }
3898                }
3899                lastTracesFile = curTracesFile;
3900            }
3901            tracesFile.renameTo(curTracesFile);
3902            if (tracesTmp.exists()) {
3903                tracesTmp.renameTo(tracesFile);
3904            }
3905        } finally {
3906            StrictMode.setThreadPolicy(oldPolicy);
3907        }
3908    }
3909
3910    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3911            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3912        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3913        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3914
3915        if (mController != null) {
3916            try {
3917                // 0 == continue, -1 = kill process immediately
3918                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3919                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3920            } catch (RemoteException e) {
3921                mController = null;
3922                Watchdog.getInstance().setActivityController(null);
3923            }
3924        }
3925
3926        long anrTime = SystemClock.uptimeMillis();
3927        if (MONITOR_CPU_USAGE) {
3928            updateCpuStatsNow();
3929        }
3930
3931        synchronized (this) {
3932            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3933            if (mShuttingDown) {
3934                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3935                return;
3936            } else if (app.notResponding) {
3937                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3938                return;
3939            } else if (app.crashing) {
3940                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3941                return;
3942            }
3943
3944            // In case we come through here for the same app before completing
3945            // this one, mark as anring now so we will bail out.
3946            app.notResponding = true;
3947
3948            // Log the ANR to the event log.
3949            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3950                    app.processName, app.info.flags, annotation);
3951
3952            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3953            firstPids.add(app.pid);
3954
3955            int parentPid = app.pid;
3956            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3957            if (parentPid != app.pid) firstPids.add(parentPid);
3958
3959            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3960
3961            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3962                ProcessRecord r = mLruProcesses.get(i);
3963                if (r != null && r.thread != null) {
3964                    int pid = r.pid;
3965                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3966                        if (r.persistent) {
3967                            firstPids.add(pid);
3968                        } else {
3969                            lastPids.put(pid, Boolean.TRUE);
3970                        }
3971                    }
3972                }
3973            }
3974        }
3975
3976        // Log the ANR to the main log.
3977        StringBuilder info = new StringBuilder();
3978        info.setLength(0);
3979        info.append("ANR in ").append(app.processName);
3980        if (activity != null && activity.shortComponentName != null) {
3981            info.append(" (").append(activity.shortComponentName).append(")");
3982        }
3983        info.append("\n");
3984        info.append("PID: ").append(app.pid).append("\n");
3985        if (annotation != null) {
3986            info.append("Reason: ").append(annotation).append("\n");
3987        }
3988        if (parent != null && parent != activity) {
3989            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3990        }
3991
3992        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
3993
3994        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
3995                NATIVE_STACKS_OF_INTEREST);
3996
3997        String cpuInfo = null;
3998        if (MONITOR_CPU_USAGE) {
3999            updateCpuStatsNow();
4000            synchronized (mProcessCpuThread) {
4001                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4002            }
4003            info.append(processCpuTracker.printCurrentLoad());
4004            info.append(cpuInfo);
4005        }
4006
4007        info.append(processCpuTracker.printCurrentState(anrTime));
4008
4009        Slog.e(TAG, info.toString());
4010        if (tracesFile == null) {
4011            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4012            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4013        }
4014
4015        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4016                cpuInfo, tracesFile, null);
4017
4018        if (mController != null) {
4019            try {
4020                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4021                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4022                if (res != 0) {
4023                    if (res < 0 && app.pid != MY_PID) {
4024                        Process.killProcess(app.pid);
4025                    } else {
4026                        synchronized (this) {
4027                            mServices.scheduleServiceTimeoutLocked(app);
4028                        }
4029                    }
4030                    return;
4031                }
4032            } catch (RemoteException e) {
4033                mController = null;
4034                Watchdog.getInstance().setActivityController(null);
4035            }
4036        }
4037
4038        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4039        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4040                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4041
4042        synchronized (this) {
4043            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4044                killUnneededProcessLocked(app, "background ANR");
4045                return;
4046            }
4047
4048            // Set the app's notResponding state, and look up the errorReportReceiver
4049            makeAppNotRespondingLocked(app,
4050                    activity != null ? activity.shortComponentName : null,
4051                    annotation != null ? "ANR " + annotation : "ANR",
4052                    info.toString());
4053
4054            // Bring up the infamous App Not Responding dialog
4055            Message msg = Message.obtain();
4056            HashMap<String, Object> map = new HashMap<String, Object>();
4057            msg.what = SHOW_NOT_RESPONDING_MSG;
4058            msg.obj = map;
4059            msg.arg1 = aboveSystem ? 1 : 0;
4060            map.put("app", app);
4061            if (activity != null) {
4062                map.put("activity", activity);
4063            }
4064
4065            mHandler.sendMessage(msg);
4066        }
4067    }
4068
4069    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4070        if (!mLaunchWarningShown) {
4071            mLaunchWarningShown = true;
4072            mHandler.post(new Runnable() {
4073                @Override
4074                public void run() {
4075                    synchronized (ActivityManagerService.this) {
4076                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4077                        d.show();
4078                        mHandler.postDelayed(new Runnable() {
4079                            @Override
4080                            public void run() {
4081                                synchronized (ActivityManagerService.this) {
4082                                    d.dismiss();
4083                                    mLaunchWarningShown = false;
4084                                }
4085                            }
4086                        }, 4000);
4087                    }
4088                }
4089            });
4090        }
4091    }
4092
4093    @Override
4094    public boolean clearApplicationUserData(final String packageName,
4095            final IPackageDataObserver observer, int userId) {
4096        enforceNotIsolatedCaller("clearApplicationUserData");
4097        int uid = Binder.getCallingUid();
4098        int pid = Binder.getCallingPid();
4099        userId = handleIncomingUser(pid, uid,
4100                userId, false, true, "clearApplicationUserData", null);
4101        long callingId = Binder.clearCallingIdentity();
4102        try {
4103            IPackageManager pm = AppGlobals.getPackageManager();
4104            int pkgUid = -1;
4105            synchronized(this) {
4106                try {
4107                    pkgUid = pm.getPackageUid(packageName, userId);
4108                } catch (RemoteException e) {
4109                }
4110                if (pkgUid == -1) {
4111                    Slog.w(TAG, "Invalid packageName: " + packageName);
4112                    if (observer != null) {
4113                        try {
4114                            observer.onRemoveCompleted(packageName, false);
4115                        } catch (RemoteException e) {
4116                            Slog.i(TAG, "Observer no longer exists.");
4117                        }
4118                    }
4119                    return false;
4120                }
4121                if (uid == pkgUid || checkComponentPermission(
4122                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4123                        pid, uid, -1, true)
4124                        == PackageManager.PERMISSION_GRANTED) {
4125                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4126                } else {
4127                    throw new SecurityException("PID " + pid + " does not have permission "
4128                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4129                                    + " of package " + packageName);
4130                }
4131            }
4132
4133            try {
4134                // Clear application user data
4135                pm.clearApplicationUserData(packageName, observer, userId);
4136
4137                // Remove all permissions granted from/to this package
4138                removeUriPermissionsForPackageLocked(packageName, userId, true);
4139
4140                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4141                        Uri.fromParts("package", packageName, null));
4142                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4143                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4144                        null, null, 0, null, null, null, false, false, userId);
4145            } catch (RemoteException e) {
4146            }
4147        } finally {
4148            Binder.restoreCallingIdentity(callingId);
4149        }
4150        return true;
4151    }
4152
4153    @Override
4154    public void killBackgroundProcesses(final String packageName, int userId) {
4155        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4156                != PackageManager.PERMISSION_GRANTED &&
4157                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4158                        != PackageManager.PERMISSION_GRANTED) {
4159            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4160                    + Binder.getCallingPid()
4161                    + ", uid=" + Binder.getCallingUid()
4162                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4163            Slog.w(TAG, msg);
4164            throw new SecurityException(msg);
4165        }
4166
4167        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4168                userId, true, true, "killBackgroundProcesses", null);
4169        long callingId = Binder.clearCallingIdentity();
4170        try {
4171            IPackageManager pm = AppGlobals.getPackageManager();
4172            synchronized(this) {
4173                int appId = -1;
4174                try {
4175                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4176                } catch (RemoteException e) {
4177                }
4178                if (appId == -1) {
4179                    Slog.w(TAG, "Invalid packageName: " + packageName);
4180                    return;
4181                }
4182                killPackageProcessesLocked(packageName, appId, userId,
4183                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4184            }
4185        } finally {
4186            Binder.restoreCallingIdentity(callingId);
4187        }
4188    }
4189
4190    @Override
4191    public void killAllBackgroundProcesses() {
4192        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4193                != PackageManager.PERMISSION_GRANTED) {
4194            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4195                    + Binder.getCallingPid()
4196                    + ", uid=" + Binder.getCallingUid()
4197                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4198            Slog.w(TAG, msg);
4199            throw new SecurityException(msg);
4200        }
4201
4202        long callingId = Binder.clearCallingIdentity();
4203        try {
4204            synchronized(this) {
4205                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4206                final int NP = mProcessNames.getMap().size();
4207                for (int ip=0; ip<NP; ip++) {
4208                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4209                    final int NA = apps.size();
4210                    for (int ia=0; ia<NA; ia++) {
4211                        ProcessRecord app = apps.valueAt(ia);
4212                        if (app.persistent) {
4213                            // we don't kill persistent processes
4214                            continue;
4215                        }
4216                        if (app.removed) {
4217                            procs.add(app);
4218                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4219                            app.removed = true;
4220                            procs.add(app);
4221                        }
4222                    }
4223                }
4224
4225                int N = procs.size();
4226                for (int i=0; i<N; i++) {
4227                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4228                }
4229                mAllowLowerMemLevel = true;
4230                updateOomAdjLocked();
4231                doLowMemReportIfNeededLocked(null);
4232            }
4233        } finally {
4234            Binder.restoreCallingIdentity(callingId);
4235        }
4236    }
4237
4238    @Override
4239    public void forceStopPackage(final String packageName, int userId) {
4240        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4241                != PackageManager.PERMISSION_GRANTED) {
4242            String msg = "Permission Denial: forceStopPackage() from pid="
4243                    + Binder.getCallingPid()
4244                    + ", uid=" + Binder.getCallingUid()
4245                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4246            Slog.w(TAG, msg);
4247            throw new SecurityException(msg);
4248        }
4249        final int callingPid = Binder.getCallingPid();
4250        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4251                userId, true, true, "forceStopPackage", null);
4252        long callingId = Binder.clearCallingIdentity();
4253        try {
4254            IPackageManager pm = AppGlobals.getPackageManager();
4255            synchronized(this) {
4256                int[] users = userId == UserHandle.USER_ALL
4257                        ? getUsersLocked() : new int[] { userId };
4258                for (int user : users) {
4259                    int pkgUid = -1;
4260                    try {
4261                        pkgUid = pm.getPackageUid(packageName, user);
4262                    } catch (RemoteException e) {
4263                    }
4264                    if (pkgUid == -1) {
4265                        Slog.w(TAG, "Invalid packageName: " + packageName);
4266                        continue;
4267                    }
4268                    try {
4269                        pm.setPackageStoppedState(packageName, true, user);
4270                    } catch (RemoteException e) {
4271                    } catch (IllegalArgumentException e) {
4272                        Slog.w(TAG, "Failed trying to unstop package "
4273                                + packageName + ": " + e);
4274                    }
4275                    if (isUserRunningLocked(user, false)) {
4276                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4277                    }
4278                }
4279            }
4280        } finally {
4281            Binder.restoreCallingIdentity(callingId);
4282        }
4283    }
4284
4285    /*
4286     * The pkg name and app id have to be specified.
4287     */
4288    @Override
4289    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4290        if (pkg == null) {
4291            return;
4292        }
4293        // Make sure the uid is valid.
4294        if (appid < 0) {
4295            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4296            return;
4297        }
4298        int callerUid = Binder.getCallingUid();
4299        // Only the system server can kill an application
4300        if (callerUid == Process.SYSTEM_UID) {
4301            // Post an aysnc message to kill the application
4302            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4303            msg.arg1 = appid;
4304            msg.arg2 = 0;
4305            Bundle bundle = new Bundle();
4306            bundle.putString("pkg", pkg);
4307            bundle.putString("reason", reason);
4308            msg.obj = bundle;
4309            mHandler.sendMessage(msg);
4310        } else {
4311            throw new SecurityException(callerUid + " cannot kill pkg: " +
4312                    pkg);
4313        }
4314    }
4315
4316    @Override
4317    public void closeSystemDialogs(String reason) {
4318        enforceNotIsolatedCaller("closeSystemDialogs");
4319
4320        final int pid = Binder.getCallingPid();
4321        final int uid = Binder.getCallingUid();
4322        final long origId = Binder.clearCallingIdentity();
4323        try {
4324            synchronized (this) {
4325                // Only allow this from foreground processes, so that background
4326                // applications can't abuse it to prevent system UI from being shown.
4327                if (uid >= Process.FIRST_APPLICATION_UID) {
4328                    ProcessRecord proc;
4329                    synchronized (mPidsSelfLocked) {
4330                        proc = mPidsSelfLocked.get(pid);
4331                    }
4332                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4333                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4334                                + " from background process " + proc);
4335                        return;
4336                    }
4337                }
4338                closeSystemDialogsLocked(reason);
4339            }
4340        } finally {
4341            Binder.restoreCallingIdentity(origId);
4342        }
4343    }
4344
4345    void closeSystemDialogsLocked(String reason) {
4346        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4347        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4348                | Intent.FLAG_RECEIVER_FOREGROUND);
4349        if (reason != null) {
4350            intent.putExtra("reason", reason);
4351        }
4352        mWindowManager.closeSystemDialogs(reason);
4353
4354        mStackSupervisor.closeSystemDialogsLocked();
4355
4356        broadcastIntentLocked(null, null, intent, null,
4357                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4358                Process.SYSTEM_UID, UserHandle.USER_ALL);
4359    }
4360
4361    @Override
4362    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4363        enforceNotIsolatedCaller("getProcessMemoryInfo");
4364        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4365        for (int i=pids.length-1; i>=0; i--) {
4366            ProcessRecord proc;
4367            int oomAdj;
4368            synchronized (this) {
4369                synchronized (mPidsSelfLocked) {
4370                    proc = mPidsSelfLocked.get(pids[i]);
4371                    oomAdj = proc != null ? proc.setAdj : 0;
4372                }
4373            }
4374            infos[i] = new Debug.MemoryInfo();
4375            Debug.getMemoryInfo(pids[i], infos[i]);
4376            if (proc != null) {
4377                synchronized (this) {
4378                    if (proc.thread != null && proc.setAdj == oomAdj) {
4379                        // Record this for posterity if the process has been stable.
4380                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4381                                infos[i].getTotalUss(), false, proc.pkgList);
4382                    }
4383                }
4384            }
4385        }
4386        return infos;
4387    }
4388
4389    @Override
4390    public long[] getProcessPss(int[] pids) {
4391        enforceNotIsolatedCaller("getProcessPss");
4392        long[] pss = new long[pids.length];
4393        for (int i=pids.length-1; i>=0; i--) {
4394            ProcessRecord proc;
4395            int oomAdj;
4396            synchronized (this) {
4397                synchronized (mPidsSelfLocked) {
4398                    proc = mPidsSelfLocked.get(pids[i]);
4399                    oomAdj = proc != null ? proc.setAdj : 0;
4400                }
4401            }
4402            long[] tmpUss = new long[1];
4403            pss[i] = Debug.getPss(pids[i], tmpUss);
4404            if (proc != null) {
4405                synchronized (this) {
4406                    if (proc.thread != null && proc.setAdj == oomAdj) {
4407                        // Record this for posterity if the process has been stable.
4408                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4409                    }
4410                }
4411            }
4412        }
4413        return pss;
4414    }
4415
4416    @Override
4417    public void killApplicationProcess(String processName, int uid) {
4418        if (processName == null) {
4419            return;
4420        }
4421
4422        int callerUid = Binder.getCallingUid();
4423        // Only the system server can kill an application
4424        if (callerUid == Process.SYSTEM_UID) {
4425            synchronized (this) {
4426                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4427                if (app != null && app.thread != null) {
4428                    try {
4429                        app.thread.scheduleSuicide();
4430                    } catch (RemoteException e) {
4431                        // If the other end already died, then our work here is done.
4432                    }
4433                } else {
4434                    Slog.w(TAG, "Process/uid not found attempting kill of "
4435                            + processName + " / " + uid);
4436                }
4437            }
4438        } else {
4439            throw new SecurityException(callerUid + " cannot kill app process: " +
4440                    processName);
4441        }
4442    }
4443
4444    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4445        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4446                false, true, false, UserHandle.getUserId(uid), reason);
4447        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4448                Uri.fromParts("package", packageName, null));
4449        if (!mProcessesReady) {
4450            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4451                    | Intent.FLAG_RECEIVER_FOREGROUND);
4452        }
4453        intent.putExtra(Intent.EXTRA_UID, uid);
4454        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4455        broadcastIntentLocked(null, null, intent,
4456                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4457                false, false,
4458                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4459    }
4460
4461    private void forceStopUserLocked(int userId, String reason) {
4462        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
4463        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4464        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4465                | Intent.FLAG_RECEIVER_FOREGROUND);
4466        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4467        broadcastIntentLocked(null, null, intent,
4468                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4469                false, false,
4470                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4471    }
4472
4473    private final boolean killPackageProcessesLocked(String packageName, int appId,
4474            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4475            boolean doit, boolean evenPersistent, String reason) {
4476        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4477
4478        // Remove all processes this package may have touched: all with the
4479        // same UID (except for the system or root user), and all whose name
4480        // matches the package name.
4481        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4482        final int NP = mProcessNames.getMap().size();
4483        for (int ip=0; ip<NP; ip++) {
4484            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4485            final int NA = apps.size();
4486            for (int ia=0; ia<NA; ia++) {
4487                ProcessRecord app = apps.valueAt(ia);
4488                if (app.persistent && !evenPersistent) {
4489                    // we don't kill persistent processes
4490                    continue;
4491                }
4492                if (app.removed) {
4493                    if (doit) {
4494                        procs.add(app);
4495                    }
4496                    continue;
4497                }
4498
4499                // Skip process if it doesn't meet our oom adj requirement.
4500                if (app.setAdj < minOomAdj) {
4501                    continue;
4502                }
4503
4504                // If no package is specified, we call all processes under the
4505                // give user id.
4506                if (packageName == null) {
4507                    if (app.userId != userId) {
4508                        continue;
4509                    }
4510                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4511                        continue;
4512                    }
4513                // Package has been specified, we want to hit all processes
4514                // that match it.  We need to qualify this by the processes
4515                // that are running under the specified app and user ID.
4516                } else {
4517                    if (UserHandle.getAppId(app.uid) != appId) {
4518                        continue;
4519                    }
4520                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4521                        continue;
4522                    }
4523                    if (!app.pkgList.containsKey(packageName)) {
4524                        continue;
4525                    }
4526                }
4527
4528                // Process has passed all conditions, kill it!
4529                if (!doit) {
4530                    return true;
4531                }
4532                app.removed = true;
4533                procs.add(app);
4534            }
4535        }
4536
4537        int N = procs.size();
4538        for (int i=0; i<N; i++) {
4539            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4540        }
4541        updateOomAdjLocked();
4542        return N > 0;
4543    }
4544
4545    private final boolean forceStopPackageLocked(String name, int appId,
4546            boolean callerWillRestart, boolean purgeCache, boolean doit,
4547            boolean evenPersistent, int userId, String reason) {
4548        int i;
4549        int N;
4550
4551        if (userId == UserHandle.USER_ALL && name == null) {
4552            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4553        }
4554
4555        if (appId < 0 && name != null) {
4556            try {
4557                appId = UserHandle.getAppId(
4558                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4559            } catch (RemoteException e) {
4560            }
4561        }
4562
4563        if (doit) {
4564            if (name != null) {
4565                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4566                        + " user=" + userId + ": " + reason);
4567            } else {
4568                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4569            }
4570
4571            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4572            for (int ip=pmap.size()-1; ip>=0; ip--) {
4573                SparseArray<Long> ba = pmap.valueAt(ip);
4574                for (i=ba.size()-1; i>=0; i--) {
4575                    boolean remove = false;
4576                    final int entUid = ba.keyAt(i);
4577                    if (name != null) {
4578                        if (userId == UserHandle.USER_ALL) {
4579                            if (UserHandle.getAppId(entUid) == appId) {
4580                                remove = true;
4581                            }
4582                        } else {
4583                            if (entUid == UserHandle.getUid(userId, appId)) {
4584                                remove = true;
4585                            }
4586                        }
4587                    } else if (UserHandle.getUserId(entUid) == userId) {
4588                        remove = true;
4589                    }
4590                    if (remove) {
4591                        ba.removeAt(i);
4592                    }
4593                }
4594                if (ba.size() == 0) {
4595                    pmap.removeAt(ip);
4596                }
4597            }
4598        }
4599
4600        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4601                -100, callerWillRestart, true, doit, evenPersistent,
4602                name == null ? ("stop user " + userId) : ("stop " + name));
4603
4604        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4605            if (!doit) {
4606                return true;
4607            }
4608            didSomething = true;
4609        }
4610
4611        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4612            if (!doit) {
4613                return true;
4614            }
4615            didSomething = true;
4616        }
4617
4618        if (name == null) {
4619            // Remove all sticky broadcasts from this user.
4620            mStickyBroadcasts.remove(userId);
4621        }
4622
4623        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4624        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4625                userId, providers)) {
4626            if (!doit) {
4627                return true;
4628            }
4629            didSomething = true;
4630        }
4631        N = providers.size();
4632        for (i=0; i<N; i++) {
4633            removeDyingProviderLocked(null, providers.get(i), true);
4634        }
4635
4636        // Remove transient permissions granted from/to this package/user
4637        removeUriPermissionsForPackageLocked(name, userId, false);
4638
4639        if (name == null) {
4640            // Remove pending intents.  For now we only do this when force
4641            // stopping users, because we have some problems when doing this
4642            // for packages -- app widgets are not currently cleaned up for
4643            // such packages, so they can be left with bad pending intents.
4644            if (mIntentSenderRecords.size() > 0) {
4645                Iterator<WeakReference<PendingIntentRecord>> it
4646                        = mIntentSenderRecords.values().iterator();
4647                while (it.hasNext()) {
4648                    WeakReference<PendingIntentRecord> wpir = it.next();
4649                    if (wpir == null) {
4650                        it.remove();
4651                        continue;
4652                    }
4653                    PendingIntentRecord pir = wpir.get();
4654                    if (pir == null) {
4655                        it.remove();
4656                        continue;
4657                    }
4658                    if (name == null) {
4659                        // Stopping user, remove all objects for the user.
4660                        if (pir.key.userId != userId) {
4661                            // Not the same user, skip it.
4662                            continue;
4663                        }
4664                    } else {
4665                        if (UserHandle.getAppId(pir.uid) != appId) {
4666                            // Different app id, skip it.
4667                            continue;
4668                        }
4669                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4670                            // Different user, skip it.
4671                            continue;
4672                        }
4673                        if (!pir.key.packageName.equals(name)) {
4674                            // Different package, skip it.
4675                            continue;
4676                        }
4677                    }
4678                    if (!doit) {
4679                        return true;
4680                    }
4681                    didSomething = true;
4682                    it.remove();
4683                    pir.canceled = true;
4684                    if (pir.key.activity != null) {
4685                        pir.key.activity.pendingResults.remove(pir.ref);
4686                    }
4687                }
4688            }
4689        }
4690
4691        if (doit) {
4692            if (purgeCache && name != null) {
4693                AttributeCache ac = AttributeCache.instance();
4694                if (ac != null) {
4695                    ac.removePackage(name);
4696                }
4697            }
4698            if (mBooted) {
4699                mStackSupervisor.resumeTopActivitiesLocked();
4700                mStackSupervisor.scheduleIdleLocked();
4701            }
4702        }
4703
4704        return didSomething;
4705    }
4706
4707    private final boolean removeProcessLocked(ProcessRecord app,
4708            boolean callerWillRestart, boolean allowRestart, String reason) {
4709        final String name = app.processName;
4710        final int uid = app.uid;
4711        if (DEBUG_PROCESSES) Slog.d(
4712            TAG, "Force removing proc " + app.toShortString() + " (" + name
4713            + "/" + uid + ")");
4714
4715        mProcessNames.remove(name, uid);
4716        mIsolatedProcesses.remove(app.uid);
4717        if (mHeavyWeightProcess == app) {
4718            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4719                    mHeavyWeightProcess.userId, 0));
4720            mHeavyWeightProcess = null;
4721        }
4722        boolean needRestart = false;
4723        if (app.pid > 0 && app.pid != MY_PID) {
4724            int pid = app.pid;
4725            synchronized (mPidsSelfLocked) {
4726                mPidsSelfLocked.remove(pid);
4727                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4728            }
4729            killUnneededProcessLocked(app, reason);
4730            handleAppDiedLocked(app, true, allowRestart);
4731            removeLruProcessLocked(app);
4732
4733            if (app.persistent && !app.isolated) {
4734                if (!callerWillRestart) {
4735                    addAppLocked(app.info, false);
4736                } else {
4737                    needRestart = true;
4738                }
4739            }
4740        } else {
4741            mRemovedProcesses.add(app);
4742        }
4743
4744        return needRestart;
4745    }
4746
4747    private final void processStartTimedOutLocked(ProcessRecord app) {
4748        final int pid = app.pid;
4749        boolean gone = false;
4750        synchronized (mPidsSelfLocked) {
4751            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4752            if (knownApp != null && knownApp.thread == null) {
4753                mPidsSelfLocked.remove(pid);
4754                gone = true;
4755            }
4756        }
4757
4758        if (gone) {
4759            Slog.w(TAG, "Process " + app + " failed to attach");
4760            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4761                    pid, app.uid, app.processName);
4762            mProcessNames.remove(app.processName, app.uid);
4763            mIsolatedProcesses.remove(app.uid);
4764            if (mHeavyWeightProcess == app) {
4765                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4766                        mHeavyWeightProcess.userId, 0));
4767                mHeavyWeightProcess = null;
4768            }
4769            // Take care of any launching providers waiting for this process.
4770            checkAppInLaunchingProvidersLocked(app, true);
4771            // Take care of any services that are waiting for the process.
4772            mServices.processStartTimedOutLocked(app);
4773            killUnneededProcessLocked(app, "start timeout");
4774            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4775                Slog.w(TAG, "Unattached app died before backup, skipping");
4776                try {
4777                    IBackupManager bm = IBackupManager.Stub.asInterface(
4778                            ServiceManager.getService(Context.BACKUP_SERVICE));
4779                    bm.agentDisconnected(app.info.packageName);
4780                } catch (RemoteException e) {
4781                    // Can't happen; the backup manager is local
4782                }
4783            }
4784            if (isPendingBroadcastProcessLocked(pid)) {
4785                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4786                skipPendingBroadcastLocked(pid);
4787            }
4788        } else {
4789            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4790        }
4791    }
4792
4793    private final boolean attachApplicationLocked(IApplicationThread thread,
4794            int pid) {
4795
4796        // Find the application record that is being attached...  either via
4797        // the pid if we are running in multiple processes, or just pull the
4798        // next app record if we are emulating process with anonymous threads.
4799        ProcessRecord app;
4800        if (pid != MY_PID && pid >= 0) {
4801            synchronized (mPidsSelfLocked) {
4802                app = mPidsSelfLocked.get(pid);
4803            }
4804        } else {
4805            app = null;
4806        }
4807
4808        if (app == null) {
4809            Slog.w(TAG, "No pending application record for pid " + pid
4810                    + " (IApplicationThread " + thread + "); dropping process");
4811            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4812            if (pid > 0 && pid != MY_PID) {
4813                Process.killProcessQuiet(pid);
4814            } else {
4815                try {
4816                    thread.scheduleExit();
4817                } catch (Exception e) {
4818                    // Ignore exceptions.
4819                }
4820            }
4821            return false;
4822        }
4823
4824        // If this application record is still attached to a previous
4825        // process, clean it up now.
4826        if (app.thread != null) {
4827            handleAppDiedLocked(app, true, true);
4828        }
4829
4830        // Tell the process all about itself.
4831
4832        if (localLOGV) Slog.v(
4833                TAG, "Binding process pid " + pid + " to record " + app);
4834
4835        final String processName = app.processName;
4836        try {
4837            AppDeathRecipient adr = new AppDeathRecipient(
4838                    app, pid, thread);
4839            thread.asBinder().linkToDeath(adr, 0);
4840            app.deathRecipient = adr;
4841        } catch (RemoteException e) {
4842            app.resetPackageList(mProcessStats);
4843            startProcessLocked(app, "link fail", processName);
4844            return false;
4845        }
4846
4847        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4848
4849        app.makeActive(thread, mProcessStats);
4850        app.curAdj = app.setAdj = -100;
4851        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4852        app.forcingToForeground = null;
4853        app.foregroundServices = false;
4854        app.hasShownUi = false;
4855        app.debugging = false;
4856        app.cached = false;
4857
4858        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4859
4860        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4861        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4862
4863        if (!normalMode) {
4864            Slog.i(TAG, "Launching preboot mode app: " + app);
4865        }
4866
4867        if (localLOGV) Slog.v(
4868            TAG, "New app record " + app
4869            + " thread=" + thread.asBinder() + " pid=" + pid);
4870        try {
4871            int testMode = IApplicationThread.DEBUG_OFF;
4872            if (mDebugApp != null && mDebugApp.equals(processName)) {
4873                testMode = mWaitForDebugger
4874                    ? IApplicationThread.DEBUG_WAIT
4875                    : IApplicationThread.DEBUG_ON;
4876                app.debugging = true;
4877                if (mDebugTransient) {
4878                    mDebugApp = mOrigDebugApp;
4879                    mWaitForDebugger = mOrigWaitForDebugger;
4880                }
4881            }
4882            String profileFile = app.instrumentationProfileFile;
4883            ParcelFileDescriptor profileFd = null;
4884            boolean profileAutoStop = false;
4885            if (mProfileApp != null && mProfileApp.equals(processName)) {
4886                mProfileProc = app;
4887                profileFile = mProfileFile;
4888                profileFd = mProfileFd;
4889                profileAutoStop = mAutoStopProfiler;
4890            }
4891            boolean enableOpenGlTrace = false;
4892            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4893                enableOpenGlTrace = true;
4894                mOpenGlTraceApp = null;
4895            }
4896
4897            // If the app is being launched for restore or full backup, set it up specially
4898            boolean isRestrictedBackupMode = false;
4899            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4900                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4901                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4902                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4903            }
4904
4905            ensurePackageDexOpt(app.instrumentationInfo != null
4906                    ? app.instrumentationInfo.packageName
4907                    : app.info.packageName);
4908            if (app.instrumentationClass != null) {
4909                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4910            }
4911            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4912                    + processName + " with config " + mConfiguration);
4913            ApplicationInfo appInfo = app.instrumentationInfo != null
4914                    ? app.instrumentationInfo : app.info;
4915            app.compat = compatibilityInfoForPackageLocked(appInfo);
4916            if (profileFd != null) {
4917                profileFd = profileFd.dup();
4918            }
4919            thread.bindApplication(processName, appInfo, providers,
4920                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4921                    app.instrumentationArguments, app.instrumentationWatcher,
4922                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4923                    isRestrictedBackupMode || !normalMode, app.persistent,
4924                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4925                    mCoreSettingsObserver.getCoreSettingsLocked());
4926            updateLruProcessLocked(app, false, null);
4927            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4928        } catch (Exception e) {
4929            // todo: Yikes!  What should we do?  For now we will try to
4930            // start another process, but that could easily get us in
4931            // an infinite loop of restarting processes...
4932            Slog.w(TAG, "Exception thrown during bind!", e);
4933
4934            app.resetPackageList(mProcessStats);
4935            app.unlinkDeathRecipient();
4936            startProcessLocked(app, "bind fail", processName);
4937            return false;
4938        }
4939
4940        // Remove this record from the list of starting applications.
4941        mPersistentStartingProcesses.remove(app);
4942        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4943                "Attach application locked removing on hold: " + app);
4944        mProcessesOnHold.remove(app);
4945
4946        boolean badApp = false;
4947        boolean didSomething = false;
4948
4949        // See if the top visible activity is waiting to run in this process...
4950        if (normalMode) {
4951            try {
4952                if (mStackSupervisor.attachApplicationLocked(app)) {
4953                    didSomething = true;
4954                }
4955            } catch (Exception e) {
4956                badApp = true;
4957            }
4958        }
4959
4960        // Find any services that should be running in this process...
4961        if (!badApp) {
4962            try {
4963                didSomething |= mServices.attachApplicationLocked(app, processName);
4964            } catch (Exception e) {
4965                badApp = true;
4966            }
4967        }
4968
4969        // Check if a next-broadcast receiver is in this process...
4970        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4971            try {
4972                didSomething |= sendPendingBroadcastsLocked(app);
4973            } catch (Exception e) {
4974                // If the app died trying to launch the receiver we declare it 'bad'
4975                badApp = true;
4976            }
4977        }
4978
4979        // Check whether the next backup agent is in this process...
4980        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4981            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4982            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4983            try {
4984                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4985                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4986                        mBackupTarget.backupMode);
4987            } catch (Exception e) {
4988                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4989                e.printStackTrace();
4990            }
4991        }
4992
4993        if (badApp) {
4994            // todo: Also need to kill application to deal with all
4995            // kinds of exceptions.
4996            handleAppDiedLocked(app, false, true);
4997            return false;
4998        }
4999
5000        if (!didSomething) {
5001            updateOomAdjLocked();
5002        }
5003
5004        return true;
5005    }
5006
5007    @Override
5008    public final void attachApplication(IApplicationThread thread) {
5009        synchronized (this) {
5010            int callingPid = Binder.getCallingPid();
5011            final long origId = Binder.clearCallingIdentity();
5012            attachApplicationLocked(thread, callingPid);
5013            Binder.restoreCallingIdentity(origId);
5014        }
5015    }
5016
5017    @Override
5018    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5019        final long origId = Binder.clearCallingIdentity();
5020        synchronized (this) {
5021            ActivityStack stack = ActivityRecord.getStackLocked(token);
5022            if (stack != null) {
5023                ActivityRecord r =
5024                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5025                if (stopProfiling) {
5026                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5027                        try {
5028                            mProfileFd.close();
5029                        } catch (IOException e) {
5030                        }
5031                        clearProfilerLocked();
5032                    }
5033                }
5034            }
5035        }
5036        Binder.restoreCallingIdentity(origId);
5037    }
5038
5039    void enableScreenAfterBoot() {
5040        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5041                SystemClock.uptimeMillis());
5042        mWindowManager.enableScreenAfterBoot();
5043
5044        synchronized (this) {
5045            updateEventDispatchingLocked();
5046        }
5047    }
5048
5049    @Override
5050    public void showBootMessage(final CharSequence msg, final boolean always) {
5051        enforceNotIsolatedCaller("showBootMessage");
5052        mWindowManager.showBootMessage(msg, always);
5053    }
5054
5055    @Override
5056    public void dismissKeyguardOnNextActivity() {
5057        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5058        final long token = Binder.clearCallingIdentity();
5059        try {
5060            synchronized (this) {
5061                if (DEBUG_LOCKSCREEN) logLockScreen("");
5062                if (mLockScreenShown) {
5063                    mLockScreenShown = false;
5064                    comeOutOfSleepIfNeededLocked();
5065                }
5066                mStackSupervisor.setDismissKeyguard(true);
5067            }
5068        } finally {
5069            Binder.restoreCallingIdentity(token);
5070        }
5071    }
5072
5073    final void finishBooting() {
5074        IntentFilter pkgFilter = new IntentFilter();
5075        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5076        pkgFilter.addDataScheme("package");
5077        mContext.registerReceiver(new BroadcastReceiver() {
5078            @Override
5079            public void onReceive(Context context, Intent intent) {
5080                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5081                if (pkgs != null) {
5082                    for (String pkg : pkgs) {
5083                        synchronized (ActivityManagerService.this) {
5084                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
5085                                    "finished booting")) {
5086                                setResultCode(Activity.RESULT_OK);
5087                                return;
5088                            }
5089                        }
5090                    }
5091                }
5092            }
5093        }, pkgFilter);
5094
5095        synchronized (this) {
5096            // Ensure that any processes we had put on hold are now started
5097            // up.
5098            final int NP = mProcessesOnHold.size();
5099            if (NP > 0) {
5100                ArrayList<ProcessRecord> procs =
5101                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5102                for (int ip=0; ip<NP; ip++) {
5103                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5104                            + procs.get(ip));
5105                    startProcessLocked(procs.get(ip), "on-hold", null);
5106                }
5107            }
5108
5109            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5110                // Start looking for apps that are abusing wake locks.
5111                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5112                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5113                // Tell anyone interested that we are done booting!
5114                SystemProperties.set("sys.boot_completed", "1");
5115                SystemProperties.set("dev.bootcomplete", "1");
5116                for (int i=0; i<mStartedUsers.size(); i++) {
5117                    UserStartedState uss = mStartedUsers.valueAt(i);
5118                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5119                        uss.mState = UserStartedState.STATE_RUNNING;
5120                        final int userId = mStartedUsers.keyAt(i);
5121                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5122                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5123                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5124                        broadcastIntentLocked(null, null, intent, null,
5125                                new IIntentReceiver.Stub() {
5126                                    @Override
5127                                    public void performReceive(Intent intent, int resultCode,
5128                                            String data, Bundle extras, boolean ordered,
5129                                            boolean sticky, int sendingUser) {
5130                                        synchronized (ActivityManagerService.this) {
5131                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5132                                                    true, false);
5133                                        }
5134                                    }
5135                                },
5136                                0, null, null,
5137                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5138                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5139                                userId);
5140                    }
5141                }
5142            }
5143        }
5144    }
5145
5146    final void ensureBootCompleted() {
5147        boolean booting;
5148        boolean enableScreen;
5149        synchronized (this) {
5150            booting = mBooting;
5151            mBooting = false;
5152            enableScreen = !mBooted;
5153            mBooted = true;
5154        }
5155
5156        if (booting) {
5157            finishBooting();
5158        }
5159
5160        if (enableScreen) {
5161            enableScreenAfterBoot();
5162        }
5163    }
5164
5165    @Override
5166    public final void activityResumed(IBinder token) {
5167        final long origId = Binder.clearCallingIdentity();
5168        synchronized(this) {
5169            ActivityStack stack = ActivityRecord.getStackLocked(token);
5170            if (stack != null) {
5171                ActivityRecord.activityResumedLocked(token);
5172            }
5173        }
5174        Binder.restoreCallingIdentity(origId);
5175    }
5176
5177    @Override
5178    public final void activityPaused(IBinder token) {
5179        final long origId = Binder.clearCallingIdentity();
5180        synchronized(this) {
5181            ActivityStack stack = ActivityRecord.getStackLocked(token);
5182            if (stack != null) {
5183                stack.activityPausedLocked(token, false);
5184            }
5185        }
5186        Binder.restoreCallingIdentity(origId);
5187    }
5188
5189    @Override
5190    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5191            CharSequence description) {
5192        if (localLOGV) Slog.v(
5193            TAG, "Activity stopped: token=" + token);
5194
5195        // Refuse possible leaked file descriptors
5196        if (icicle != null && icicle.hasFileDescriptors()) {
5197            throw new IllegalArgumentException("File descriptors passed in Bundle");
5198        }
5199
5200        ActivityRecord r = null;
5201
5202        final long origId = Binder.clearCallingIdentity();
5203
5204        synchronized (this) {
5205            r = ActivityRecord.isInStackLocked(token);
5206            if (r != null) {
5207                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5208            }
5209        }
5210
5211        if (r != null) {
5212            sendPendingThumbnail(r, null, null, null, false);
5213        }
5214
5215        trimApplications();
5216
5217        Binder.restoreCallingIdentity(origId);
5218    }
5219
5220    @Override
5221    public final void activityDestroyed(IBinder token) {
5222        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5223        synchronized (this) {
5224            ActivityStack stack = ActivityRecord.getStackLocked(token);
5225            if (stack != null) {
5226                stack.activityDestroyedLocked(token);
5227            }
5228        }
5229    }
5230
5231    @Override
5232    public String getCallingPackage(IBinder token) {
5233        synchronized (this) {
5234            ActivityRecord r = getCallingRecordLocked(token);
5235            return r != null ? r.info.packageName : null;
5236        }
5237    }
5238
5239    @Override
5240    public ComponentName getCallingActivity(IBinder token) {
5241        synchronized (this) {
5242            ActivityRecord r = getCallingRecordLocked(token);
5243            return r != null ? r.intent.getComponent() : null;
5244        }
5245    }
5246
5247    private ActivityRecord getCallingRecordLocked(IBinder token) {
5248        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5249        if (r == null) {
5250            return null;
5251        }
5252        return r.resultTo;
5253    }
5254
5255    @Override
5256    public ComponentName getActivityClassForToken(IBinder token) {
5257        synchronized(this) {
5258            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5259            if (r == null) {
5260                return null;
5261            }
5262            return r.intent.getComponent();
5263        }
5264    }
5265
5266    @Override
5267    public String getPackageForToken(IBinder token) {
5268        synchronized(this) {
5269            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5270            if (r == null) {
5271                return null;
5272            }
5273            return r.packageName;
5274        }
5275    }
5276
5277    @Override
5278    public IIntentSender getIntentSender(int type,
5279            String packageName, IBinder token, String resultWho,
5280            int requestCode, Intent[] intents, String[] resolvedTypes,
5281            int flags, Bundle options, int userId) {
5282        enforceNotIsolatedCaller("getIntentSender");
5283        // Refuse possible leaked file descriptors
5284        if (intents != null) {
5285            if (intents.length < 1) {
5286                throw new IllegalArgumentException("Intents array length must be >= 1");
5287            }
5288            for (int i=0; i<intents.length; i++) {
5289                Intent intent = intents[i];
5290                if (intent != null) {
5291                    if (intent.hasFileDescriptors()) {
5292                        throw new IllegalArgumentException("File descriptors passed in Intent");
5293                    }
5294                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5295                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5296                        throw new IllegalArgumentException(
5297                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5298                    }
5299                    intents[i] = new Intent(intent);
5300                }
5301            }
5302            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5303                throw new IllegalArgumentException(
5304                        "Intent array length does not match resolvedTypes length");
5305            }
5306        }
5307        if (options != null) {
5308            if (options.hasFileDescriptors()) {
5309                throw new IllegalArgumentException("File descriptors passed in options");
5310            }
5311        }
5312
5313        synchronized(this) {
5314            int callingUid = Binder.getCallingUid();
5315            int origUserId = userId;
5316            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5317                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5318                    "getIntentSender", null);
5319            if (origUserId == UserHandle.USER_CURRENT) {
5320                // We don't want to evaluate this until the pending intent is
5321                // actually executed.  However, we do want to always do the
5322                // security checking for it above.
5323                userId = UserHandle.USER_CURRENT;
5324            }
5325            try {
5326                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5327                    int uid = AppGlobals.getPackageManager()
5328                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5329                    if (!UserHandle.isSameApp(callingUid, uid)) {
5330                        String msg = "Permission Denial: getIntentSender() from pid="
5331                            + Binder.getCallingPid()
5332                            + ", uid=" + Binder.getCallingUid()
5333                            + ", (need uid=" + uid + ")"
5334                            + " is not allowed to send as package " + packageName;
5335                        Slog.w(TAG, msg);
5336                        throw new SecurityException(msg);
5337                    }
5338                }
5339
5340                return getIntentSenderLocked(type, packageName, callingUid, userId,
5341                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5342
5343            } catch (RemoteException e) {
5344                throw new SecurityException(e);
5345            }
5346        }
5347    }
5348
5349    IIntentSender getIntentSenderLocked(int type, String packageName,
5350            int callingUid, int userId, IBinder token, String resultWho,
5351            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5352            Bundle options) {
5353        if (DEBUG_MU)
5354            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5355        ActivityRecord activity = null;
5356        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5357            activity = ActivityRecord.isInStackLocked(token);
5358            if (activity == null) {
5359                return null;
5360            }
5361            if (activity.finishing) {
5362                return null;
5363            }
5364        }
5365
5366        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5367        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5368        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5369        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5370                |PendingIntent.FLAG_UPDATE_CURRENT);
5371
5372        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5373                type, packageName, activity, resultWho,
5374                requestCode, intents, resolvedTypes, flags, options, userId);
5375        WeakReference<PendingIntentRecord> ref;
5376        ref = mIntentSenderRecords.get(key);
5377        PendingIntentRecord rec = ref != null ? ref.get() : null;
5378        if (rec != null) {
5379            if (!cancelCurrent) {
5380                if (updateCurrent) {
5381                    if (rec.key.requestIntent != null) {
5382                        rec.key.requestIntent.replaceExtras(intents != null ?
5383                                intents[intents.length - 1] : null);
5384                    }
5385                    if (intents != null) {
5386                        intents[intents.length-1] = rec.key.requestIntent;
5387                        rec.key.allIntents = intents;
5388                        rec.key.allResolvedTypes = resolvedTypes;
5389                    } else {
5390                        rec.key.allIntents = null;
5391                        rec.key.allResolvedTypes = null;
5392                    }
5393                }
5394                return rec;
5395            }
5396            rec.canceled = true;
5397            mIntentSenderRecords.remove(key);
5398        }
5399        if (noCreate) {
5400            return rec;
5401        }
5402        rec = new PendingIntentRecord(this, key, callingUid);
5403        mIntentSenderRecords.put(key, rec.ref);
5404        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5405            if (activity.pendingResults == null) {
5406                activity.pendingResults
5407                        = new HashSet<WeakReference<PendingIntentRecord>>();
5408            }
5409            activity.pendingResults.add(rec.ref);
5410        }
5411        return rec;
5412    }
5413
5414    @Override
5415    public void cancelIntentSender(IIntentSender sender) {
5416        if (!(sender instanceof PendingIntentRecord)) {
5417            return;
5418        }
5419        synchronized(this) {
5420            PendingIntentRecord rec = (PendingIntentRecord)sender;
5421            try {
5422                int uid = AppGlobals.getPackageManager()
5423                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5424                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5425                    String msg = "Permission Denial: cancelIntentSender() from pid="
5426                        + Binder.getCallingPid()
5427                        + ", uid=" + Binder.getCallingUid()
5428                        + " is not allowed to cancel packges "
5429                        + rec.key.packageName;
5430                    Slog.w(TAG, msg);
5431                    throw new SecurityException(msg);
5432                }
5433            } catch (RemoteException e) {
5434                throw new SecurityException(e);
5435            }
5436            cancelIntentSenderLocked(rec, true);
5437        }
5438    }
5439
5440    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5441        rec.canceled = true;
5442        mIntentSenderRecords.remove(rec.key);
5443        if (cleanActivity && rec.key.activity != null) {
5444            rec.key.activity.pendingResults.remove(rec.ref);
5445        }
5446    }
5447
5448    @Override
5449    public String getPackageForIntentSender(IIntentSender pendingResult) {
5450        if (!(pendingResult instanceof PendingIntentRecord)) {
5451            return null;
5452        }
5453        try {
5454            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5455            return res.key.packageName;
5456        } catch (ClassCastException e) {
5457        }
5458        return null;
5459    }
5460
5461    @Override
5462    public int getUidForIntentSender(IIntentSender sender) {
5463        if (sender instanceof PendingIntentRecord) {
5464            try {
5465                PendingIntentRecord res = (PendingIntentRecord)sender;
5466                return res.uid;
5467            } catch (ClassCastException e) {
5468            }
5469        }
5470        return -1;
5471    }
5472
5473    @Override
5474    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5475        if (!(pendingResult instanceof PendingIntentRecord)) {
5476            return false;
5477        }
5478        try {
5479            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5480            if (res.key.allIntents == null) {
5481                return false;
5482            }
5483            for (int i=0; i<res.key.allIntents.length; i++) {
5484                Intent intent = res.key.allIntents[i];
5485                if (intent.getPackage() != null && intent.getComponent() != null) {
5486                    return false;
5487                }
5488            }
5489            return true;
5490        } catch (ClassCastException e) {
5491        }
5492        return false;
5493    }
5494
5495    @Override
5496    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5497        if (!(pendingResult instanceof PendingIntentRecord)) {
5498            return false;
5499        }
5500        try {
5501            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5502            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5503                return true;
5504            }
5505            return false;
5506        } catch (ClassCastException e) {
5507        }
5508        return false;
5509    }
5510
5511    @Override
5512    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5513        if (!(pendingResult instanceof PendingIntentRecord)) {
5514            return null;
5515        }
5516        try {
5517            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5518            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5519        } catch (ClassCastException e) {
5520        }
5521        return null;
5522    }
5523
5524    @Override
5525    public void setProcessLimit(int max) {
5526        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5527                "setProcessLimit()");
5528        synchronized (this) {
5529            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5530            mProcessLimitOverride = max;
5531        }
5532        trimApplications();
5533    }
5534
5535    @Override
5536    public int getProcessLimit() {
5537        synchronized (this) {
5538            return mProcessLimitOverride;
5539        }
5540    }
5541
5542    void foregroundTokenDied(ForegroundToken token) {
5543        synchronized (ActivityManagerService.this) {
5544            synchronized (mPidsSelfLocked) {
5545                ForegroundToken cur
5546                    = mForegroundProcesses.get(token.pid);
5547                if (cur != token) {
5548                    return;
5549                }
5550                mForegroundProcesses.remove(token.pid);
5551                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5552                if (pr == null) {
5553                    return;
5554                }
5555                pr.forcingToForeground = null;
5556                pr.foregroundServices = false;
5557            }
5558            updateOomAdjLocked();
5559        }
5560    }
5561
5562    @Override
5563    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5564        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5565                "setProcessForeground()");
5566        synchronized(this) {
5567            boolean changed = false;
5568
5569            synchronized (mPidsSelfLocked) {
5570                ProcessRecord pr = mPidsSelfLocked.get(pid);
5571                if (pr == null && isForeground) {
5572                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5573                    return;
5574                }
5575                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5576                if (oldToken != null) {
5577                    oldToken.token.unlinkToDeath(oldToken, 0);
5578                    mForegroundProcesses.remove(pid);
5579                    if (pr != null) {
5580                        pr.forcingToForeground = null;
5581                    }
5582                    changed = true;
5583                }
5584                if (isForeground && token != null) {
5585                    ForegroundToken newToken = new ForegroundToken() {
5586                        @Override
5587                        public void binderDied() {
5588                            foregroundTokenDied(this);
5589                        }
5590                    };
5591                    newToken.pid = pid;
5592                    newToken.token = token;
5593                    try {
5594                        token.linkToDeath(newToken, 0);
5595                        mForegroundProcesses.put(pid, newToken);
5596                        pr.forcingToForeground = token;
5597                        changed = true;
5598                    } catch (RemoteException e) {
5599                        // If the process died while doing this, we will later
5600                        // do the cleanup with the process death link.
5601                    }
5602                }
5603            }
5604
5605            if (changed) {
5606                updateOomAdjLocked();
5607            }
5608        }
5609    }
5610
5611    // =========================================================
5612    // PERMISSIONS
5613    // =========================================================
5614
5615    static class PermissionController extends IPermissionController.Stub {
5616        ActivityManagerService mActivityManagerService;
5617        PermissionController(ActivityManagerService activityManagerService) {
5618            mActivityManagerService = activityManagerService;
5619        }
5620
5621        @Override
5622        public boolean checkPermission(String permission, int pid, int uid) {
5623            return mActivityManagerService.checkPermission(permission, pid,
5624                    uid) == PackageManager.PERMISSION_GRANTED;
5625        }
5626    }
5627
5628    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5629        @Override
5630        public int checkComponentPermission(String permission, int pid, int uid,
5631                int owningUid, boolean exported) {
5632            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5633                    owningUid, exported);
5634        }
5635
5636        @Override
5637        public Object getAMSLock() {
5638            return ActivityManagerService.this;
5639        }
5640    }
5641
5642    /**
5643     * This can be called with or without the global lock held.
5644     */
5645    int checkComponentPermission(String permission, int pid, int uid,
5646            int owningUid, boolean exported) {
5647        // We might be performing an operation on behalf of an indirect binder
5648        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5649        // client identity accordingly before proceeding.
5650        Identity tlsIdentity = sCallerIdentity.get();
5651        if (tlsIdentity != null) {
5652            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5653                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5654            uid = tlsIdentity.uid;
5655            pid = tlsIdentity.pid;
5656        }
5657
5658        if (pid == MY_PID) {
5659            return PackageManager.PERMISSION_GRANTED;
5660        }
5661
5662        return ActivityManager.checkComponentPermission(permission, uid,
5663                owningUid, exported);
5664    }
5665
5666    /**
5667     * As the only public entry point for permissions checking, this method
5668     * can enforce the semantic that requesting a check on a null global
5669     * permission is automatically denied.  (Internally a null permission
5670     * string is used when calling {@link #checkComponentPermission} in cases
5671     * when only uid-based security is needed.)
5672     *
5673     * This can be called with or without the global lock held.
5674     */
5675    @Override
5676    public int checkPermission(String permission, int pid, int uid) {
5677        if (permission == null) {
5678            return PackageManager.PERMISSION_DENIED;
5679        }
5680        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5681    }
5682
5683    /**
5684     * Binder IPC calls go through the public entry point.
5685     * This can be called with or without the global lock held.
5686     */
5687    int checkCallingPermission(String permission) {
5688        return checkPermission(permission,
5689                Binder.getCallingPid(),
5690                UserHandle.getAppId(Binder.getCallingUid()));
5691    }
5692
5693    /**
5694     * This can be called with or without the global lock held.
5695     */
5696    void enforceCallingPermission(String permission, String func) {
5697        if (checkCallingPermission(permission)
5698                == PackageManager.PERMISSION_GRANTED) {
5699            return;
5700        }
5701
5702        String msg = "Permission Denial: " + func + " from pid="
5703                + Binder.getCallingPid()
5704                + ", uid=" + Binder.getCallingUid()
5705                + " requires " + permission;
5706        Slog.w(TAG, msg);
5707        throw new SecurityException(msg);
5708    }
5709
5710    /**
5711     * Determine if UID is holding permissions required to access {@link Uri} in
5712     * the given {@link ProviderInfo}. Final permission checking is always done
5713     * in {@link ContentProvider}.
5714     */
5715    private final boolean checkHoldingPermissionsLocked(
5716            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5717        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5718                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5719
5720        if (pi.applicationInfo.uid == uid) {
5721            return true;
5722        } else if (!pi.exported) {
5723            return false;
5724        }
5725
5726        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5727        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5728        try {
5729            // check if target holds top-level <provider> permissions
5730            if (!readMet && pi.readPermission != null
5731                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5732                readMet = true;
5733            }
5734            if (!writeMet && pi.writePermission != null
5735                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5736                writeMet = true;
5737            }
5738
5739            // track if unprotected read/write is allowed; any denied
5740            // <path-permission> below removes this ability
5741            boolean allowDefaultRead = pi.readPermission == null;
5742            boolean allowDefaultWrite = pi.writePermission == null;
5743
5744            // check if target holds any <path-permission> that match uri
5745            final PathPermission[] pps = pi.pathPermissions;
5746            if (pps != null) {
5747                final String path = uri.getPath();
5748                int i = pps.length;
5749                while (i > 0 && (!readMet || !writeMet)) {
5750                    i--;
5751                    PathPermission pp = pps[i];
5752                    if (pp.match(path)) {
5753                        if (!readMet) {
5754                            final String pprperm = pp.getReadPermission();
5755                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5756                                    + pprperm + " for " + pp.getPath()
5757                                    + ": match=" + pp.match(path)
5758                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5759                            if (pprperm != null) {
5760                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5761                                    readMet = true;
5762                                } else {
5763                                    allowDefaultRead = false;
5764                                }
5765                            }
5766                        }
5767                        if (!writeMet) {
5768                            final String ppwperm = pp.getWritePermission();
5769                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5770                                    + ppwperm + " for " + pp.getPath()
5771                                    + ": match=" + pp.match(path)
5772                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5773                            if (ppwperm != null) {
5774                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5775                                    writeMet = true;
5776                                } else {
5777                                    allowDefaultWrite = false;
5778                                }
5779                            }
5780                        }
5781                    }
5782                }
5783            }
5784
5785            // grant unprotected <provider> read/write, if not blocked by
5786            // <path-permission> above
5787            if (allowDefaultRead) readMet = true;
5788            if (allowDefaultWrite) writeMet = true;
5789
5790        } catch (RemoteException e) {
5791            return false;
5792        }
5793
5794        return readMet && writeMet;
5795    }
5796
5797    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5798        ProviderInfo pi = null;
5799        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5800        if (cpr != null) {
5801            pi = cpr.info;
5802        } else {
5803            try {
5804                pi = AppGlobals.getPackageManager().resolveContentProvider(
5805                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5806            } catch (RemoteException ex) {
5807            }
5808        }
5809        return pi;
5810    }
5811
5812    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5813        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5814        if (targetUris != null) {
5815            return targetUris.get(uri);
5816        } else {
5817            return null;
5818        }
5819    }
5820
5821    private UriPermission findOrCreateUriPermissionLocked(
5822            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5823        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5824        if (targetUris == null) {
5825            targetUris = Maps.newArrayMap();
5826            mGrantedUriPermissions.put(targetUid, targetUris);
5827        }
5828
5829        UriPermission perm = targetUris.get(uri);
5830        if (perm == null) {
5831            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5832            targetUris.put(uri, perm);
5833        }
5834
5835        return perm;
5836    }
5837
5838    private final boolean checkUriPermissionLocked(
5839            Uri uri, int uid, int modeFlags, int minStrength) {
5840        // Root gets to do everything.
5841        if (uid == 0) {
5842            return true;
5843        }
5844        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5845        if (perms == null) return false;
5846        UriPermission perm = perms.get(uri);
5847        if (perm == null) return false;
5848        return perm.getStrength(modeFlags) >= minStrength;
5849    }
5850
5851    @Override
5852    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5853        enforceNotIsolatedCaller("checkUriPermission");
5854
5855        // Another redirected-binder-call permissions check as in
5856        // {@link checkComponentPermission}.
5857        Identity tlsIdentity = sCallerIdentity.get();
5858        if (tlsIdentity != null) {
5859            uid = tlsIdentity.uid;
5860            pid = tlsIdentity.pid;
5861        }
5862
5863        // Our own process gets to do everything.
5864        if (pid == MY_PID) {
5865            return PackageManager.PERMISSION_GRANTED;
5866        }
5867        synchronized(this) {
5868            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5869                    ? PackageManager.PERMISSION_GRANTED
5870                    : PackageManager.PERMISSION_DENIED;
5871        }
5872    }
5873
5874    /**
5875     * Check if the targetPkg can be granted permission to access uri by
5876     * the callingUid using the given modeFlags.  Throws a security exception
5877     * if callingUid is not allowed to do this.  Returns the uid of the target
5878     * if the URI permission grant should be performed; returns -1 if it is not
5879     * needed (for example targetPkg already has permission to access the URI).
5880     * If you already know the uid of the target, you can supply it in
5881     * lastTargetUid else set that to -1.
5882     */
5883    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5884            Uri uri, int modeFlags, int lastTargetUid) {
5885        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5886        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5887                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5888        if (modeFlags == 0) {
5889            return -1;
5890        }
5891
5892        if (targetPkg != null) {
5893            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5894                    "Checking grant " + targetPkg + " permission to " + uri);
5895        }
5896
5897        final IPackageManager pm = AppGlobals.getPackageManager();
5898
5899        // If this is not a content: uri, we can't do anything with it.
5900        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5901            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5902                    "Can't grant URI permission for non-content URI: " + uri);
5903            return -1;
5904        }
5905
5906        final String authority = uri.getAuthority();
5907        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5908        if (pi == null) {
5909            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5910            return -1;
5911        }
5912
5913        int targetUid = lastTargetUid;
5914        if (targetUid < 0 && targetPkg != null) {
5915            try {
5916                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5917                if (targetUid < 0) {
5918                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5919                            "Can't grant URI permission no uid for: " + targetPkg);
5920                    return -1;
5921                }
5922            } catch (RemoteException ex) {
5923                return -1;
5924            }
5925        }
5926
5927        if (targetUid >= 0) {
5928            // First...  does the target actually need this permission?
5929            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5930                // No need to grant the target this permission.
5931                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5932                        "Target " + targetPkg + " already has full permission to " + uri);
5933                return -1;
5934            }
5935        } else {
5936            // First...  there is no target package, so can anyone access it?
5937            boolean allowed = pi.exported;
5938            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5939                if (pi.readPermission != null) {
5940                    allowed = false;
5941                }
5942            }
5943            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5944                if (pi.writePermission != null) {
5945                    allowed = false;
5946                }
5947            }
5948            if (allowed) {
5949                return -1;
5950            }
5951        }
5952
5953        // Second...  is the provider allowing granting of URI permissions?
5954        if (!pi.grantUriPermissions) {
5955            throw new SecurityException("Provider " + pi.packageName
5956                    + "/" + pi.name
5957                    + " does not allow granting of Uri permissions (uri "
5958                    + uri + ")");
5959        }
5960        if (pi.uriPermissionPatterns != null) {
5961            final int N = pi.uriPermissionPatterns.length;
5962            boolean allowed = false;
5963            for (int i=0; i<N; i++) {
5964                if (pi.uriPermissionPatterns[i] != null
5965                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5966                    allowed = true;
5967                    break;
5968                }
5969            }
5970            if (!allowed) {
5971                throw new SecurityException("Provider " + pi.packageName
5972                        + "/" + pi.name
5973                        + " does not allow granting of permission to path of Uri "
5974                        + uri);
5975            }
5976        }
5977
5978        // Third...  does the caller itself have permission to access
5979        // this uri?
5980        if (callingUid != Process.myUid()) {
5981            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5982                // Require they hold a strong enough Uri permission
5983                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
5984                        : UriPermission.STRENGTH_OWNED;
5985                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
5986                    throw new SecurityException("Uid " + callingUid
5987                            + " does not have permission to uri " + uri);
5988                }
5989            }
5990        }
5991
5992        return targetUid;
5993    }
5994
5995    @Override
5996    public int checkGrantUriPermission(int callingUid, String targetPkg,
5997            Uri uri, int modeFlags) {
5998        enforceNotIsolatedCaller("checkGrantUriPermission");
5999        synchronized(this) {
6000            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6001        }
6002    }
6003
6004    void grantUriPermissionUncheckedLocked(
6005            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6006        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6007        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6008                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6009        if (modeFlags == 0) {
6010            return;
6011        }
6012
6013        // So here we are: the caller has the assumed permission
6014        // to the uri, and the target doesn't.  Let's now give this to
6015        // the target.
6016
6017        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6018                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6019
6020        final String authority = uri.getAuthority();
6021        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6022        if (pi == null) {
6023            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6024            return;
6025        }
6026
6027        final UriPermission perm = findOrCreateUriPermissionLocked(
6028                pi.packageName, targetPkg, targetUid, uri);
6029        perm.grantModes(modeFlags, persistable, owner);
6030    }
6031
6032    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6033            int modeFlags, UriPermissionOwner owner) {
6034        if (targetPkg == null) {
6035            throw new NullPointerException("targetPkg");
6036        }
6037
6038        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6039        if (targetUid < 0) {
6040            return;
6041        }
6042
6043        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6044    }
6045
6046    static class NeededUriGrants extends ArrayList<Uri> {
6047        final String targetPkg;
6048        final int targetUid;
6049        final int flags;
6050
6051        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6052            this.targetPkg = targetPkg;
6053            this.targetUid = targetUid;
6054            this.flags = flags;
6055        }
6056    }
6057
6058    /**
6059     * Like checkGrantUriPermissionLocked, but takes an Intent.
6060     */
6061    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6062            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6063        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6064                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6065                + " clip=" + (intent != null ? intent.getClipData() : null)
6066                + " from " + intent + "; flags=0x"
6067                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6068
6069        if (targetPkg == null) {
6070            throw new NullPointerException("targetPkg");
6071        }
6072
6073        if (intent == null) {
6074            return null;
6075        }
6076        Uri data = intent.getData();
6077        ClipData clip = intent.getClipData();
6078        if (data == null && clip == null) {
6079            return null;
6080        }
6081
6082        if (data != null) {
6083            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6084                mode, needed != null ? needed.targetUid : -1);
6085            if (targetUid > 0) {
6086                if (needed == null) {
6087                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6088                }
6089                needed.add(data);
6090            }
6091        }
6092        if (clip != null) {
6093            for (int i=0; i<clip.getItemCount(); i++) {
6094                Uri uri = clip.getItemAt(i).getUri();
6095                if (uri != null) {
6096                    int targetUid = -1;
6097                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6098                            mode, needed != null ? needed.targetUid : -1);
6099                    if (targetUid > 0) {
6100                        if (needed == null) {
6101                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6102                        }
6103                        needed.add(uri);
6104                    }
6105                } else {
6106                    Intent clipIntent = clip.getItemAt(i).getIntent();
6107                    if (clipIntent != null) {
6108                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6109                                callingUid, targetPkg, clipIntent, mode, needed);
6110                        if (newNeeded != null) {
6111                            needed = newNeeded;
6112                        }
6113                    }
6114                }
6115            }
6116        }
6117
6118        return needed;
6119    }
6120
6121    /**
6122     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6123     */
6124    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6125            UriPermissionOwner owner) {
6126        if (needed != null) {
6127            for (int i=0; i<needed.size(); i++) {
6128                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6129                        needed.get(i), needed.flags, owner);
6130            }
6131        }
6132    }
6133
6134    void grantUriPermissionFromIntentLocked(int callingUid,
6135            String targetPkg, Intent intent, UriPermissionOwner owner) {
6136        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6137                intent, intent != null ? intent.getFlags() : 0, null);
6138        if (needed == null) {
6139            return;
6140        }
6141
6142        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6143    }
6144
6145    @Override
6146    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6147            Uri uri, int modeFlags) {
6148        enforceNotIsolatedCaller("grantUriPermission");
6149        synchronized(this) {
6150            final ProcessRecord r = getRecordForAppLocked(caller);
6151            if (r == null) {
6152                throw new SecurityException("Unable to find app for caller "
6153                        + caller
6154                        + " when granting permission to uri " + uri);
6155            }
6156            if (targetPkg == null) {
6157                throw new IllegalArgumentException("null target");
6158            }
6159            if (uri == null) {
6160                throw new IllegalArgumentException("null uri");
6161            }
6162
6163            // Persistable only supported through Intents
6164            Preconditions.checkFlagsArgument(modeFlags,
6165                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6166
6167            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6168                    null);
6169        }
6170    }
6171
6172    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6173        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6174                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6175            ArrayMap<Uri, UriPermission> perms
6176                    = mGrantedUriPermissions.get(perm.targetUid);
6177            if (perms != null) {
6178                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6179                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6180                perms.remove(perm.uri);
6181                if (perms.size() == 0) {
6182                    mGrantedUriPermissions.remove(perm.targetUid);
6183                }
6184            }
6185        }
6186    }
6187
6188    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6189        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6190
6191        final IPackageManager pm = AppGlobals.getPackageManager();
6192        final String authority = uri.getAuthority();
6193        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6194        if (pi == null) {
6195            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6196            return;
6197        }
6198
6199        // Does the caller have this permission on the URI?
6200        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6201            // Right now, if you are not the original owner of the permission,
6202            // you are not allowed to revoke it.
6203            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6204                throw new SecurityException("Uid " + callingUid
6205                        + " does not have permission to uri " + uri);
6206            //}
6207        }
6208
6209        boolean persistChanged = false;
6210
6211        // Go through all of the permissions and remove any that match.
6212        final List<String> SEGMENTS = uri.getPathSegments();
6213        if (SEGMENTS != null) {
6214            final int NS = SEGMENTS.size();
6215            int N = mGrantedUriPermissions.size();
6216            for (int i=0; i<N; i++) {
6217                ArrayMap<Uri, UriPermission> perms
6218                        = mGrantedUriPermissions.valueAt(i);
6219                Iterator<UriPermission> it = perms.values().iterator();
6220            toploop:
6221                while (it.hasNext()) {
6222                    UriPermission perm = it.next();
6223                    Uri targetUri = perm.uri;
6224                    if (!authority.equals(targetUri.getAuthority())) {
6225                        continue;
6226                    }
6227                    List<String> targetSegments = targetUri.getPathSegments();
6228                    if (targetSegments == null) {
6229                        continue;
6230                    }
6231                    if (targetSegments.size() < NS) {
6232                        continue;
6233                    }
6234                    for (int j=0; j<NS; j++) {
6235                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6236                            continue toploop;
6237                        }
6238                    }
6239                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6240                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6241                    persistChanged |= perm.clearModes(modeFlags, true);
6242                    if (perm.modeFlags == 0) {
6243                        it.remove();
6244                    }
6245                }
6246                if (perms.size() == 0) {
6247                    mGrantedUriPermissions.remove(
6248                            mGrantedUriPermissions.keyAt(i));
6249                    N--;
6250                    i--;
6251                }
6252            }
6253        }
6254
6255        if (persistChanged) {
6256            schedulePersistUriGrants();
6257        }
6258    }
6259
6260    @Override
6261    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6262            int modeFlags) {
6263        enforceNotIsolatedCaller("revokeUriPermission");
6264        synchronized(this) {
6265            final ProcessRecord r = getRecordForAppLocked(caller);
6266            if (r == null) {
6267                throw new SecurityException("Unable to find app for caller "
6268                        + caller
6269                        + " when revoking permission to uri " + uri);
6270            }
6271            if (uri == null) {
6272                Slog.w(TAG, "revokeUriPermission: null uri");
6273                return;
6274            }
6275
6276            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6277                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6278            if (modeFlags == 0) {
6279                return;
6280            }
6281
6282            final IPackageManager pm = AppGlobals.getPackageManager();
6283            final String authority = uri.getAuthority();
6284            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6285            if (pi == null) {
6286                Slog.w(TAG, "No content provider found for permission revoke: "
6287                        + uri.toSafeString());
6288                return;
6289            }
6290
6291            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6292        }
6293    }
6294
6295    /**
6296     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6297     * given package.
6298     *
6299     * @param packageName Package name to match, or {@code null} to apply to all
6300     *            packages.
6301     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6302     *            to all users.
6303     * @param persistable If persistable grants should be removed.
6304     */
6305    private void removeUriPermissionsForPackageLocked(
6306            String packageName, int userHandle, boolean persistable) {
6307        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6308            throw new IllegalArgumentException("Must narrow by either package or user");
6309        }
6310
6311        boolean persistChanged = false;
6312
6313        final int size = mGrantedUriPermissions.size();
6314        for (int i = 0; i < size; i++) {
6315            // Only inspect grants matching user
6316            if (userHandle == UserHandle.USER_ALL
6317                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6318                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6319                        .values().iterator();
6320                while (it.hasNext()) {
6321                    final UriPermission perm = it.next();
6322
6323                    // Only inspect grants matching package
6324                    if (packageName == null || perm.sourcePkg.equals(packageName)
6325                            || perm.targetPkg.equals(packageName)) {
6326                        persistChanged |= perm.clearModes(~0, persistable);
6327
6328                        // Only remove when no modes remain; any persisted grants
6329                        // will keep this alive.
6330                        if (perm.modeFlags == 0) {
6331                            it.remove();
6332                        }
6333                    }
6334                }
6335            }
6336        }
6337
6338        if (persistChanged) {
6339            schedulePersistUriGrants();
6340        }
6341    }
6342
6343    @Override
6344    public IBinder newUriPermissionOwner(String name) {
6345        enforceNotIsolatedCaller("newUriPermissionOwner");
6346        synchronized(this) {
6347            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6348            return owner.getExternalTokenLocked();
6349        }
6350    }
6351
6352    @Override
6353    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6354            Uri uri, int modeFlags) {
6355        synchronized(this) {
6356            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6357            if (owner == null) {
6358                throw new IllegalArgumentException("Unknown owner: " + token);
6359            }
6360            if (fromUid != Binder.getCallingUid()) {
6361                if (Binder.getCallingUid() != Process.myUid()) {
6362                    // Only system code can grant URI permissions on behalf
6363                    // of other users.
6364                    throw new SecurityException("nice try");
6365                }
6366            }
6367            if (targetPkg == null) {
6368                throw new IllegalArgumentException("null target");
6369            }
6370            if (uri == null) {
6371                throw new IllegalArgumentException("null uri");
6372            }
6373
6374            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6375        }
6376    }
6377
6378    @Override
6379    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6380        synchronized(this) {
6381            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6382            if (owner == null) {
6383                throw new IllegalArgumentException("Unknown owner: " + token);
6384            }
6385
6386            if (uri == null) {
6387                owner.removeUriPermissionsLocked(mode);
6388            } else {
6389                owner.removeUriPermissionLocked(uri, mode);
6390            }
6391        }
6392    }
6393
6394    private void schedulePersistUriGrants() {
6395        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6396            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6397                    10 * DateUtils.SECOND_IN_MILLIS);
6398        }
6399    }
6400
6401    private void writeGrantedUriPermissions() {
6402        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6403
6404        // Snapshot permissions so we can persist without lock
6405        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6406        synchronized (this) {
6407            final int size = mGrantedUriPermissions.size();
6408            for (int i = 0 ; i < size; i++) {
6409                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6410                    if (perm.persistedModeFlags != 0) {
6411                        persist.add(perm.snapshot());
6412                    }
6413                }
6414            }
6415        }
6416
6417        FileOutputStream fos = null;
6418        try {
6419            fos = mGrantFile.startWrite();
6420
6421            XmlSerializer out = new FastXmlSerializer();
6422            out.setOutput(fos, "utf-8");
6423            out.startDocument(null, true);
6424            out.startTag(null, TAG_URI_GRANTS);
6425            for (UriPermission.Snapshot perm : persist) {
6426                out.startTag(null, TAG_URI_GRANT);
6427                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6428                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6429                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6430                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6431                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6432                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6433                out.endTag(null, TAG_URI_GRANT);
6434            }
6435            out.endTag(null, TAG_URI_GRANTS);
6436            out.endDocument();
6437
6438            mGrantFile.finishWrite(fos);
6439        } catch (IOException e) {
6440            if (fos != null) {
6441                mGrantFile.failWrite(fos);
6442            }
6443        }
6444    }
6445
6446    private void readGrantedUriPermissionsLocked() {
6447        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6448
6449        final long now = System.currentTimeMillis();
6450
6451        FileInputStream fis = null;
6452        try {
6453            fis = mGrantFile.openRead();
6454            final XmlPullParser in = Xml.newPullParser();
6455            in.setInput(fis, null);
6456
6457            int type;
6458            while ((type = in.next()) != END_DOCUMENT) {
6459                final String tag = in.getName();
6460                if (type == START_TAG) {
6461                    if (TAG_URI_GRANT.equals(tag)) {
6462                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6463                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6464                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6465                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6466                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6467                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6468
6469                        // Sanity check that provider still belongs to source package
6470                        final ProviderInfo pi = getProviderInfoLocked(
6471                                uri.getAuthority(), userHandle);
6472                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6473                            int targetUid = -1;
6474                            try {
6475                                targetUid = AppGlobals.getPackageManager()
6476                                        .getPackageUid(targetPkg, userHandle);
6477                            } catch (RemoteException e) {
6478                            }
6479                            if (targetUid != -1) {
6480                                final UriPermission perm = findOrCreateUriPermissionLocked(
6481                                        sourcePkg, targetPkg, targetUid, uri);
6482                                perm.initPersistedModes(modeFlags, createdTime);
6483                            }
6484                        } else {
6485                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6486                                    + " but instead found " + pi);
6487                        }
6488                    }
6489                }
6490            }
6491        } catch (FileNotFoundException e) {
6492            // Missing grants is okay
6493        } catch (IOException e) {
6494            Log.wtf(TAG, "Failed reading Uri grants", e);
6495        } catch (XmlPullParserException e) {
6496            Log.wtf(TAG, "Failed reading Uri grants", e);
6497        } finally {
6498            IoUtils.closeQuietly(fis);
6499        }
6500    }
6501
6502    @Override
6503    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6504        enforceNotIsolatedCaller("takePersistableUriPermission");
6505
6506        Preconditions.checkFlagsArgument(modeFlags,
6507                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6508
6509        synchronized (this) {
6510            final int callingUid = Binder.getCallingUid();
6511            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6512            if (perm == null) {
6513                throw new SecurityException("No permission grant found for UID " + callingUid
6514                        + " and Uri " + uri.toSafeString());
6515            }
6516
6517            boolean persistChanged = perm.takePersistableModes(modeFlags);
6518            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6519
6520            if (persistChanged) {
6521                schedulePersistUriGrants();
6522            }
6523        }
6524    }
6525
6526    @Override
6527    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6528        enforceNotIsolatedCaller("releasePersistableUriPermission");
6529
6530        Preconditions.checkFlagsArgument(modeFlags,
6531                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6532
6533        synchronized (this) {
6534            final int callingUid = Binder.getCallingUid();
6535
6536            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6537            if (perm == null) {
6538                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6539                        + uri.toSafeString());
6540                return;
6541            }
6542
6543            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6544            removeUriPermissionIfNeededLocked(perm);
6545            if (persistChanged) {
6546                schedulePersistUriGrants();
6547            }
6548        }
6549    }
6550
6551    /**
6552     * Prune any older {@link UriPermission} for the given UID until outstanding
6553     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6554     *
6555     * @return if any mutations occured that require persisting.
6556     */
6557    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6558        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6559        if (perms == null) return false;
6560        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6561
6562        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6563        for (UriPermission perm : perms.values()) {
6564            if (perm.persistedModeFlags != 0) {
6565                persisted.add(perm);
6566            }
6567        }
6568
6569        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6570        if (trimCount <= 0) return false;
6571
6572        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6573        for (int i = 0; i < trimCount; i++) {
6574            final UriPermission perm = persisted.get(i);
6575
6576            if (DEBUG_URI_PERMISSION) {
6577                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6578            }
6579
6580            perm.releasePersistableModes(~0);
6581            removeUriPermissionIfNeededLocked(perm);
6582        }
6583
6584        return true;
6585    }
6586
6587    @Override
6588    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6589            String packageName, boolean incoming) {
6590        enforceNotIsolatedCaller("getPersistedUriPermissions");
6591        Preconditions.checkNotNull(packageName, "packageName");
6592
6593        final int callingUid = Binder.getCallingUid();
6594        final IPackageManager pm = AppGlobals.getPackageManager();
6595        try {
6596            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6597            if (packageUid != callingUid) {
6598                throw new SecurityException(
6599                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6600            }
6601        } catch (RemoteException e) {
6602            throw new SecurityException("Failed to verify package name ownership");
6603        }
6604
6605        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6606        synchronized (this) {
6607            if (incoming) {
6608                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6609                if (perms == null) {
6610                    Slog.w(TAG, "No permission grants found for " + packageName);
6611                } else {
6612                    final int size = perms.size();
6613                    for (int i = 0; i < size; i++) {
6614                        final UriPermission perm = perms.valueAt(i);
6615                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6616                            result.add(perm.buildPersistedPublicApiObject());
6617                        }
6618                    }
6619                }
6620            } else {
6621                final int size = mGrantedUriPermissions.size();
6622                for (int i = 0; i < size; i++) {
6623                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6624                    final int permsSize = perms.size();
6625                    for (int j = 0; j < permsSize; j++) {
6626                        final UriPermission perm = perms.valueAt(j);
6627                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6628                            result.add(perm.buildPersistedPublicApiObject());
6629                        }
6630                    }
6631                }
6632            }
6633        }
6634        return new ParceledListSlice<android.content.UriPermission>(result);
6635    }
6636
6637    @Override
6638    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6639        synchronized (this) {
6640            ProcessRecord app =
6641                who != null ? getRecordForAppLocked(who) : null;
6642            if (app == null) return;
6643
6644            Message msg = Message.obtain();
6645            msg.what = WAIT_FOR_DEBUGGER_MSG;
6646            msg.obj = app;
6647            msg.arg1 = waiting ? 1 : 0;
6648            mHandler.sendMessage(msg);
6649        }
6650    }
6651
6652    @Override
6653    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6654        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6655        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6656        outInfo.availMem = Process.getFreeMemory();
6657        outInfo.totalMem = Process.getTotalMemory();
6658        outInfo.threshold = homeAppMem;
6659        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6660        outInfo.hiddenAppThreshold = cachedAppMem;
6661        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6662                ProcessList.SERVICE_ADJ);
6663        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6664                ProcessList.VISIBLE_APP_ADJ);
6665        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6666                ProcessList.FOREGROUND_APP_ADJ);
6667    }
6668
6669    // =========================================================
6670    // TASK MANAGEMENT
6671    // =========================================================
6672
6673    @Override
6674    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6675                         IThumbnailReceiver receiver) {
6676        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6677
6678        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6679        ActivityRecord topRecord = null;
6680
6681        synchronized(this) {
6682            if (localLOGV) Slog.v(
6683                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6684                + ", receiver=" + receiver);
6685
6686            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6687                    != PackageManager.PERMISSION_GRANTED) {
6688                if (receiver != null) {
6689                    // If the caller wants to wait for pending thumbnails,
6690                    // it ain't gonna get them.
6691                    try {
6692                        receiver.finished();
6693                    } catch (RemoteException ex) {
6694                    }
6695                }
6696                String msg = "Permission Denial: getTasks() from pid="
6697                        + Binder.getCallingPid()
6698                        + ", uid=" + Binder.getCallingUid()
6699                        + " requires " + android.Manifest.permission.GET_TASKS;
6700                Slog.w(TAG, msg);
6701                throw new SecurityException(msg);
6702            }
6703
6704            // TODO: Improve with MRU list from all ActivityStacks.
6705            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6706
6707            if (!pending.pendingRecords.isEmpty()) {
6708                mPendingThumbnails.add(pending);
6709            }
6710        }
6711
6712        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6713
6714        if (topRecord != null) {
6715            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6716            try {
6717                IApplicationThread topThumbnail = topRecord.app.thread;
6718                topThumbnail.requestThumbnail(topRecord.appToken);
6719            } catch (Exception e) {
6720                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6721                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6722            }
6723        }
6724
6725        if (pending == null && receiver != null) {
6726            // In this case all thumbnails were available and the client
6727            // is being asked to be told when the remaining ones come in...
6728            // which is unusually, since the top-most currently running
6729            // activity should never have a canned thumbnail!  Oh well.
6730            try {
6731                receiver.finished();
6732            } catch (RemoteException ex) {
6733            }
6734        }
6735
6736        return list;
6737    }
6738
6739    TaskRecord getMostRecentTask() {
6740        return mRecentTasks.get(0);
6741    }
6742
6743    @Override
6744    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6745            int flags, int userId) {
6746        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6747                false, true, "getRecentTasks", null);
6748
6749        synchronized (this) {
6750            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6751                    "getRecentTasks()");
6752            final boolean detailed = checkCallingPermission(
6753                    android.Manifest.permission.GET_DETAILED_TASKS)
6754                    == PackageManager.PERMISSION_GRANTED;
6755
6756            IPackageManager pm = AppGlobals.getPackageManager();
6757
6758            final int N = mRecentTasks.size();
6759            ArrayList<ActivityManager.RecentTaskInfo> res
6760                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6761                            maxNum < N ? maxNum : N);
6762            for (int i=0; i<N && maxNum > 0; i++) {
6763                TaskRecord tr = mRecentTasks.get(i);
6764                // Only add calling user's recent tasks
6765                if (tr.userId != userId) continue;
6766                // Return the entry if desired by the caller.  We always return
6767                // the first entry, because callers always expect this to be the
6768                // foreground app.  We may filter others if the caller has
6769                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6770                // we should exclude the entry.
6771
6772                if (i == 0
6773                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6774                        || (tr.intent == null)
6775                        || ((tr.intent.getFlags()
6776                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6777                    ActivityManager.RecentTaskInfo rti
6778                            = new ActivityManager.RecentTaskInfo();
6779                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6780                    rti.persistentId = tr.taskId;
6781                    rti.baseIntent = new Intent(
6782                            tr.intent != null ? tr.intent : tr.affinityIntent);
6783                    if (!detailed) {
6784                        rti.baseIntent.replaceExtras((Bundle)null);
6785                    }
6786                    rti.origActivity = tr.origActivity;
6787                    rti.description = tr.lastDescription;
6788                    rti.stackId = tr.stack.mStackId;
6789
6790                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6791                        // Check whether this activity is currently available.
6792                        try {
6793                            if (rti.origActivity != null) {
6794                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6795                                        == null) {
6796                                    continue;
6797                                }
6798                            } else if (rti.baseIntent != null) {
6799                                if (pm.queryIntentActivities(rti.baseIntent,
6800                                        null, 0, userId) == null) {
6801                                    continue;
6802                                }
6803                            }
6804                        } catch (RemoteException e) {
6805                            // Will never happen.
6806                        }
6807                    }
6808
6809                    res.add(rti);
6810                    maxNum--;
6811                }
6812            }
6813            return res;
6814        }
6815    }
6816
6817    private TaskRecord recentTaskForIdLocked(int id) {
6818        final int N = mRecentTasks.size();
6819            for (int i=0; i<N; i++) {
6820                TaskRecord tr = mRecentTasks.get(i);
6821                if (tr.taskId == id) {
6822                    return tr;
6823                }
6824            }
6825            return null;
6826    }
6827
6828    @Override
6829    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6830        synchronized (this) {
6831            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6832                    "getTaskThumbnails()");
6833            TaskRecord tr = recentTaskForIdLocked(id);
6834            if (tr != null) {
6835                return tr.getTaskThumbnailsLocked();
6836            }
6837        }
6838        return null;
6839    }
6840
6841    @Override
6842    public Bitmap getTaskTopThumbnail(int id) {
6843        synchronized (this) {
6844            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6845                    "getTaskTopThumbnail()");
6846            TaskRecord tr = recentTaskForIdLocked(id);
6847            if (tr != null) {
6848                return tr.getTaskTopThumbnailLocked();
6849            }
6850        }
6851        return null;
6852    }
6853
6854    @Override
6855    public boolean removeSubTask(int taskId, int subTaskIndex) {
6856        synchronized (this) {
6857            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6858                    "removeSubTask()");
6859            long ident = Binder.clearCallingIdentity();
6860            try {
6861                TaskRecord tr = recentTaskForIdLocked(taskId);
6862                if (tr != null) {
6863                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6864                }
6865                return false;
6866            } finally {
6867                Binder.restoreCallingIdentity(ident);
6868            }
6869        }
6870    }
6871
6872    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6873        if (!pr.killedByAm) {
6874            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6875            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6876                    pr.processName, pr.setAdj, reason);
6877            pr.killedByAm = true;
6878            Process.killProcessQuiet(pr.pid);
6879        }
6880    }
6881
6882    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6883        tr.disposeThumbnail();
6884        mRecentTasks.remove(tr);
6885        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6886        Intent baseIntent = new Intent(
6887                tr.intent != null ? tr.intent : tr.affinityIntent);
6888        ComponentName component = baseIntent.getComponent();
6889        if (component == null) {
6890            Slog.w(TAG, "Now component for base intent of task: " + tr);
6891            return;
6892        }
6893
6894        // Find any running services associated with this app.
6895        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6896
6897        if (killProcesses) {
6898            // Find any running processes associated with this app.
6899            final String pkg = component.getPackageName();
6900            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6901            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6902            for (int i=0; i<pmap.size(); i++) {
6903                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6904                for (int j=0; j<uids.size(); j++) {
6905                    ProcessRecord proc = uids.valueAt(j);
6906                    if (proc.userId != tr.userId) {
6907                        continue;
6908                    }
6909                    if (!proc.pkgList.containsKey(pkg)) {
6910                        continue;
6911                    }
6912                    procs.add(proc);
6913                }
6914            }
6915
6916            // Kill the running processes.
6917            for (int i=0; i<procs.size(); i++) {
6918                ProcessRecord pr = procs.get(i);
6919                if (pr == mHomeProcess) {
6920                    // Don't kill the home process along with tasks from the same package.
6921                    continue;
6922                }
6923                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6924                    killUnneededProcessLocked(pr, "remove task");
6925                } else {
6926                    pr.waitingToKill = "remove task";
6927                }
6928            }
6929        }
6930    }
6931
6932    @Override
6933    public boolean removeTask(int taskId, int flags) {
6934        synchronized (this) {
6935            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6936                    "removeTask()");
6937            long ident = Binder.clearCallingIdentity();
6938            try {
6939                TaskRecord tr = recentTaskForIdLocked(taskId);
6940                if (tr != null) {
6941                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6942                    if (r != null) {
6943                        cleanUpRemovedTaskLocked(tr, flags);
6944                        return true;
6945                    }
6946                    if (tr.mActivities.size() == 0) {
6947                        // Caller is just removing a recent task that is
6948                        // not actively running.  That is easy!
6949                        cleanUpRemovedTaskLocked(tr, flags);
6950                        return true;
6951                    }
6952                    Slog.w(TAG, "removeTask: task " + taskId
6953                            + " does not have activities to remove, "
6954                            + " but numActivities=" + tr.numActivities
6955                            + ": " + tr);
6956                }
6957            } finally {
6958                Binder.restoreCallingIdentity(ident);
6959            }
6960        }
6961        return false;
6962    }
6963
6964    /**
6965     * TODO: Add mController hook
6966     */
6967    @Override
6968    public void moveTaskToFront(int task, int flags, Bundle options) {
6969        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6970                "moveTaskToFront()");
6971
6972        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
6973        synchronized(this) {
6974            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6975                    Binder.getCallingUid(), "Task to front")) {
6976                ActivityOptions.abort(options);
6977                return;
6978            }
6979            final long origId = Binder.clearCallingIdentity();
6980            try {
6981                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
6982            } finally {
6983                Binder.restoreCallingIdentity(origId);
6984            }
6985            ActivityOptions.abort(options);
6986        }
6987    }
6988
6989    @Override
6990    public void moveTaskToBack(int taskId) {
6991        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6992                "moveTaskToBack()");
6993
6994        synchronized(this) {
6995            TaskRecord tr = recentTaskForIdLocked(taskId);
6996            if (tr != null) {
6997                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
6998                ActivityStack stack = tr.stack;
6999                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7000                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7001                            Binder.getCallingUid(), "Task to back")) {
7002                        return;
7003                    }
7004                }
7005                final long origId = Binder.clearCallingIdentity();
7006                try {
7007                    stack.moveTaskToBackLocked(taskId, null);
7008                } finally {
7009                    Binder.restoreCallingIdentity(origId);
7010                }
7011            }
7012        }
7013    }
7014
7015    /**
7016     * Moves an activity, and all of the other activities within the same task, to the bottom
7017     * of the history stack.  The activity's order within the task is unchanged.
7018     *
7019     * @param token A reference to the activity we wish to move
7020     * @param nonRoot If false then this only works if the activity is the root
7021     *                of a task; if true it will work for any activity in a task.
7022     * @return Returns true if the move completed, false if not.
7023     */
7024    @Override
7025    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7026        enforceNotIsolatedCaller("moveActivityTaskToBack");
7027        synchronized(this) {
7028            final long origId = Binder.clearCallingIdentity();
7029            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7030            if (taskId >= 0) {
7031                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7032            }
7033            Binder.restoreCallingIdentity(origId);
7034        }
7035        return false;
7036    }
7037
7038    @Override
7039    public void moveTaskBackwards(int task) {
7040        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7041                "moveTaskBackwards()");
7042
7043        synchronized(this) {
7044            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7045                    Binder.getCallingUid(), "Task backwards")) {
7046                return;
7047            }
7048            final long origId = Binder.clearCallingIdentity();
7049            moveTaskBackwardsLocked(task);
7050            Binder.restoreCallingIdentity(origId);
7051        }
7052    }
7053
7054    private final void moveTaskBackwardsLocked(int task) {
7055        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7056    }
7057
7058    @Override
7059    public IBinder getHomeActivityToken() throws RemoteException {
7060        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7061                "getHomeActivityToken()");
7062        synchronized (this) {
7063            return mStackSupervisor.getHomeActivityToken();
7064        }
7065    }
7066
7067    @Override
7068    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7069            IActivityContainerCallback callback) throws RemoteException {
7070        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7071                "createActivityContainer()");
7072        synchronized (this) {
7073            if (parentActivityToken == null) {
7074                throw new IllegalArgumentException("parent token must not be null");
7075            }
7076            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7077            if (r == null) {
7078                return null;
7079            }
7080            return mStackSupervisor.createActivityContainer(r, callback);
7081        }
7082    }
7083
7084    @Override
7085    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7086        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7087                "deleteActivityContainer()");
7088        synchronized (this) {
7089            mStackSupervisor.deleteActivityContainer(container);
7090        }
7091    }
7092
7093    @Override
7094    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7095            throws RemoteException {
7096        synchronized (this) {
7097            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7098            if (stack != null) {
7099                return stack.mActivityContainer;
7100            }
7101            return null;
7102        }
7103    }
7104
7105    @Override
7106    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7107        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7108                "moveTaskToStack()");
7109        if (stackId == HOME_STACK_ID) {
7110            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7111                    new RuntimeException("here").fillInStackTrace());
7112        }
7113        synchronized (this) {
7114            long ident = Binder.clearCallingIdentity();
7115            try {
7116                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7117                        + stackId + " toTop=" + toTop);
7118                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7119            } finally {
7120                Binder.restoreCallingIdentity(ident);
7121            }
7122        }
7123    }
7124
7125    @Override
7126    public void resizeStack(int stackBoxId, Rect bounds) {
7127        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7128                "resizeStackBox()");
7129        long ident = Binder.clearCallingIdentity();
7130        try {
7131            mWindowManager.resizeStack(stackBoxId, bounds);
7132        } finally {
7133            Binder.restoreCallingIdentity(ident);
7134        }
7135    }
7136
7137    @Override
7138    public List<StackInfo> getAllStackInfos() {
7139        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7140                "getAllStackInfos()");
7141        long ident = Binder.clearCallingIdentity();
7142        try {
7143            synchronized (this) {
7144                return mStackSupervisor.getAllStackInfosLocked();
7145            }
7146        } finally {
7147            Binder.restoreCallingIdentity(ident);
7148        }
7149    }
7150
7151    @Override
7152    public StackInfo getStackInfo(int stackId) {
7153        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7154                "getStackInfo()");
7155        long ident = Binder.clearCallingIdentity();
7156        try {
7157            synchronized (this) {
7158                return mStackSupervisor.getStackInfoLocked(stackId);
7159            }
7160        } finally {
7161            Binder.restoreCallingIdentity(ident);
7162        }
7163    }
7164
7165    @Override
7166    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7167        synchronized(this) {
7168            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7169        }
7170    }
7171
7172    // =========================================================
7173    // THUMBNAILS
7174    // =========================================================
7175
7176    public void reportThumbnail(IBinder token,
7177            Bitmap thumbnail, CharSequence description) {
7178        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7179        final long origId = Binder.clearCallingIdentity();
7180        sendPendingThumbnail(null, token, thumbnail, description, true);
7181        Binder.restoreCallingIdentity(origId);
7182    }
7183
7184    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7185            Bitmap thumbnail, CharSequence description, boolean always) {
7186        TaskRecord task;
7187        ArrayList<PendingThumbnailsRecord> receivers = null;
7188
7189        //System.out.println("Send pending thumbnail: " + r);
7190
7191        synchronized(this) {
7192            if (r == null) {
7193                r = ActivityRecord.isInStackLocked(token);
7194                if (r == null) {
7195                    return;
7196                }
7197            }
7198            if (thumbnail == null && r.thumbHolder != null) {
7199                thumbnail = r.thumbHolder.lastThumbnail;
7200                description = r.thumbHolder.lastDescription;
7201            }
7202            if (thumbnail == null && !always) {
7203                // If there is no thumbnail, and this entry is not actually
7204                // going away, then abort for now and pick up the next
7205                // thumbnail we get.
7206                return;
7207            }
7208            task = r.task;
7209
7210            int N = mPendingThumbnails.size();
7211            int i=0;
7212            while (i<N) {
7213                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7214                //System.out.println("Looking in " + pr.pendingRecords);
7215                if (pr.pendingRecords.remove(r)) {
7216                    if (receivers == null) {
7217                        receivers = new ArrayList<PendingThumbnailsRecord>();
7218                    }
7219                    receivers.add(pr);
7220                    if (pr.pendingRecords.size() == 0) {
7221                        pr.finished = true;
7222                        mPendingThumbnails.remove(i);
7223                        N--;
7224                        continue;
7225                    }
7226                }
7227                i++;
7228            }
7229        }
7230
7231        if (receivers != null) {
7232            final int N = receivers.size();
7233            for (int i=0; i<N; i++) {
7234                try {
7235                    PendingThumbnailsRecord pr = receivers.get(i);
7236                    pr.receiver.newThumbnail(
7237                        task != null ? task.taskId : -1, thumbnail, description);
7238                    if (pr.finished) {
7239                        pr.receiver.finished();
7240                    }
7241                } catch (Exception e) {
7242                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7243                }
7244            }
7245        }
7246    }
7247
7248    // =========================================================
7249    // CONTENT PROVIDERS
7250    // =========================================================
7251
7252    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7253        List<ProviderInfo> providers = null;
7254        try {
7255            providers = AppGlobals.getPackageManager().
7256                queryContentProviders(app.processName, app.uid,
7257                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7258        } catch (RemoteException ex) {
7259        }
7260        if (DEBUG_MU)
7261            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7262        int userId = app.userId;
7263        if (providers != null) {
7264            int N = providers.size();
7265            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7266            for (int i=0; i<N; i++) {
7267                ProviderInfo cpi =
7268                    (ProviderInfo)providers.get(i);
7269                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7270                        cpi.name, cpi.flags);
7271                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7272                    // This is a singleton provider, but a user besides the
7273                    // default user is asking to initialize a process it runs
7274                    // in...  well, no, it doesn't actually run in this process,
7275                    // it runs in the process of the default user.  Get rid of it.
7276                    providers.remove(i);
7277                    N--;
7278                    i--;
7279                    continue;
7280                }
7281
7282                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7283                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7284                if (cpr == null) {
7285                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7286                    mProviderMap.putProviderByClass(comp, cpr);
7287                }
7288                if (DEBUG_MU)
7289                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7290                app.pubProviders.put(cpi.name, cpr);
7291                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7292                    // Don't add this if it is a platform component that is marked
7293                    // to run in multiple processes, because this is actually
7294                    // part of the framework so doesn't make sense to track as a
7295                    // separate apk in the process.
7296                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7297                }
7298                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7299            }
7300        }
7301        return providers;
7302    }
7303
7304    /**
7305     * Check if {@link ProcessRecord} has a possible chance at accessing the
7306     * given {@link ProviderInfo}. Final permission checking is always done
7307     * in {@link ContentProvider}.
7308     */
7309    private final String checkContentProviderPermissionLocked(
7310            ProviderInfo cpi, ProcessRecord r) {
7311        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7312        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7313        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7314                cpi.applicationInfo.uid, cpi.exported)
7315                == PackageManager.PERMISSION_GRANTED) {
7316            return null;
7317        }
7318        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7319                cpi.applicationInfo.uid, cpi.exported)
7320                == PackageManager.PERMISSION_GRANTED) {
7321            return null;
7322        }
7323
7324        PathPermission[] pps = cpi.pathPermissions;
7325        if (pps != null) {
7326            int i = pps.length;
7327            while (i > 0) {
7328                i--;
7329                PathPermission pp = pps[i];
7330                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7331                        cpi.applicationInfo.uid, cpi.exported)
7332                        == PackageManager.PERMISSION_GRANTED) {
7333                    return null;
7334                }
7335                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7336                        cpi.applicationInfo.uid, cpi.exported)
7337                        == PackageManager.PERMISSION_GRANTED) {
7338                    return null;
7339                }
7340            }
7341        }
7342
7343        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7344        if (perms != null) {
7345            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7346                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7347                    return null;
7348                }
7349            }
7350        }
7351
7352        String msg;
7353        if (!cpi.exported) {
7354            msg = "Permission Denial: opening provider " + cpi.name
7355                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7356                    + ", uid=" + callingUid + ") that is not exported from uid "
7357                    + cpi.applicationInfo.uid;
7358        } else {
7359            msg = "Permission Denial: opening provider " + cpi.name
7360                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7361                    + ", uid=" + callingUid + ") requires "
7362                    + cpi.readPermission + " or " + cpi.writePermission;
7363        }
7364        Slog.w(TAG, msg);
7365        return msg;
7366    }
7367
7368    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7369            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7370        if (r != null) {
7371            for (int i=0; i<r.conProviders.size(); i++) {
7372                ContentProviderConnection conn = r.conProviders.get(i);
7373                if (conn.provider == cpr) {
7374                    if (DEBUG_PROVIDER) Slog.v(TAG,
7375                            "Adding provider requested by "
7376                            + r.processName + " from process "
7377                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7378                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7379                    if (stable) {
7380                        conn.stableCount++;
7381                        conn.numStableIncs++;
7382                    } else {
7383                        conn.unstableCount++;
7384                        conn.numUnstableIncs++;
7385                    }
7386                    return conn;
7387                }
7388            }
7389            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7390            if (stable) {
7391                conn.stableCount = 1;
7392                conn.numStableIncs = 1;
7393            } else {
7394                conn.unstableCount = 1;
7395                conn.numUnstableIncs = 1;
7396            }
7397            cpr.connections.add(conn);
7398            r.conProviders.add(conn);
7399            return conn;
7400        }
7401        cpr.addExternalProcessHandleLocked(externalProcessToken);
7402        return null;
7403    }
7404
7405    boolean decProviderCountLocked(ContentProviderConnection conn,
7406            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7407        if (conn != null) {
7408            cpr = conn.provider;
7409            if (DEBUG_PROVIDER) Slog.v(TAG,
7410                    "Removing provider requested by "
7411                    + conn.client.processName + " from process "
7412                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7413                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7414            if (stable) {
7415                conn.stableCount--;
7416            } else {
7417                conn.unstableCount--;
7418            }
7419            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7420                cpr.connections.remove(conn);
7421                conn.client.conProviders.remove(conn);
7422                return true;
7423            }
7424            return false;
7425        }
7426        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7427        return false;
7428    }
7429
7430    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7431            String name, IBinder token, boolean stable, int userId) {
7432        ContentProviderRecord cpr;
7433        ContentProviderConnection conn = null;
7434        ProviderInfo cpi = null;
7435
7436        synchronized(this) {
7437            ProcessRecord r = null;
7438            if (caller != null) {
7439                r = getRecordForAppLocked(caller);
7440                if (r == null) {
7441                    throw new SecurityException(
7442                            "Unable to find app for caller " + caller
7443                          + " (pid=" + Binder.getCallingPid()
7444                          + ") when getting content provider " + name);
7445                }
7446            }
7447
7448            // First check if this content provider has been published...
7449            cpr = mProviderMap.getProviderByName(name, userId);
7450            boolean providerRunning = cpr != null;
7451            if (providerRunning) {
7452                cpi = cpr.info;
7453                String msg;
7454                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7455                    throw new SecurityException(msg);
7456                }
7457
7458                if (r != null && cpr.canRunHere(r)) {
7459                    // This provider has been published or is in the process
7460                    // of being published...  but it is also allowed to run
7461                    // in the caller's process, so don't make a connection
7462                    // and just let the caller instantiate its own instance.
7463                    ContentProviderHolder holder = cpr.newHolder(null);
7464                    // don't give caller the provider object, it needs
7465                    // to make its own.
7466                    holder.provider = null;
7467                    return holder;
7468                }
7469
7470                final long origId = Binder.clearCallingIdentity();
7471
7472                // In this case the provider instance already exists, so we can
7473                // return it right away.
7474                conn = incProviderCountLocked(r, cpr, token, stable);
7475                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7476                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7477                        // If this is a perceptible app accessing the provider,
7478                        // make sure to count it as being accessed and thus
7479                        // back up on the LRU list.  This is good because
7480                        // content providers are often expensive to start.
7481                        updateLruProcessLocked(cpr.proc, false, null);
7482                    }
7483                }
7484
7485                if (cpr.proc != null) {
7486                    if (false) {
7487                        if (cpr.name.flattenToShortString().equals(
7488                                "com.android.providers.calendar/.CalendarProvider2")) {
7489                            Slog.v(TAG, "****************** KILLING "
7490                                + cpr.name.flattenToShortString());
7491                            Process.killProcess(cpr.proc.pid);
7492                        }
7493                    }
7494                    boolean success = updateOomAdjLocked(cpr.proc);
7495                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7496                    // NOTE: there is still a race here where a signal could be
7497                    // pending on the process even though we managed to update its
7498                    // adj level.  Not sure what to do about this, but at least
7499                    // the race is now smaller.
7500                    if (!success) {
7501                        // Uh oh...  it looks like the provider's process
7502                        // has been killed on us.  We need to wait for a new
7503                        // process to be started, and make sure its death
7504                        // doesn't kill our process.
7505                        Slog.i(TAG,
7506                                "Existing provider " + cpr.name.flattenToShortString()
7507                                + " is crashing; detaching " + r);
7508                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7509                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7510                        if (!lastRef) {
7511                            // This wasn't the last ref our process had on
7512                            // the provider...  we have now been killed, bail.
7513                            return null;
7514                        }
7515                        providerRunning = false;
7516                        conn = null;
7517                    }
7518                }
7519
7520                Binder.restoreCallingIdentity(origId);
7521            }
7522
7523            boolean singleton;
7524            if (!providerRunning) {
7525                try {
7526                    cpi = AppGlobals.getPackageManager().
7527                        resolveContentProvider(name,
7528                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7529                } catch (RemoteException ex) {
7530                }
7531                if (cpi == null) {
7532                    return null;
7533                }
7534                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7535                        cpi.name, cpi.flags);
7536                if (singleton) {
7537                    userId = 0;
7538                }
7539                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7540
7541                String msg;
7542                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7543                    throw new SecurityException(msg);
7544                }
7545
7546                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7547                        && !cpi.processName.equals("system")) {
7548                    // If this content provider does not run in the system
7549                    // process, and the system is not yet ready to run other
7550                    // processes, then fail fast instead of hanging.
7551                    throw new IllegalArgumentException(
7552                            "Attempt to launch content provider before system ready");
7553                }
7554
7555                // Make sure that the user who owns this provider is started.  If not,
7556                // we don't want to allow it to run.
7557                if (mStartedUsers.get(userId) == null) {
7558                    Slog.w(TAG, "Unable to launch app "
7559                            + cpi.applicationInfo.packageName + "/"
7560                            + cpi.applicationInfo.uid + " for provider "
7561                            + name + ": user " + userId + " is stopped");
7562                    return null;
7563                }
7564
7565                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7566                cpr = mProviderMap.getProviderByClass(comp, userId);
7567                final boolean firstClass = cpr == null;
7568                if (firstClass) {
7569                    try {
7570                        ApplicationInfo ai =
7571                            AppGlobals.getPackageManager().
7572                                getApplicationInfo(
7573                                        cpi.applicationInfo.packageName,
7574                                        STOCK_PM_FLAGS, userId);
7575                        if (ai == null) {
7576                            Slog.w(TAG, "No package info for content provider "
7577                                    + cpi.name);
7578                            return null;
7579                        }
7580                        ai = getAppInfoForUser(ai, userId);
7581                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7582                    } catch (RemoteException ex) {
7583                        // pm is in same process, this will never happen.
7584                    }
7585                }
7586
7587                if (r != null && cpr.canRunHere(r)) {
7588                    // If this is a multiprocess provider, then just return its
7589                    // info and allow the caller to instantiate it.  Only do
7590                    // this if the provider is the same user as the caller's
7591                    // process, or can run as root (so can be in any process).
7592                    return cpr.newHolder(null);
7593                }
7594
7595                if (DEBUG_PROVIDER) {
7596                    RuntimeException e = new RuntimeException("here");
7597                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7598                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7599                }
7600
7601                // This is single process, and our app is now connecting to it.
7602                // See if we are already in the process of launching this
7603                // provider.
7604                final int N = mLaunchingProviders.size();
7605                int i;
7606                for (i=0; i<N; i++) {
7607                    if (mLaunchingProviders.get(i) == cpr) {
7608                        break;
7609                    }
7610                }
7611
7612                // If the provider is not already being launched, then get it
7613                // started.
7614                if (i >= N) {
7615                    final long origId = Binder.clearCallingIdentity();
7616
7617                    try {
7618                        // Content provider is now in use, its package can't be stopped.
7619                        try {
7620                            AppGlobals.getPackageManager().setPackageStoppedState(
7621                                    cpr.appInfo.packageName, false, userId);
7622                        } catch (RemoteException e) {
7623                        } catch (IllegalArgumentException e) {
7624                            Slog.w(TAG, "Failed trying to unstop package "
7625                                    + cpr.appInfo.packageName + ": " + e);
7626                        }
7627
7628                        // Use existing process if already started
7629                        ProcessRecord proc = getProcessRecordLocked(
7630                                cpi.processName, cpr.appInfo.uid, false);
7631                        if (proc != null && proc.thread != null) {
7632                            if (DEBUG_PROVIDER) {
7633                                Slog.d(TAG, "Installing in existing process " + proc);
7634                            }
7635                            proc.pubProviders.put(cpi.name, cpr);
7636                            try {
7637                                proc.thread.scheduleInstallProvider(cpi);
7638                            } catch (RemoteException e) {
7639                            }
7640                        } else {
7641                            proc = startProcessLocked(cpi.processName,
7642                                    cpr.appInfo, false, 0, "content provider",
7643                                    new ComponentName(cpi.applicationInfo.packageName,
7644                                            cpi.name), false, false, false);
7645                            if (proc == null) {
7646                                Slog.w(TAG, "Unable to launch app "
7647                                        + cpi.applicationInfo.packageName + "/"
7648                                        + cpi.applicationInfo.uid + " for provider "
7649                                        + name + ": process is bad");
7650                                return null;
7651                            }
7652                        }
7653                        cpr.launchingApp = proc;
7654                        mLaunchingProviders.add(cpr);
7655                    } finally {
7656                        Binder.restoreCallingIdentity(origId);
7657                    }
7658                }
7659
7660                // Make sure the provider is published (the same provider class
7661                // may be published under multiple names).
7662                if (firstClass) {
7663                    mProviderMap.putProviderByClass(comp, cpr);
7664                }
7665
7666                mProviderMap.putProviderByName(name, cpr);
7667                conn = incProviderCountLocked(r, cpr, token, stable);
7668                if (conn != null) {
7669                    conn.waiting = true;
7670                }
7671            }
7672        }
7673
7674        // Wait for the provider to be published...
7675        synchronized (cpr) {
7676            while (cpr.provider == null) {
7677                if (cpr.launchingApp == null) {
7678                    Slog.w(TAG, "Unable to launch app "
7679                            + cpi.applicationInfo.packageName + "/"
7680                            + cpi.applicationInfo.uid + " for provider "
7681                            + name + ": launching app became null");
7682                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7683                            UserHandle.getUserId(cpi.applicationInfo.uid),
7684                            cpi.applicationInfo.packageName,
7685                            cpi.applicationInfo.uid, name);
7686                    return null;
7687                }
7688                try {
7689                    if (DEBUG_MU) {
7690                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7691                                + cpr.launchingApp);
7692                    }
7693                    if (conn != null) {
7694                        conn.waiting = true;
7695                    }
7696                    cpr.wait();
7697                } catch (InterruptedException ex) {
7698                } finally {
7699                    if (conn != null) {
7700                        conn.waiting = false;
7701                    }
7702                }
7703            }
7704        }
7705        return cpr != null ? cpr.newHolder(conn) : null;
7706    }
7707
7708    public final ContentProviderHolder getContentProvider(
7709            IApplicationThread caller, String name, int userId, boolean stable) {
7710        enforceNotIsolatedCaller("getContentProvider");
7711        if (caller == null) {
7712            String msg = "null IApplicationThread when getting content provider "
7713                    + name;
7714            Slog.w(TAG, msg);
7715            throw new SecurityException(msg);
7716        }
7717
7718        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7719                false, true, "getContentProvider", null);
7720        return getContentProviderImpl(caller, name, null, stable, userId);
7721    }
7722
7723    public ContentProviderHolder getContentProviderExternal(
7724            String name, int userId, IBinder token) {
7725        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7726            "Do not have permission in call getContentProviderExternal()");
7727        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7728                false, true, "getContentProvider", null);
7729        return getContentProviderExternalUnchecked(name, token, userId);
7730    }
7731
7732    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7733            IBinder token, int userId) {
7734        return getContentProviderImpl(null, name, token, true, userId);
7735    }
7736
7737    /**
7738     * Drop a content provider from a ProcessRecord's bookkeeping
7739     */
7740    public void removeContentProvider(IBinder connection, boolean stable) {
7741        enforceNotIsolatedCaller("removeContentProvider");
7742        synchronized (this) {
7743            ContentProviderConnection conn;
7744            try {
7745                conn = (ContentProviderConnection)connection;
7746            } catch (ClassCastException e) {
7747                String msg ="removeContentProvider: " + connection
7748                        + " not a ContentProviderConnection";
7749                Slog.w(TAG, msg);
7750                throw new IllegalArgumentException(msg);
7751            }
7752            if (conn == null) {
7753                throw new NullPointerException("connection is null");
7754            }
7755            if (decProviderCountLocked(conn, null, null, stable)) {
7756                updateOomAdjLocked();
7757            }
7758        }
7759    }
7760
7761    public void removeContentProviderExternal(String name, IBinder token) {
7762        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7763            "Do not have permission in call removeContentProviderExternal()");
7764        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7765    }
7766
7767    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7768        synchronized (this) {
7769            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7770            if(cpr == null) {
7771                //remove from mProvidersByClass
7772                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7773                return;
7774            }
7775
7776            //update content provider record entry info
7777            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7778            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7779            if (localCpr.hasExternalProcessHandles()) {
7780                if (localCpr.removeExternalProcessHandleLocked(token)) {
7781                    updateOomAdjLocked();
7782                } else {
7783                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7784                            + " with no external reference for token: "
7785                            + token + ".");
7786                }
7787            } else {
7788                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7789                        + " with no external references.");
7790            }
7791        }
7792    }
7793
7794    public final void publishContentProviders(IApplicationThread caller,
7795            List<ContentProviderHolder> providers) {
7796        if (providers == null) {
7797            return;
7798        }
7799
7800        enforceNotIsolatedCaller("publishContentProviders");
7801        synchronized (this) {
7802            final ProcessRecord r = getRecordForAppLocked(caller);
7803            if (DEBUG_MU)
7804                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7805            if (r == null) {
7806                throw new SecurityException(
7807                        "Unable to find app for caller " + caller
7808                      + " (pid=" + Binder.getCallingPid()
7809                      + ") when publishing content providers");
7810            }
7811
7812            final long origId = Binder.clearCallingIdentity();
7813
7814            final int N = providers.size();
7815            for (int i=0; i<N; i++) {
7816                ContentProviderHolder src = providers.get(i);
7817                if (src == null || src.info == null || src.provider == null) {
7818                    continue;
7819                }
7820                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7821                if (DEBUG_MU)
7822                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7823                if (dst != null) {
7824                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7825                    mProviderMap.putProviderByClass(comp, dst);
7826                    String names[] = dst.info.authority.split(";");
7827                    for (int j = 0; j < names.length; j++) {
7828                        mProviderMap.putProviderByName(names[j], dst);
7829                    }
7830
7831                    int NL = mLaunchingProviders.size();
7832                    int j;
7833                    for (j=0; j<NL; j++) {
7834                        if (mLaunchingProviders.get(j) == dst) {
7835                            mLaunchingProviders.remove(j);
7836                            j--;
7837                            NL--;
7838                        }
7839                    }
7840                    synchronized (dst) {
7841                        dst.provider = src.provider;
7842                        dst.proc = r;
7843                        dst.notifyAll();
7844                    }
7845                    updateOomAdjLocked(r);
7846                }
7847            }
7848
7849            Binder.restoreCallingIdentity(origId);
7850        }
7851    }
7852
7853    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7854        ContentProviderConnection conn;
7855        try {
7856            conn = (ContentProviderConnection)connection;
7857        } catch (ClassCastException e) {
7858            String msg ="refContentProvider: " + connection
7859                    + " not a ContentProviderConnection";
7860            Slog.w(TAG, msg);
7861            throw new IllegalArgumentException(msg);
7862        }
7863        if (conn == null) {
7864            throw new NullPointerException("connection is null");
7865        }
7866
7867        synchronized (this) {
7868            if (stable > 0) {
7869                conn.numStableIncs += stable;
7870            }
7871            stable = conn.stableCount + stable;
7872            if (stable < 0) {
7873                throw new IllegalStateException("stableCount < 0: " + stable);
7874            }
7875
7876            if (unstable > 0) {
7877                conn.numUnstableIncs += unstable;
7878            }
7879            unstable = conn.unstableCount + unstable;
7880            if (unstable < 0) {
7881                throw new IllegalStateException("unstableCount < 0: " + unstable);
7882            }
7883
7884            if ((stable+unstable) <= 0) {
7885                throw new IllegalStateException("ref counts can't go to zero here: stable="
7886                        + stable + " unstable=" + unstable);
7887            }
7888            conn.stableCount = stable;
7889            conn.unstableCount = unstable;
7890            return !conn.dead;
7891        }
7892    }
7893
7894    public void unstableProviderDied(IBinder connection) {
7895        ContentProviderConnection conn;
7896        try {
7897            conn = (ContentProviderConnection)connection;
7898        } catch (ClassCastException e) {
7899            String msg ="refContentProvider: " + connection
7900                    + " not a ContentProviderConnection";
7901            Slog.w(TAG, msg);
7902            throw new IllegalArgumentException(msg);
7903        }
7904        if (conn == null) {
7905            throw new NullPointerException("connection is null");
7906        }
7907
7908        // Safely retrieve the content provider associated with the connection.
7909        IContentProvider provider;
7910        synchronized (this) {
7911            provider = conn.provider.provider;
7912        }
7913
7914        if (provider == null) {
7915            // Um, yeah, we're way ahead of you.
7916            return;
7917        }
7918
7919        // Make sure the caller is being honest with us.
7920        if (provider.asBinder().pingBinder()) {
7921            // Er, no, still looks good to us.
7922            synchronized (this) {
7923                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7924                        + " says " + conn + " died, but we don't agree");
7925                return;
7926            }
7927        }
7928
7929        // Well look at that!  It's dead!
7930        synchronized (this) {
7931            if (conn.provider.provider != provider) {
7932                // But something changed...  good enough.
7933                return;
7934            }
7935
7936            ProcessRecord proc = conn.provider.proc;
7937            if (proc == null || proc.thread == null) {
7938                // Seems like the process is already cleaned up.
7939                return;
7940            }
7941
7942            // As far as we're concerned, this is just like receiving a
7943            // death notification...  just a bit prematurely.
7944            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7945                    + ") early provider death");
7946            final long ident = Binder.clearCallingIdentity();
7947            try {
7948                appDiedLocked(proc, proc.pid, proc.thread);
7949            } finally {
7950                Binder.restoreCallingIdentity(ident);
7951            }
7952        }
7953    }
7954
7955    @Override
7956    public void appNotRespondingViaProvider(IBinder connection) {
7957        enforceCallingPermission(
7958                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7959
7960        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7961        if (conn == null) {
7962            Slog.w(TAG, "ContentProviderConnection is null");
7963            return;
7964        }
7965
7966        final ProcessRecord host = conn.provider.proc;
7967        if (host == null) {
7968            Slog.w(TAG, "Failed to find hosting ProcessRecord");
7969            return;
7970        }
7971
7972        final long token = Binder.clearCallingIdentity();
7973        try {
7974            appNotResponding(host, null, null, false, "ContentProvider not responding");
7975        } finally {
7976            Binder.restoreCallingIdentity(token);
7977        }
7978    }
7979
7980    public final void installSystemProviders() {
7981        List<ProviderInfo> providers;
7982        synchronized (this) {
7983            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
7984            providers = generateApplicationProvidersLocked(app);
7985            if (providers != null) {
7986                for (int i=providers.size()-1; i>=0; i--) {
7987                    ProviderInfo pi = (ProviderInfo)providers.get(i);
7988                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7989                        Slog.w(TAG, "Not installing system proc provider " + pi.name
7990                                + ": not system .apk");
7991                        providers.remove(i);
7992                    }
7993                }
7994            }
7995        }
7996        if (providers != null) {
7997            mSystemThread.installSystemProviders(providers);
7998        }
7999
8000        mCoreSettingsObserver = new CoreSettingsObserver(this);
8001
8002        mUsageStatsService.monitorPackages();
8003    }
8004
8005    /**
8006     * Allows app to retrieve the MIME type of a URI without having permission
8007     * to access its content provider.
8008     *
8009     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8010     *
8011     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8012     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8013     */
8014    public String getProviderMimeType(Uri uri, int userId) {
8015        enforceNotIsolatedCaller("getProviderMimeType");
8016        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8017                userId, false, true, "getProviderMimeType", null);
8018        final String name = uri.getAuthority();
8019        final long ident = Binder.clearCallingIdentity();
8020        ContentProviderHolder holder = null;
8021
8022        try {
8023            holder = getContentProviderExternalUnchecked(name, null, userId);
8024            if (holder != null) {
8025                return holder.provider.getType(uri);
8026            }
8027        } catch (RemoteException e) {
8028            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8029            return null;
8030        } finally {
8031            if (holder != null) {
8032                removeContentProviderExternalUnchecked(name, null, userId);
8033            }
8034            Binder.restoreCallingIdentity(ident);
8035        }
8036
8037        return null;
8038    }
8039
8040    // =========================================================
8041    // GLOBAL MANAGEMENT
8042    // =========================================================
8043
8044    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8045            boolean isolated) {
8046        String proc = customProcess != null ? customProcess : info.processName;
8047        BatteryStatsImpl.Uid.Proc ps = null;
8048        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8049        int uid = info.uid;
8050        if (isolated) {
8051            int userId = UserHandle.getUserId(uid);
8052            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8053            while (true) {
8054                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8055                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8056                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8057                }
8058                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8059                mNextIsolatedProcessUid++;
8060                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8061                    // No process for this uid, use it.
8062                    break;
8063                }
8064                stepsLeft--;
8065                if (stepsLeft <= 0) {
8066                    return null;
8067                }
8068            }
8069        }
8070        return new ProcessRecord(stats, info, proc, uid);
8071    }
8072
8073    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8074        ProcessRecord app;
8075        if (!isolated) {
8076            app = getProcessRecordLocked(info.processName, info.uid, true);
8077        } else {
8078            app = null;
8079        }
8080
8081        if (app == null) {
8082            app = newProcessRecordLocked(info, null, isolated);
8083            mProcessNames.put(info.processName, app.uid, app);
8084            if (isolated) {
8085                mIsolatedProcesses.put(app.uid, app);
8086            }
8087            updateLruProcessLocked(app, false, null);
8088            updateOomAdjLocked();
8089        }
8090
8091        // This package really, really can not be stopped.
8092        try {
8093            AppGlobals.getPackageManager().setPackageStoppedState(
8094                    info.packageName, false, UserHandle.getUserId(app.uid));
8095        } catch (RemoteException e) {
8096        } catch (IllegalArgumentException e) {
8097            Slog.w(TAG, "Failed trying to unstop package "
8098                    + info.packageName + ": " + e);
8099        }
8100
8101        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8102                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8103            app.persistent = true;
8104            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8105        }
8106        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8107            mPersistentStartingProcesses.add(app);
8108            startProcessLocked(app, "added application", app.processName);
8109        }
8110
8111        return app;
8112    }
8113
8114    public void unhandledBack() {
8115        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8116                "unhandledBack()");
8117
8118        synchronized(this) {
8119            final long origId = Binder.clearCallingIdentity();
8120            try {
8121                getFocusedStack().unhandledBackLocked();
8122            } finally {
8123                Binder.restoreCallingIdentity(origId);
8124            }
8125        }
8126    }
8127
8128    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8129        enforceNotIsolatedCaller("openContentUri");
8130        final int userId = UserHandle.getCallingUserId();
8131        String name = uri.getAuthority();
8132        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8133        ParcelFileDescriptor pfd = null;
8134        if (cph != null) {
8135            // We record the binder invoker's uid in thread-local storage before
8136            // going to the content provider to open the file.  Later, in the code
8137            // that handles all permissions checks, we look for this uid and use
8138            // that rather than the Activity Manager's own uid.  The effect is that
8139            // we do the check against the caller's permissions even though it looks
8140            // to the content provider like the Activity Manager itself is making
8141            // the request.
8142            sCallerIdentity.set(new Identity(
8143                    Binder.getCallingPid(), Binder.getCallingUid()));
8144            try {
8145                pfd = cph.provider.openFile(null, uri, "r", null);
8146            } catch (FileNotFoundException e) {
8147                // do nothing; pfd will be returned null
8148            } finally {
8149                // Ensure that whatever happens, we clean up the identity state
8150                sCallerIdentity.remove();
8151            }
8152
8153            // We've got the fd now, so we're done with the provider.
8154            removeContentProviderExternalUnchecked(name, null, userId);
8155        } else {
8156            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8157        }
8158        return pfd;
8159    }
8160
8161    // Actually is sleeping or shutting down or whatever else in the future
8162    // is an inactive state.
8163    public boolean isSleepingOrShuttingDown() {
8164        return mSleeping || mShuttingDown;
8165    }
8166
8167    public void goingToSleep() {
8168        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8169                != PackageManager.PERMISSION_GRANTED) {
8170            throw new SecurityException("Requires permission "
8171                    + android.Manifest.permission.DEVICE_POWER);
8172        }
8173
8174        synchronized(this) {
8175            mWentToSleep = true;
8176            updateEventDispatchingLocked();
8177
8178            if (!mSleeping) {
8179                mSleeping = true;
8180                mStackSupervisor.goingToSleepLocked();
8181
8182                // Initialize the wake times of all processes.
8183                checkExcessivePowerUsageLocked(false);
8184                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8185                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8186                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8187            }
8188        }
8189    }
8190
8191    @Override
8192    public boolean shutdown(int timeout) {
8193        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8194                != PackageManager.PERMISSION_GRANTED) {
8195            throw new SecurityException("Requires permission "
8196                    + android.Manifest.permission.SHUTDOWN);
8197        }
8198
8199        boolean timedout = false;
8200
8201        synchronized(this) {
8202            mShuttingDown = true;
8203            updateEventDispatchingLocked();
8204            timedout = mStackSupervisor.shutdownLocked(timeout);
8205        }
8206
8207        mAppOpsService.shutdown();
8208        mUsageStatsService.shutdown();
8209        mBatteryStatsService.shutdown();
8210        synchronized (this) {
8211            mProcessStats.shutdownLocked();
8212        }
8213
8214        return timedout;
8215    }
8216
8217    public final void activitySlept(IBinder token) {
8218        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8219
8220        final long origId = Binder.clearCallingIdentity();
8221
8222        synchronized (this) {
8223            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8224            if (r != null) {
8225                mStackSupervisor.activitySleptLocked(r);
8226            }
8227        }
8228
8229        Binder.restoreCallingIdentity(origId);
8230    }
8231
8232    void logLockScreen(String msg) {
8233        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8234                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8235                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8236                mStackSupervisor.mDismissKeyguardOnNextActivity);
8237    }
8238
8239    private void comeOutOfSleepIfNeededLocked() {
8240        if (!mWentToSleep && !mLockScreenShown) {
8241            if (mSleeping) {
8242                mSleeping = false;
8243                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8244            }
8245        }
8246    }
8247
8248    public void wakingUp() {
8249        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8250                != PackageManager.PERMISSION_GRANTED) {
8251            throw new SecurityException("Requires permission "
8252                    + android.Manifest.permission.DEVICE_POWER);
8253        }
8254
8255        synchronized(this) {
8256            mWentToSleep = false;
8257            updateEventDispatchingLocked();
8258            comeOutOfSleepIfNeededLocked();
8259        }
8260    }
8261
8262    private void updateEventDispatchingLocked() {
8263        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8264    }
8265
8266    public void setLockScreenShown(boolean shown) {
8267        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8268                != PackageManager.PERMISSION_GRANTED) {
8269            throw new SecurityException("Requires permission "
8270                    + android.Manifest.permission.DEVICE_POWER);
8271        }
8272
8273        synchronized(this) {
8274            long ident = Binder.clearCallingIdentity();
8275            try {
8276                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8277                mLockScreenShown = shown;
8278                comeOutOfSleepIfNeededLocked();
8279            } finally {
8280                Binder.restoreCallingIdentity(ident);
8281            }
8282        }
8283    }
8284
8285    public void stopAppSwitches() {
8286        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8287                != PackageManager.PERMISSION_GRANTED) {
8288            throw new SecurityException("Requires permission "
8289                    + android.Manifest.permission.STOP_APP_SWITCHES);
8290        }
8291
8292        synchronized(this) {
8293            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8294                    + APP_SWITCH_DELAY_TIME;
8295            mDidAppSwitch = false;
8296            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8297            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8298            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8299        }
8300    }
8301
8302    public void resumeAppSwitches() {
8303        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8304                != PackageManager.PERMISSION_GRANTED) {
8305            throw new SecurityException("Requires permission "
8306                    + android.Manifest.permission.STOP_APP_SWITCHES);
8307        }
8308
8309        synchronized(this) {
8310            // Note that we don't execute any pending app switches... we will
8311            // let those wait until either the timeout, or the next start
8312            // activity request.
8313            mAppSwitchesAllowedTime = 0;
8314        }
8315    }
8316
8317    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8318            String name) {
8319        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8320            return true;
8321        }
8322
8323        final int perm = checkComponentPermission(
8324                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8325                callingUid, -1, true);
8326        if (perm == PackageManager.PERMISSION_GRANTED) {
8327            return true;
8328        }
8329
8330        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8331        return false;
8332    }
8333
8334    public void setDebugApp(String packageName, boolean waitForDebugger,
8335            boolean persistent) {
8336        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8337                "setDebugApp()");
8338
8339        long ident = Binder.clearCallingIdentity();
8340        try {
8341            // Note that this is not really thread safe if there are multiple
8342            // callers into it at the same time, but that's not a situation we
8343            // care about.
8344            if (persistent) {
8345                final ContentResolver resolver = mContext.getContentResolver();
8346                Settings.Global.putString(
8347                    resolver, Settings.Global.DEBUG_APP,
8348                    packageName);
8349                Settings.Global.putInt(
8350                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8351                    waitForDebugger ? 1 : 0);
8352            }
8353
8354            synchronized (this) {
8355                if (!persistent) {
8356                    mOrigDebugApp = mDebugApp;
8357                    mOrigWaitForDebugger = mWaitForDebugger;
8358                }
8359                mDebugApp = packageName;
8360                mWaitForDebugger = waitForDebugger;
8361                mDebugTransient = !persistent;
8362                if (packageName != null) {
8363                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8364                            UserHandle.USER_ALL, "set debug app");
8365                }
8366            }
8367        } finally {
8368            Binder.restoreCallingIdentity(ident);
8369        }
8370    }
8371
8372    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8373        synchronized (this) {
8374            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8375            if (!isDebuggable) {
8376                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8377                    throw new SecurityException("Process not debuggable: " + app.packageName);
8378                }
8379            }
8380
8381            mOpenGlTraceApp = processName;
8382        }
8383    }
8384
8385    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8386            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8387        synchronized (this) {
8388            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8389            if (!isDebuggable) {
8390                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8391                    throw new SecurityException("Process not debuggable: " + app.packageName);
8392                }
8393            }
8394            mProfileApp = processName;
8395            mProfileFile = profileFile;
8396            if (mProfileFd != null) {
8397                try {
8398                    mProfileFd.close();
8399                } catch (IOException e) {
8400                }
8401                mProfileFd = null;
8402            }
8403            mProfileFd = profileFd;
8404            mProfileType = 0;
8405            mAutoStopProfiler = autoStopProfiler;
8406        }
8407    }
8408
8409    @Override
8410    public void setAlwaysFinish(boolean enabled) {
8411        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8412                "setAlwaysFinish()");
8413
8414        Settings.Global.putInt(
8415                mContext.getContentResolver(),
8416                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8417
8418        synchronized (this) {
8419            mAlwaysFinishActivities = enabled;
8420        }
8421    }
8422
8423    @Override
8424    public void setActivityController(IActivityController controller) {
8425        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8426                "setActivityController()");
8427        synchronized (this) {
8428            mController = controller;
8429            Watchdog.getInstance().setActivityController(controller);
8430        }
8431    }
8432
8433    @Override
8434    public void setUserIsMonkey(boolean userIsMonkey) {
8435        synchronized (this) {
8436            synchronized (mPidsSelfLocked) {
8437                final int callingPid = Binder.getCallingPid();
8438                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8439                if (precessRecord == null) {
8440                    throw new SecurityException("Unknown process: " + callingPid);
8441                }
8442                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8443                    throw new SecurityException("Only an instrumentation process "
8444                            + "with a UiAutomation can call setUserIsMonkey");
8445                }
8446            }
8447            mUserIsMonkey = userIsMonkey;
8448        }
8449    }
8450
8451    @Override
8452    public boolean isUserAMonkey() {
8453        synchronized (this) {
8454            // If there is a controller also implies the user is a monkey.
8455            return (mUserIsMonkey || mController != null);
8456        }
8457    }
8458
8459    public void requestBugReport() {
8460        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8461        SystemProperties.set("ctl.start", "bugreport");
8462    }
8463
8464    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8465        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8466    }
8467
8468    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8469        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8470            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8471        }
8472        return KEY_DISPATCHING_TIMEOUT;
8473    }
8474
8475    @Override
8476    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8477        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8478                != PackageManager.PERMISSION_GRANTED) {
8479            throw new SecurityException("Requires permission "
8480                    + android.Manifest.permission.FILTER_EVENTS);
8481        }
8482        ProcessRecord proc;
8483        long timeout;
8484        synchronized (this) {
8485            synchronized (mPidsSelfLocked) {
8486                proc = mPidsSelfLocked.get(pid);
8487            }
8488            timeout = getInputDispatchingTimeoutLocked(proc);
8489        }
8490
8491        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8492            return -1;
8493        }
8494
8495        return timeout;
8496    }
8497
8498    /**
8499     * Handle input dispatching timeouts.
8500     * Returns whether input dispatching should be aborted or not.
8501     */
8502    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8503            final ActivityRecord activity, final ActivityRecord parent,
8504            final boolean aboveSystem, String reason) {
8505        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8506                != PackageManager.PERMISSION_GRANTED) {
8507            throw new SecurityException("Requires permission "
8508                    + android.Manifest.permission.FILTER_EVENTS);
8509        }
8510
8511        final String annotation;
8512        if (reason == null) {
8513            annotation = "Input dispatching timed out";
8514        } else {
8515            annotation = "Input dispatching timed out (" + reason + ")";
8516        }
8517
8518        if (proc != null) {
8519            synchronized (this) {
8520                if (proc.debugging) {
8521                    return false;
8522                }
8523
8524                if (mDidDexOpt) {
8525                    // Give more time since we were dexopting.
8526                    mDidDexOpt = false;
8527                    return false;
8528                }
8529
8530                if (proc.instrumentationClass != null) {
8531                    Bundle info = new Bundle();
8532                    info.putString("shortMsg", "keyDispatchingTimedOut");
8533                    info.putString("longMsg", annotation);
8534                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8535                    return true;
8536                }
8537            }
8538            mHandler.post(new Runnable() {
8539                @Override
8540                public void run() {
8541                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8542                }
8543            });
8544        }
8545
8546        return true;
8547    }
8548
8549    public Bundle getAssistContextExtras(int requestType) {
8550        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8551                "getAssistContextExtras()");
8552        PendingAssistExtras pae;
8553        Bundle extras = new Bundle();
8554        synchronized (this) {
8555            ActivityRecord activity = getFocusedStack().mResumedActivity;
8556            if (activity == null) {
8557                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8558                return null;
8559            }
8560            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8561            if (activity.app == null || activity.app.thread == null) {
8562                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8563                return extras;
8564            }
8565            if (activity.app.pid == Binder.getCallingPid()) {
8566                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8567                return extras;
8568            }
8569            pae = new PendingAssistExtras(activity);
8570            try {
8571                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8572                        requestType);
8573                mPendingAssistExtras.add(pae);
8574                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8575            } catch (RemoteException e) {
8576                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8577                return extras;
8578            }
8579        }
8580        synchronized (pae) {
8581            while (!pae.haveResult) {
8582                try {
8583                    pae.wait();
8584                } catch (InterruptedException e) {
8585                }
8586            }
8587            if (pae.result != null) {
8588                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8589            }
8590        }
8591        synchronized (this) {
8592            mPendingAssistExtras.remove(pae);
8593            mHandler.removeCallbacks(pae);
8594        }
8595        return extras;
8596    }
8597
8598    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8599        PendingAssistExtras pae = (PendingAssistExtras)token;
8600        synchronized (pae) {
8601            pae.result = extras;
8602            pae.haveResult = true;
8603            pae.notifyAll();
8604        }
8605    }
8606
8607    public void registerProcessObserver(IProcessObserver observer) {
8608        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8609                "registerProcessObserver()");
8610        synchronized (this) {
8611            mProcessObservers.register(observer);
8612        }
8613    }
8614
8615    @Override
8616    public void unregisterProcessObserver(IProcessObserver observer) {
8617        synchronized (this) {
8618            mProcessObservers.unregister(observer);
8619        }
8620    }
8621
8622    @Override
8623    public boolean convertFromTranslucent(IBinder token) {
8624        final long origId = Binder.clearCallingIdentity();
8625        try {
8626            synchronized (this) {
8627                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8628                if (r == null) {
8629                    return false;
8630                }
8631                if (r.changeWindowTranslucency(true)) {
8632                    mWindowManager.setAppFullscreen(token, true);
8633                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8634                    return true;
8635                }
8636                return false;
8637            }
8638        } finally {
8639            Binder.restoreCallingIdentity(origId);
8640        }
8641    }
8642
8643    @Override
8644    public boolean convertToTranslucent(IBinder token) {
8645        final long origId = Binder.clearCallingIdentity();
8646        try {
8647            synchronized (this) {
8648                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8649                if (r == null) {
8650                    return false;
8651                }
8652                if (r.changeWindowTranslucency(false)) {
8653                    r.task.stack.convertToTranslucent(r);
8654                    mWindowManager.setAppFullscreen(token, false);
8655                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8656                    return true;
8657                }
8658                return false;
8659            }
8660        } finally {
8661            Binder.restoreCallingIdentity(origId);
8662        }
8663    }
8664
8665    @Override
8666    public void setImmersive(IBinder token, boolean immersive) {
8667        synchronized(this) {
8668            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8669            if (r == null) {
8670                throw new IllegalArgumentException();
8671            }
8672            r.immersive = immersive;
8673
8674            // update associated state if we're frontmost
8675            if (r == mFocusedActivity) {
8676                if (DEBUG_IMMERSIVE) {
8677                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8678                }
8679                applyUpdateLockStateLocked(r);
8680            }
8681        }
8682    }
8683
8684    @Override
8685    public boolean isImmersive(IBinder token) {
8686        synchronized (this) {
8687            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8688            if (r == null) {
8689                throw new IllegalArgumentException();
8690            }
8691            return r.immersive;
8692        }
8693    }
8694
8695    public boolean isTopActivityImmersive() {
8696        enforceNotIsolatedCaller("startActivity");
8697        synchronized (this) {
8698            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8699            return (r != null) ? r.immersive : false;
8700        }
8701    }
8702
8703    public final void enterSafeMode() {
8704        synchronized(this) {
8705            // It only makes sense to do this before the system is ready
8706            // and started launching other packages.
8707            if (!mSystemReady) {
8708                try {
8709                    AppGlobals.getPackageManager().enterSafeMode();
8710                } catch (RemoteException e) {
8711                }
8712            }
8713        }
8714    }
8715
8716    public final void showSafeModeOverlay() {
8717        View v = LayoutInflater.from(mContext).inflate(
8718                com.android.internal.R.layout.safe_mode, null);
8719        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8720        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8721        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8722        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8723        lp.gravity = Gravity.BOTTOM | Gravity.START;
8724        lp.format = v.getBackground().getOpacity();
8725        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8726                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8727        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8728        ((WindowManager)mContext.getSystemService(
8729                Context.WINDOW_SERVICE)).addView(v, lp);
8730    }
8731
8732    public void noteWakeupAlarm(IIntentSender sender) {
8733        if (!(sender instanceof PendingIntentRecord)) {
8734            return;
8735        }
8736        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8737        synchronized (stats) {
8738            if (mBatteryStatsService.isOnBattery()) {
8739                mBatteryStatsService.enforceCallingPermission();
8740                PendingIntentRecord rec = (PendingIntentRecord)sender;
8741                int MY_UID = Binder.getCallingUid();
8742                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8743                BatteryStatsImpl.Uid.Pkg pkg =
8744                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8745                pkg.incWakeupsLocked();
8746            }
8747        }
8748    }
8749
8750    public boolean killPids(int[] pids, String pReason, boolean secure) {
8751        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8752            throw new SecurityException("killPids only available to the system");
8753        }
8754        String reason = (pReason == null) ? "Unknown" : pReason;
8755        // XXX Note: don't acquire main activity lock here, because the window
8756        // manager calls in with its locks held.
8757
8758        boolean killed = false;
8759        synchronized (mPidsSelfLocked) {
8760            int[] types = new int[pids.length];
8761            int worstType = 0;
8762            for (int i=0; i<pids.length; i++) {
8763                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8764                if (proc != null) {
8765                    int type = proc.setAdj;
8766                    types[i] = type;
8767                    if (type > worstType) {
8768                        worstType = type;
8769                    }
8770                }
8771            }
8772
8773            // If the worst oom_adj is somewhere in the cached proc LRU range,
8774            // then constrain it so we will kill all cached procs.
8775            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8776                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8777                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8778            }
8779
8780            // If this is not a secure call, don't let it kill processes that
8781            // are important.
8782            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8783                worstType = ProcessList.SERVICE_ADJ;
8784            }
8785
8786            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8787            for (int i=0; i<pids.length; i++) {
8788                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8789                if (proc == null) {
8790                    continue;
8791                }
8792                int adj = proc.setAdj;
8793                if (adj >= worstType && !proc.killedByAm) {
8794                    killUnneededProcessLocked(proc, reason);
8795                    killed = true;
8796                }
8797            }
8798        }
8799        return killed;
8800    }
8801
8802    @Override
8803    public void killUid(int uid, String reason) {
8804        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8805            throw new SecurityException("killUid only available to the system");
8806        }
8807        synchronized (this) {
8808            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8809                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8810                    reason != null ? reason : "kill uid");
8811        }
8812    }
8813
8814    @Override
8815    public boolean killProcessesBelowForeground(String reason) {
8816        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8817            throw new SecurityException("killProcessesBelowForeground() only available to system");
8818        }
8819
8820        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8821    }
8822
8823    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8824        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8825            throw new SecurityException("killProcessesBelowAdj() only available to system");
8826        }
8827
8828        boolean killed = false;
8829        synchronized (mPidsSelfLocked) {
8830            final int size = mPidsSelfLocked.size();
8831            for (int i = 0; i < size; i++) {
8832                final int pid = mPidsSelfLocked.keyAt(i);
8833                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8834                if (proc == null) continue;
8835
8836                final int adj = proc.setAdj;
8837                if (adj > belowAdj && !proc.killedByAm) {
8838                    killUnneededProcessLocked(proc, reason);
8839                    killed = true;
8840                }
8841            }
8842        }
8843        return killed;
8844    }
8845
8846    @Override
8847    public void hang(final IBinder who, boolean allowRestart) {
8848        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8849                != PackageManager.PERMISSION_GRANTED) {
8850            throw new SecurityException("Requires permission "
8851                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8852        }
8853
8854        final IBinder.DeathRecipient death = new DeathRecipient() {
8855            @Override
8856            public void binderDied() {
8857                synchronized (this) {
8858                    notifyAll();
8859                }
8860            }
8861        };
8862
8863        try {
8864            who.linkToDeath(death, 0);
8865        } catch (RemoteException e) {
8866            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8867            return;
8868        }
8869
8870        synchronized (this) {
8871            Watchdog.getInstance().setAllowRestart(allowRestart);
8872            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8873            synchronized (death) {
8874                while (who.isBinderAlive()) {
8875                    try {
8876                        death.wait();
8877                    } catch (InterruptedException e) {
8878                    }
8879                }
8880            }
8881            Watchdog.getInstance().setAllowRestart(true);
8882        }
8883    }
8884
8885    @Override
8886    public void restart() {
8887        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8888                != PackageManager.PERMISSION_GRANTED) {
8889            throw new SecurityException("Requires permission "
8890                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8891        }
8892
8893        Log.i(TAG, "Sending shutdown broadcast...");
8894
8895        BroadcastReceiver br = new BroadcastReceiver() {
8896            @Override public void onReceive(Context context, Intent intent) {
8897                // Now the broadcast is done, finish up the low-level shutdown.
8898                Log.i(TAG, "Shutting down activity manager...");
8899                shutdown(10000);
8900                Log.i(TAG, "Shutdown complete, restarting!");
8901                Process.killProcess(Process.myPid());
8902                System.exit(10);
8903            }
8904        };
8905
8906        // First send the high-level shut down broadcast.
8907        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8908        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8909        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8910        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8911        mContext.sendOrderedBroadcastAsUser(intent,
8912                UserHandle.ALL, null, br, mHandler, 0, null, null);
8913        */
8914        br.onReceive(mContext, intent);
8915    }
8916
8917    private long getLowRamTimeSinceIdle(long now) {
8918        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8919    }
8920
8921    @Override
8922    public void performIdleMaintenance() {
8923        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8924                != PackageManager.PERMISSION_GRANTED) {
8925            throw new SecurityException("Requires permission "
8926                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8927        }
8928
8929        synchronized (this) {
8930            final long now = SystemClock.uptimeMillis();
8931            final long timeSinceLastIdle = now - mLastIdleTime;
8932            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8933            mLastIdleTime = now;
8934            mLowRamTimeSinceLastIdle = 0;
8935            if (mLowRamStartTime != 0) {
8936                mLowRamStartTime = now;
8937            }
8938
8939            StringBuilder sb = new StringBuilder(128);
8940            sb.append("Idle maintenance over ");
8941            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8942            sb.append(" low RAM for ");
8943            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8944            Slog.i(TAG, sb.toString());
8945
8946            // If at least 1/3 of our time since the last idle period has been spent
8947            // with RAM low, then we want to kill processes.
8948            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8949
8950            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8951                ProcessRecord proc = mLruProcesses.get(i);
8952                if (proc.notCachedSinceIdle) {
8953                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8954                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8955                        if (doKilling && proc.initialIdlePss != 0
8956                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8957                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8958                                    + " from " + proc.initialIdlePss + ")");
8959                        }
8960                    }
8961                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8962                    proc.notCachedSinceIdle = true;
8963                    proc.initialIdlePss = 0;
8964                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8965                            mSleeping, now);
8966                }
8967            }
8968
8969            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8970            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8971        }
8972    }
8973
8974    public final void startRunning(String pkg, String cls, String action,
8975            String data) {
8976        synchronized(this) {
8977            if (mStartRunning) {
8978                return;
8979            }
8980            mStartRunning = true;
8981            mTopComponent = pkg != null && cls != null
8982                    ? new ComponentName(pkg, cls) : null;
8983            mTopAction = action != null ? action : Intent.ACTION_MAIN;
8984            mTopData = data;
8985            if (!mSystemReady) {
8986                return;
8987            }
8988        }
8989
8990        systemReady(null);
8991    }
8992
8993    private void retrieveSettings() {
8994        final ContentResolver resolver = mContext.getContentResolver();
8995        String debugApp = Settings.Global.getString(
8996            resolver, Settings.Global.DEBUG_APP);
8997        boolean waitForDebugger = Settings.Global.getInt(
8998            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
8999        boolean alwaysFinishActivities = Settings.Global.getInt(
9000            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9001        boolean forceRtl = Settings.Global.getInt(
9002                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9003        // Transfer any global setting for forcing RTL layout, into a System Property
9004        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9005
9006        Configuration configuration = new Configuration();
9007        Settings.System.getConfiguration(resolver, configuration);
9008        if (forceRtl) {
9009            // This will take care of setting the correct layout direction flags
9010            configuration.setLayoutDirection(configuration.locale);
9011        }
9012
9013        synchronized (this) {
9014            mDebugApp = mOrigDebugApp = debugApp;
9015            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9016            mAlwaysFinishActivities = alwaysFinishActivities;
9017            // This happens before any activities are started, so we can
9018            // change mConfiguration in-place.
9019            updateConfigurationLocked(configuration, null, false, true);
9020            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9021        }
9022    }
9023
9024    public boolean testIsSystemReady() {
9025        // no need to synchronize(this) just to read & return the value
9026        return mSystemReady;
9027    }
9028
9029    private static File getCalledPreBootReceiversFile() {
9030        File dataDir = Environment.getDataDirectory();
9031        File systemDir = new File(dataDir, "system");
9032        File fname = new File(systemDir, "called_pre_boots.dat");
9033        return fname;
9034    }
9035
9036    static final int LAST_DONE_VERSION = 10000;
9037
9038    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9039        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9040        File file = getCalledPreBootReceiversFile();
9041        FileInputStream fis = null;
9042        try {
9043            fis = new FileInputStream(file);
9044            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9045            int fvers = dis.readInt();
9046            if (fvers == LAST_DONE_VERSION) {
9047                String vers = dis.readUTF();
9048                String codename = dis.readUTF();
9049                String build = dis.readUTF();
9050                if (android.os.Build.VERSION.RELEASE.equals(vers)
9051                        && android.os.Build.VERSION.CODENAME.equals(codename)
9052                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9053                    int num = dis.readInt();
9054                    while (num > 0) {
9055                        num--;
9056                        String pkg = dis.readUTF();
9057                        String cls = dis.readUTF();
9058                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9059                    }
9060                }
9061            }
9062        } catch (FileNotFoundException e) {
9063        } catch (IOException e) {
9064            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9065        } finally {
9066            if (fis != null) {
9067                try {
9068                    fis.close();
9069                } catch (IOException e) {
9070                }
9071            }
9072        }
9073        return lastDoneReceivers;
9074    }
9075
9076    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9077        File file = getCalledPreBootReceiversFile();
9078        FileOutputStream fos = null;
9079        DataOutputStream dos = null;
9080        try {
9081            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9082            fos = new FileOutputStream(file);
9083            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9084            dos.writeInt(LAST_DONE_VERSION);
9085            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9086            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9087            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9088            dos.writeInt(list.size());
9089            for (int i=0; i<list.size(); i++) {
9090                dos.writeUTF(list.get(i).getPackageName());
9091                dos.writeUTF(list.get(i).getClassName());
9092            }
9093        } catch (IOException e) {
9094            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9095            file.delete();
9096        } finally {
9097            FileUtils.sync(fos);
9098            if (dos != null) {
9099                try {
9100                    dos.close();
9101                } catch (IOException e) {
9102                    // TODO Auto-generated catch block
9103                    e.printStackTrace();
9104                }
9105            }
9106        }
9107    }
9108
9109    public void systemReady(final Runnable goingCallback) {
9110        synchronized(this) {
9111            if (mSystemReady) {
9112                if (goingCallback != null) goingCallback.run();
9113                return;
9114            }
9115
9116            // Check to see if there are any update receivers to run.
9117            if (!mDidUpdate) {
9118                if (mWaitingUpdate) {
9119                    return;
9120                }
9121                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9122                List<ResolveInfo> ris = null;
9123                try {
9124                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9125                            intent, null, 0, 0);
9126                } catch (RemoteException e) {
9127                }
9128                if (ris != null) {
9129                    for (int i=ris.size()-1; i>=0; i--) {
9130                        if ((ris.get(i).activityInfo.applicationInfo.flags
9131                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9132                            ris.remove(i);
9133                        }
9134                    }
9135                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9136
9137                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9138
9139                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9140                    for (int i=0; i<ris.size(); i++) {
9141                        ActivityInfo ai = ris.get(i).activityInfo;
9142                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9143                        if (lastDoneReceivers.contains(comp)) {
9144                            ris.remove(i);
9145                            i--;
9146                        }
9147                    }
9148
9149                    final int[] users = getUsersLocked();
9150                    for (int i=0; i<ris.size(); i++) {
9151                        ActivityInfo ai = ris.get(i).activityInfo;
9152                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9153                        doneReceivers.add(comp);
9154                        intent.setComponent(comp);
9155                        for (int j=0; j<users.length; j++) {
9156                            IIntentReceiver finisher = null;
9157                            if (i == ris.size()-1 && j == users.length-1) {
9158                                finisher = new IIntentReceiver.Stub() {
9159                                    public void performReceive(Intent intent, int resultCode,
9160                                            String data, Bundle extras, boolean ordered,
9161                                            boolean sticky, int sendingUser) {
9162                                        // The raw IIntentReceiver interface is called
9163                                        // with the AM lock held, so redispatch to
9164                                        // execute our code without the lock.
9165                                        mHandler.post(new Runnable() {
9166                                            public void run() {
9167                                                synchronized (ActivityManagerService.this) {
9168                                                    mDidUpdate = true;
9169                                                }
9170                                                writeLastDonePreBootReceivers(doneReceivers);
9171                                                showBootMessage(mContext.getText(
9172                                                        R.string.android_upgrading_complete),
9173                                                        false);
9174                                                systemReady(goingCallback);
9175                                            }
9176                                        });
9177                                    }
9178                                };
9179                            }
9180                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9181                                    + " for user " + users[j]);
9182                            broadcastIntentLocked(null, null, intent, null, finisher,
9183                                    0, null, null, null, AppOpsManager.OP_NONE,
9184                                    true, false, MY_PID, Process.SYSTEM_UID,
9185                                    users[j]);
9186                            if (finisher != null) {
9187                                mWaitingUpdate = true;
9188                            }
9189                        }
9190                    }
9191                }
9192                if (mWaitingUpdate) {
9193                    return;
9194                }
9195                mDidUpdate = true;
9196            }
9197
9198            mAppOpsService.systemReady();
9199            mSystemReady = true;
9200            if (!mStartRunning) {
9201                return;
9202            }
9203        }
9204
9205        ArrayList<ProcessRecord> procsToKill = null;
9206        synchronized(mPidsSelfLocked) {
9207            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9208                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9209                if (!isAllowedWhileBooting(proc.info)){
9210                    if (procsToKill == null) {
9211                        procsToKill = new ArrayList<ProcessRecord>();
9212                    }
9213                    procsToKill.add(proc);
9214                }
9215            }
9216        }
9217
9218        synchronized(this) {
9219            if (procsToKill != null) {
9220                for (int i=procsToKill.size()-1; i>=0; i--) {
9221                    ProcessRecord proc = procsToKill.get(i);
9222                    Slog.i(TAG, "Removing system update proc: " + proc);
9223                    removeProcessLocked(proc, true, false, "system update done");
9224                }
9225            }
9226
9227            // Now that we have cleaned up any update processes, we
9228            // are ready to start launching real processes and know that
9229            // we won't trample on them any more.
9230            mProcessesReady = true;
9231        }
9232
9233        Slog.i(TAG, "System now ready");
9234        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9235            SystemClock.uptimeMillis());
9236
9237        synchronized(this) {
9238            // Make sure we have no pre-ready processes sitting around.
9239
9240            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9241                ResolveInfo ri = mContext.getPackageManager()
9242                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9243                                STOCK_PM_FLAGS);
9244                CharSequence errorMsg = null;
9245                if (ri != null) {
9246                    ActivityInfo ai = ri.activityInfo;
9247                    ApplicationInfo app = ai.applicationInfo;
9248                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9249                        mTopAction = Intent.ACTION_FACTORY_TEST;
9250                        mTopData = null;
9251                        mTopComponent = new ComponentName(app.packageName,
9252                                ai.name);
9253                    } else {
9254                        errorMsg = mContext.getResources().getText(
9255                                com.android.internal.R.string.factorytest_not_system);
9256                    }
9257                } else {
9258                    errorMsg = mContext.getResources().getText(
9259                            com.android.internal.R.string.factorytest_no_action);
9260                }
9261                if (errorMsg != null) {
9262                    mTopAction = null;
9263                    mTopData = null;
9264                    mTopComponent = null;
9265                    Message msg = Message.obtain();
9266                    msg.what = SHOW_FACTORY_ERROR_MSG;
9267                    msg.getData().putCharSequence("msg", errorMsg);
9268                    mHandler.sendMessage(msg);
9269                }
9270            }
9271        }
9272
9273        retrieveSettings();
9274
9275        synchronized (this) {
9276            readGrantedUriPermissionsLocked();
9277        }
9278
9279        if (goingCallback != null) goingCallback.run();
9280
9281        synchronized (this) {
9282            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9283                try {
9284                    List apps = AppGlobals.getPackageManager().
9285                        getPersistentApplications(STOCK_PM_FLAGS);
9286                    if (apps != null) {
9287                        int N = apps.size();
9288                        int i;
9289                        for (i=0; i<N; i++) {
9290                            ApplicationInfo info
9291                                = (ApplicationInfo)apps.get(i);
9292                            if (info != null &&
9293                                    !info.packageName.equals("android")) {
9294                                addAppLocked(info, false);
9295                            }
9296                        }
9297                    }
9298                } catch (RemoteException ex) {
9299                    // pm is in same process, this will never happen.
9300                }
9301            }
9302
9303            // Start up initial activity.
9304            mBooting = true;
9305
9306            try {
9307                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9308                    Message msg = Message.obtain();
9309                    msg.what = SHOW_UID_ERROR_MSG;
9310                    mHandler.sendMessage(msg);
9311                }
9312            } catch (RemoteException e) {
9313            }
9314
9315            long ident = Binder.clearCallingIdentity();
9316            try {
9317                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9318                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9319                        | Intent.FLAG_RECEIVER_FOREGROUND);
9320                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9321                broadcastIntentLocked(null, null, intent,
9322                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9323                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9324                intent = new Intent(Intent.ACTION_USER_STARTING);
9325                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9326                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9327                broadcastIntentLocked(null, null, intent,
9328                        null, new IIntentReceiver.Stub() {
9329                            @Override
9330                            public void performReceive(Intent intent, int resultCode, String data,
9331                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9332                                    throws RemoteException {
9333                            }
9334                        }, 0, null, null,
9335                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9336                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9337            } finally {
9338                Binder.restoreCallingIdentity(ident);
9339            }
9340            mStackSupervisor.resumeTopActivitiesLocked();
9341            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9342        }
9343    }
9344
9345    private boolean makeAppCrashingLocked(ProcessRecord app,
9346            String shortMsg, String longMsg, String stackTrace) {
9347        app.crashing = true;
9348        app.crashingReport = generateProcessError(app,
9349                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9350        startAppProblemLocked(app);
9351        app.stopFreezingAllLocked();
9352        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9353    }
9354
9355    private void makeAppNotRespondingLocked(ProcessRecord app,
9356            String activity, String shortMsg, String longMsg) {
9357        app.notResponding = true;
9358        app.notRespondingReport = generateProcessError(app,
9359                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9360                activity, shortMsg, longMsg, null);
9361        startAppProblemLocked(app);
9362        app.stopFreezingAllLocked();
9363    }
9364
9365    /**
9366     * Generate a process error record, suitable for attachment to a ProcessRecord.
9367     *
9368     * @param app The ProcessRecord in which the error occurred.
9369     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9370     *                      ActivityManager.AppErrorStateInfo
9371     * @param activity The activity associated with the crash, if known.
9372     * @param shortMsg Short message describing the crash.
9373     * @param longMsg Long message describing the crash.
9374     * @param stackTrace Full crash stack trace, may be null.
9375     *
9376     * @return Returns a fully-formed AppErrorStateInfo record.
9377     */
9378    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9379            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9380        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9381
9382        report.condition = condition;
9383        report.processName = app.processName;
9384        report.pid = app.pid;
9385        report.uid = app.info.uid;
9386        report.tag = activity;
9387        report.shortMsg = shortMsg;
9388        report.longMsg = longMsg;
9389        report.stackTrace = stackTrace;
9390
9391        return report;
9392    }
9393
9394    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9395        synchronized (this) {
9396            app.crashing = false;
9397            app.crashingReport = null;
9398            app.notResponding = false;
9399            app.notRespondingReport = null;
9400            if (app.anrDialog == fromDialog) {
9401                app.anrDialog = null;
9402            }
9403            if (app.waitDialog == fromDialog) {
9404                app.waitDialog = null;
9405            }
9406            if (app.pid > 0 && app.pid != MY_PID) {
9407                handleAppCrashLocked(app, null, null, null);
9408                killUnneededProcessLocked(app, "user request after error");
9409            }
9410        }
9411    }
9412
9413    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9414            String stackTrace) {
9415        long now = SystemClock.uptimeMillis();
9416
9417        Long crashTime;
9418        if (!app.isolated) {
9419            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9420        } else {
9421            crashTime = null;
9422        }
9423        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9424            // This process loses!
9425            Slog.w(TAG, "Process " + app.info.processName
9426                    + " has crashed too many times: killing!");
9427            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9428                    app.userId, app.info.processName, app.uid);
9429            mStackSupervisor.handleAppCrashLocked(app);
9430            if (!app.persistent) {
9431                // We don't want to start this process again until the user
9432                // explicitly does so...  but for persistent process, we really
9433                // need to keep it running.  If a persistent process is actually
9434                // repeatedly crashing, then badness for everyone.
9435                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9436                        app.info.processName);
9437                if (!app.isolated) {
9438                    // XXX We don't have a way to mark isolated processes
9439                    // as bad, since they don't have a peristent identity.
9440                    mBadProcesses.put(app.info.processName, app.uid,
9441                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9442                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9443                }
9444                app.bad = true;
9445                app.removed = true;
9446                // Don't let services in this process be restarted and potentially
9447                // annoy the user repeatedly.  Unless it is persistent, since those
9448                // processes run critical code.
9449                removeProcessLocked(app, false, false, "crash");
9450                mStackSupervisor.resumeTopActivitiesLocked();
9451                return false;
9452            }
9453            mStackSupervisor.resumeTopActivitiesLocked();
9454        } else {
9455            mStackSupervisor.finishTopRunningActivityLocked(app);
9456        }
9457
9458        // Bump up the crash count of any services currently running in the proc.
9459        for (int i=app.services.size()-1; i>=0; i--) {
9460            // Any services running in the application need to be placed
9461            // back in the pending list.
9462            ServiceRecord sr = app.services.valueAt(i);
9463            sr.crashCount++;
9464        }
9465
9466        // If the crashing process is what we consider to be the "home process" and it has been
9467        // replaced by a third-party app, clear the package preferred activities from packages
9468        // with a home activity running in the process to prevent a repeatedly crashing app
9469        // from blocking the user to manually clear the list.
9470        final ArrayList<ActivityRecord> activities = app.activities;
9471        if (app == mHomeProcess && activities.size() > 0
9472                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9473            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9474                final ActivityRecord r = activities.get(activityNdx);
9475                if (r.isHomeActivity()) {
9476                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9477                    try {
9478                        ActivityThread.getPackageManager()
9479                                .clearPackagePreferredActivities(r.packageName);
9480                    } catch (RemoteException c) {
9481                        // pm is in same process, this will never happen.
9482                    }
9483                }
9484            }
9485        }
9486
9487        if (!app.isolated) {
9488            // XXX Can't keep track of crash times for isolated processes,
9489            // because they don't have a perisistent identity.
9490            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9491        }
9492
9493        return true;
9494    }
9495
9496    void startAppProblemLocked(ProcessRecord app) {
9497        if (app.userId == mCurrentUserId) {
9498            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9499                    mContext, app.info.packageName, app.info.flags);
9500        } else {
9501            // If this app is not running under the current user, then we
9502            // can't give it a report button because that would require
9503            // launching the report UI under a different user.
9504            app.errorReportReceiver = null;
9505        }
9506        skipCurrentReceiverLocked(app);
9507    }
9508
9509    void skipCurrentReceiverLocked(ProcessRecord app) {
9510        for (BroadcastQueue queue : mBroadcastQueues) {
9511            queue.skipCurrentReceiverLocked(app);
9512        }
9513    }
9514
9515    /**
9516     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9517     * The application process will exit immediately after this call returns.
9518     * @param app object of the crashing app, null for the system server
9519     * @param crashInfo describing the exception
9520     */
9521    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9522        ProcessRecord r = findAppProcess(app, "Crash");
9523        final String processName = app == null ? "system_server"
9524                : (r == null ? "unknown" : r.processName);
9525
9526        handleApplicationCrashInner("crash", r, processName, crashInfo);
9527    }
9528
9529    /* Native crash reporting uses this inner version because it needs to be somewhat
9530     * decoupled from the AM-managed cleanup lifecycle
9531     */
9532    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9533            ApplicationErrorReport.CrashInfo crashInfo) {
9534        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9535                UserHandle.getUserId(Binder.getCallingUid()), processName,
9536                r == null ? -1 : r.info.flags,
9537                crashInfo.exceptionClassName,
9538                crashInfo.exceptionMessage,
9539                crashInfo.throwFileName,
9540                crashInfo.throwLineNumber);
9541
9542        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9543
9544        crashApplication(r, crashInfo);
9545    }
9546
9547    public void handleApplicationStrictModeViolation(
9548            IBinder app,
9549            int violationMask,
9550            StrictMode.ViolationInfo info) {
9551        ProcessRecord r = findAppProcess(app, "StrictMode");
9552        if (r == null) {
9553            return;
9554        }
9555
9556        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9557            Integer stackFingerprint = info.hashCode();
9558            boolean logIt = true;
9559            synchronized (mAlreadyLoggedViolatedStacks) {
9560                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9561                    logIt = false;
9562                    // TODO: sub-sample into EventLog for these, with
9563                    // the info.durationMillis?  Then we'd get
9564                    // the relative pain numbers, without logging all
9565                    // the stack traces repeatedly.  We'd want to do
9566                    // likewise in the client code, which also does
9567                    // dup suppression, before the Binder call.
9568                } else {
9569                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9570                        mAlreadyLoggedViolatedStacks.clear();
9571                    }
9572                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9573                }
9574            }
9575            if (logIt) {
9576                logStrictModeViolationToDropBox(r, info);
9577            }
9578        }
9579
9580        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9581            AppErrorResult result = new AppErrorResult();
9582            synchronized (this) {
9583                final long origId = Binder.clearCallingIdentity();
9584
9585                Message msg = Message.obtain();
9586                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9587                HashMap<String, Object> data = new HashMap<String, Object>();
9588                data.put("result", result);
9589                data.put("app", r);
9590                data.put("violationMask", violationMask);
9591                data.put("info", info);
9592                msg.obj = data;
9593                mHandler.sendMessage(msg);
9594
9595                Binder.restoreCallingIdentity(origId);
9596            }
9597            int res = result.get();
9598            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9599        }
9600    }
9601
9602    // Depending on the policy in effect, there could be a bunch of
9603    // these in quick succession so we try to batch these together to
9604    // minimize disk writes, number of dropbox entries, and maximize
9605    // compression, by having more fewer, larger records.
9606    private void logStrictModeViolationToDropBox(
9607            ProcessRecord process,
9608            StrictMode.ViolationInfo info) {
9609        if (info == null) {
9610            return;
9611        }
9612        final boolean isSystemApp = process == null ||
9613                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9614                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9615        final String processName = process == null ? "unknown" : process.processName;
9616        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9617        final DropBoxManager dbox = (DropBoxManager)
9618                mContext.getSystemService(Context.DROPBOX_SERVICE);
9619
9620        // Exit early if the dropbox isn't configured to accept this report type.
9621        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9622
9623        boolean bufferWasEmpty;
9624        boolean needsFlush;
9625        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9626        synchronized (sb) {
9627            bufferWasEmpty = sb.length() == 0;
9628            appendDropBoxProcessHeaders(process, processName, sb);
9629            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9630            sb.append("System-App: ").append(isSystemApp).append("\n");
9631            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9632            if (info.violationNumThisLoop != 0) {
9633                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9634            }
9635            if (info.numAnimationsRunning != 0) {
9636                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9637            }
9638            if (info.broadcastIntentAction != null) {
9639                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9640            }
9641            if (info.durationMillis != -1) {
9642                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9643            }
9644            if (info.numInstances != -1) {
9645                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9646            }
9647            if (info.tags != null) {
9648                for (String tag : info.tags) {
9649                    sb.append("Span-Tag: ").append(tag).append("\n");
9650                }
9651            }
9652            sb.append("\n");
9653            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9654                sb.append(info.crashInfo.stackTrace);
9655            }
9656            sb.append("\n");
9657
9658            // Only buffer up to ~64k.  Various logging bits truncate
9659            // things at 128k.
9660            needsFlush = (sb.length() > 64 * 1024);
9661        }
9662
9663        // Flush immediately if the buffer's grown too large, or this
9664        // is a non-system app.  Non-system apps are isolated with a
9665        // different tag & policy and not batched.
9666        //
9667        // Batching is useful during internal testing with
9668        // StrictMode settings turned up high.  Without batching,
9669        // thousands of separate files could be created on boot.
9670        if (!isSystemApp || needsFlush) {
9671            new Thread("Error dump: " + dropboxTag) {
9672                @Override
9673                public void run() {
9674                    String report;
9675                    synchronized (sb) {
9676                        report = sb.toString();
9677                        sb.delete(0, sb.length());
9678                        sb.trimToSize();
9679                    }
9680                    if (report.length() != 0) {
9681                        dbox.addText(dropboxTag, report);
9682                    }
9683                }
9684            }.start();
9685            return;
9686        }
9687
9688        // System app batching:
9689        if (!bufferWasEmpty) {
9690            // An existing dropbox-writing thread is outstanding, so
9691            // we don't need to start it up.  The existing thread will
9692            // catch the buffer appends we just did.
9693            return;
9694        }
9695
9696        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9697        // (After this point, we shouldn't access AMS internal data structures.)
9698        new Thread("Error dump: " + dropboxTag) {
9699            @Override
9700            public void run() {
9701                // 5 second sleep to let stacks arrive and be batched together
9702                try {
9703                    Thread.sleep(5000);  // 5 seconds
9704                } catch (InterruptedException e) {}
9705
9706                String errorReport;
9707                synchronized (mStrictModeBuffer) {
9708                    errorReport = mStrictModeBuffer.toString();
9709                    if (errorReport.length() == 0) {
9710                        return;
9711                    }
9712                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9713                    mStrictModeBuffer.trimToSize();
9714                }
9715                dbox.addText(dropboxTag, errorReport);
9716            }
9717        }.start();
9718    }
9719
9720    /**
9721     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9722     * @param app object of the crashing app, null for the system server
9723     * @param tag reported by the caller
9724     * @param crashInfo describing the context of the error
9725     * @return true if the process should exit immediately (WTF is fatal)
9726     */
9727    public boolean handleApplicationWtf(IBinder app, String tag,
9728            ApplicationErrorReport.CrashInfo crashInfo) {
9729        ProcessRecord r = findAppProcess(app, "WTF");
9730        final String processName = app == null ? "system_server"
9731                : (r == null ? "unknown" : r.processName);
9732
9733        EventLog.writeEvent(EventLogTags.AM_WTF,
9734                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9735                processName,
9736                r == null ? -1 : r.info.flags,
9737                tag, crashInfo.exceptionMessage);
9738
9739        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9740
9741        if (r != null && r.pid != Process.myPid() &&
9742                Settings.Global.getInt(mContext.getContentResolver(),
9743                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9744            crashApplication(r, crashInfo);
9745            return true;
9746        } else {
9747            return false;
9748        }
9749    }
9750
9751    /**
9752     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9753     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9754     */
9755    private ProcessRecord findAppProcess(IBinder app, String reason) {
9756        if (app == null) {
9757            return null;
9758        }
9759
9760        synchronized (this) {
9761            final int NP = mProcessNames.getMap().size();
9762            for (int ip=0; ip<NP; ip++) {
9763                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9764                final int NA = apps.size();
9765                for (int ia=0; ia<NA; ia++) {
9766                    ProcessRecord p = apps.valueAt(ia);
9767                    if (p.thread != null && p.thread.asBinder() == app) {
9768                        return p;
9769                    }
9770                }
9771            }
9772
9773            Slog.w(TAG, "Can't find mystery application for " + reason
9774                    + " from pid=" + Binder.getCallingPid()
9775                    + " uid=" + Binder.getCallingUid() + ": " + app);
9776            return null;
9777        }
9778    }
9779
9780    /**
9781     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9782     * to append various headers to the dropbox log text.
9783     */
9784    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9785            StringBuilder sb) {
9786        // Watchdog thread ends up invoking this function (with
9787        // a null ProcessRecord) to add the stack file to dropbox.
9788        // Do not acquire a lock on this (am) in such cases, as it
9789        // could cause a potential deadlock, if and when watchdog
9790        // is invoked due to unavailability of lock on am and it
9791        // would prevent watchdog from killing system_server.
9792        if (process == null) {
9793            sb.append("Process: ").append(processName).append("\n");
9794            return;
9795        }
9796        // Note: ProcessRecord 'process' is guarded by the service
9797        // instance.  (notably process.pkgList, which could otherwise change
9798        // concurrently during execution of this method)
9799        synchronized (this) {
9800            sb.append("Process: ").append(processName).append("\n");
9801            int flags = process.info.flags;
9802            IPackageManager pm = AppGlobals.getPackageManager();
9803            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9804            for (int ip=0; ip<process.pkgList.size(); ip++) {
9805                String pkg = process.pkgList.keyAt(ip);
9806                sb.append("Package: ").append(pkg);
9807                try {
9808                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9809                    if (pi != null) {
9810                        sb.append(" v").append(pi.versionCode);
9811                        if (pi.versionName != null) {
9812                            sb.append(" (").append(pi.versionName).append(")");
9813                        }
9814                    }
9815                } catch (RemoteException e) {
9816                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9817                }
9818                sb.append("\n");
9819            }
9820        }
9821    }
9822
9823    private static String processClass(ProcessRecord process) {
9824        if (process == null || process.pid == MY_PID) {
9825            return "system_server";
9826        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9827            return "system_app";
9828        } else {
9829            return "data_app";
9830        }
9831    }
9832
9833    /**
9834     * Write a description of an error (crash, WTF, ANR) to the drop box.
9835     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9836     * @param process which caused the error, null means the system server
9837     * @param activity which triggered the error, null if unknown
9838     * @param parent activity related to the error, null if unknown
9839     * @param subject line related to the error, null if absent
9840     * @param report in long form describing the error, null if absent
9841     * @param logFile to include in the report, null if none
9842     * @param crashInfo giving an application stack trace, null if absent
9843     */
9844    public void addErrorToDropBox(String eventType,
9845            ProcessRecord process, String processName, ActivityRecord activity,
9846            ActivityRecord parent, String subject,
9847            final String report, final File logFile,
9848            final ApplicationErrorReport.CrashInfo crashInfo) {
9849        // NOTE -- this must never acquire the ActivityManagerService lock,
9850        // otherwise the watchdog may be prevented from resetting the system.
9851
9852        final String dropboxTag = processClass(process) + "_" + eventType;
9853        final DropBoxManager dbox = (DropBoxManager)
9854                mContext.getSystemService(Context.DROPBOX_SERVICE);
9855
9856        // Exit early if the dropbox isn't configured to accept this report type.
9857        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9858
9859        final StringBuilder sb = new StringBuilder(1024);
9860        appendDropBoxProcessHeaders(process, processName, sb);
9861        if (activity != null) {
9862            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9863        }
9864        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9865            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9866        }
9867        if (parent != null && parent != activity) {
9868            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9869        }
9870        if (subject != null) {
9871            sb.append("Subject: ").append(subject).append("\n");
9872        }
9873        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9874        if (Debug.isDebuggerConnected()) {
9875            sb.append("Debugger: Connected\n");
9876        }
9877        sb.append("\n");
9878
9879        // Do the rest in a worker thread to avoid blocking the caller on I/O
9880        // (After this point, we shouldn't access AMS internal data structures.)
9881        Thread worker = new Thread("Error dump: " + dropboxTag) {
9882            @Override
9883            public void run() {
9884                if (report != null) {
9885                    sb.append(report);
9886                }
9887                if (logFile != null) {
9888                    try {
9889                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9890                                    "\n\n[[TRUNCATED]]"));
9891                    } catch (IOException e) {
9892                        Slog.e(TAG, "Error reading " + logFile, e);
9893                    }
9894                }
9895                if (crashInfo != null && crashInfo.stackTrace != null) {
9896                    sb.append(crashInfo.stackTrace);
9897                }
9898
9899                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9900                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9901                if (lines > 0) {
9902                    sb.append("\n");
9903
9904                    // Merge several logcat streams, and take the last N lines
9905                    InputStreamReader input = null;
9906                    try {
9907                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9908                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9909                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9910
9911                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9912                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9913                        input = new InputStreamReader(logcat.getInputStream());
9914
9915                        int num;
9916                        char[] buf = new char[8192];
9917                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9918                    } catch (IOException e) {
9919                        Slog.e(TAG, "Error running logcat", e);
9920                    } finally {
9921                        if (input != null) try { input.close(); } catch (IOException e) {}
9922                    }
9923                }
9924
9925                dbox.addText(dropboxTag, sb.toString());
9926            }
9927        };
9928
9929        if (process == null) {
9930            // If process is null, we are being called from some internal code
9931            // and may be about to die -- run this synchronously.
9932            worker.run();
9933        } else {
9934            worker.start();
9935        }
9936    }
9937
9938    /**
9939     * Bring up the "unexpected error" dialog box for a crashing app.
9940     * Deal with edge cases (intercepts from instrumented applications,
9941     * ActivityController, error intent receivers, that sort of thing).
9942     * @param r the application crashing
9943     * @param crashInfo describing the failure
9944     */
9945    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9946        long timeMillis = System.currentTimeMillis();
9947        String shortMsg = crashInfo.exceptionClassName;
9948        String longMsg = crashInfo.exceptionMessage;
9949        String stackTrace = crashInfo.stackTrace;
9950        if (shortMsg != null && longMsg != null) {
9951            longMsg = shortMsg + ": " + longMsg;
9952        } else if (shortMsg != null) {
9953            longMsg = shortMsg;
9954        }
9955
9956        AppErrorResult result = new AppErrorResult();
9957        synchronized (this) {
9958            if (mController != null) {
9959                try {
9960                    String name = r != null ? r.processName : null;
9961                    int pid = r != null ? r.pid : Binder.getCallingPid();
9962                    if (!mController.appCrashed(name, pid,
9963                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9964                        Slog.w(TAG, "Force-killing crashed app " + name
9965                                + " at watcher's request");
9966                        Process.killProcess(pid);
9967                        return;
9968                    }
9969                } catch (RemoteException e) {
9970                    mController = null;
9971                    Watchdog.getInstance().setActivityController(null);
9972                }
9973            }
9974
9975            final long origId = Binder.clearCallingIdentity();
9976
9977            // If this process is running instrumentation, finish it.
9978            if (r != null && r.instrumentationClass != null) {
9979                Slog.w(TAG, "Error in app " + r.processName
9980                      + " running instrumentation " + r.instrumentationClass + ":");
9981                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
9982                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
9983                Bundle info = new Bundle();
9984                info.putString("shortMsg", shortMsg);
9985                info.putString("longMsg", longMsg);
9986                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
9987                Binder.restoreCallingIdentity(origId);
9988                return;
9989            }
9990
9991            // If we can't identify the process or it's already exceeded its crash quota,
9992            // quit right away without showing a crash dialog.
9993            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
9994                Binder.restoreCallingIdentity(origId);
9995                return;
9996            }
9997
9998            Message msg = Message.obtain();
9999            msg.what = SHOW_ERROR_MSG;
10000            HashMap data = new HashMap();
10001            data.put("result", result);
10002            data.put("app", r);
10003            msg.obj = data;
10004            mHandler.sendMessage(msg);
10005
10006            Binder.restoreCallingIdentity(origId);
10007        }
10008
10009        int res = result.get();
10010
10011        Intent appErrorIntent = null;
10012        synchronized (this) {
10013            if (r != null && !r.isolated) {
10014                // XXX Can't keep track of crash time for isolated processes,
10015                // since they don't have a persistent identity.
10016                mProcessCrashTimes.put(r.info.processName, r.uid,
10017                        SystemClock.uptimeMillis());
10018            }
10019            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10020                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10021            }
10022        }
10023
10024        if (appErrorIntent != null) {
10025            try {
10026                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10027            } catch (ActivityNotFoundException e) {
10028                Slog.w(TAG, "bug report receiver dissappeared", e);
10029            }
10030        }
10031    }
10032
10033    Intent createAppErrorIntentLocked(ProcessRecord r,
10034            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10035        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10036        if (report == null) {
10037            return null;
10038        }
10039        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10040        result.setComponent(r.errorReportReceiver);
10041        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10042        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10043        return result;
10044    }
10045
10046    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10047            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10048        if (r.errorReportReceiver == null) {
10049            return null;
10050        }
10051
10052        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10053            return null;
10054        }
10055
10056        ApplicationErrorReport report = new ApplicationErrorReport();
10057        report.packageName = r.info.packageName;
10058        report.installerPackageName = r.errorReportReceiver.getPackageName();
10059        report.processName = r.processName;
10060        report.time = timeMillis;
10061        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10062
10063        if (r.crashing || r.forceCrashReport) {
10064            report.type = ApplicationErrorReport.TYPE_CRASH;
10065            report.crashInfo = crashInfo;
10066        } else if (r.notResponding) {
10067            report.type = ApplicationErrorReport.TYPE_ANR;
10068            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10069
10070            report.anrInfo.activity = r.notRespondingReport.tag;
10071            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10072            report.anrInfo.info = r.notRespondingReport.longMsg;
10073        }
10074
10075        return report;
10076    }
10077
10078    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10079        enforceNotIsolatedCaller("getProcessesInErrorState");
10080        // assume our apps are happy - lazy create the list
10081        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10082
10083        final boolean allUsers = ActivityManager.checkUidPermission(
10084                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10085                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10086        int userId = UserHandle.getUserId(Binder.getCallingUid());
10087
10088        synchronized (this) {
10089
10090            // iterate across all processes
10091            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10092                ProcessRecord app = mLruProcesses.get(i);
10093                if (!allUsers && app.userId != userId) {
10094                    continue;
10095                }
10096                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10097                    // This one's in trouble, so we'll generate a report for it
10098                    // crashes are higher priority (in case there's a crash *and* an anr)
10099                    ActivityManager.ProcessErrorStateInfo report = null;
10100                    if (app.crashing) {
10101                        report = app.crashingReport;
10102                    } else if (app.notResponding) {
10103                        report = app.notRespondingReport;
10104                    }
10105
10106                    if (report != null) {
10107                        if (errList == null) {
10108                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10109                        }
10110                        errList.add(report);
10111                    } else {
10112                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10113                                " crashing = " + app.crashing +
10114                                " notResponding = " + app.notResponding);
10115                    }
10116                }
10117            }
10118        }
10119
10120        return errList;
10121    }
10122
10123    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10124        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10125            if (currApp != null) {
10126                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10127            }
10128            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10129        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10130            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10131        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10132            if (currApp != null) {
10133                currApp.lru = 0;
10134            }
10135            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10136        } else if (adj >= ProcessList.SERVICE_ADJ) {
10137            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10138        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10139            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10140        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10141            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10142        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10143            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10144        } else {
10145            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10146        }
10147    }
10148
10149    private void fillInProcMemInfo(ProcessRecord app,
10150            ActivityManager.RunningAppProcessInfo outInfo) {
10151        outInfo.pid = app.pid;
10152        outInfo.uid = app.info.uid;
10153        if (mHeavyWeightProcess == app) {
10154            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10155        }
10156        if (app.persistent) {
10157            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10158        }
10159        if (app.activities.size() > 0) {
10160            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10161        }
10162        outInfo.lastTrimLevel = app.trimMemoryLevel;
10163        int adj = app.curAdj;
10164        outInfo.importance = oomAdjToImportance(adj, outInfo);
10165        outInfo.importanceReasonCode = app.adjTypeCode;
10166    }
10167
10168    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10169        enforceNotIsolatedCaller("getRunningAppProcesses");
10170        // Lazy instantiation of list
10171        List<ActivityManager.RunningAppProcessInfo> runList = null;
10172        final boolean allUsers = ActivityManager.checkUidPermission(
10173                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10174                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10175        int userId = UserHandle.getUserId(Binder.getCallingUid());
10176        synchronized (this) {
10177            // Iterate across all processes
10178            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10179                ProcessRecord app = mLruProcesses.get(i);
10180                if (!allUsers && app.userId != userId) {
10181                    continue;
10182                }
10183                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10184                    // Generate process state info for running application
10185                    ActivityManager.RunningAppProcessInfo currApp =
10186                        new ActivityManager.RunningAppProcessInfo(app.processName,
10187                                app.pid, app.getPackageList());
10188                    fillInProcMemInfo(app, currApp);
10189                    if (app.adjSource instanceof ProcessRecord) {
10190                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10191                        currApp.importanceReasonImportance = oomAdjToImportance(
10192                                app.adjSourceOom, null);
10193                    } else if (app.adjSource instanceof ActivityRecord) {
10194                        ActivityRecord r = (ActivityRecord)app.adjSource;
10195                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10196                    }
10197                    if (app.adjTarget instanceof ComponentName) {
10198                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10199                    }
10200                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10201                    //        + " lru=" + currApp.lru);
10202                    if (runList == null) {
10203                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10204                    }
10205                    runList.add(currApp);
10206                }
10207            }
10208        }
10209        return runList;
10210    }
10211
10212    public List<ApplicationInfo> getRunningExternalApplications() {
10213        enforceNotIsolatedCaller("getRunningExternalApplications");
10214        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10215        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10216        if (runningApps != null && runningApps.size() > 0) {
10217            Set<String> extList = new HashSet<String>();
10218            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10219                if (app.pkgList != null) {
10220                    for (String pkg : app.pkgList) {
10221                        extList.add(pkg);
10222                    }
10223                }
10224            }
10225            IPackageManager pm = AppGlobals.getPackageManager();
10226            for (String pkg : extList) {
10227                try {
10228                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10229                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10230                        retList.add(info);
10231                    }
10232                } catch (RemoteException e) {
10233                }
10234            }
10235        }
10236        return retList;
10237    }
10238
10239    @Override
10240    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10241        enforceNotIsolatedCaller("getMyMemoryState");
10242        synchronized (this) {
10243            ProcessRecord proc;
10244            synchronized (mPidsSelfLocked) {
10245                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10246            }
10247            fillInProcMemInfo(proc, outInfo);
10248        }
10249    }
10250
10251    @Override
10252    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10253        if (checkCallingPermission(android.Manifest.permission.DUMP)
10254                != PackageManager.PERMISSION_GRANTED) {
10255            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10256                    + Binder.getCallingPid()
10257                    + ", uid=" + Binder.getCallingUid()
10258                    + " without permission "
10259                    + android.Manifest.permission.DUMP);
10260            return;
10261        }
10262
10263        boolean dumpAll = false;
10264        boolean dumpClient = false;
10265        String dumpPackage = null;
10266
10267        int opti = 0;
10268        while (opti < args.length) {
10269            String opt = args[opti];
10270            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10271                break;
10272            }
10273            opti++;
10274            if ("-a".equals(opt)) {
10275                dumpAll = true;
10276            } else if ("-c".equals(opt)) {
10277                dumpClient = true;
10278            } else if ("-h".equals(opt)) {
10279                pw.println("Activity manager dump options:");
10280                pw.println("  [-a] [-c] [-h] [cmd] ...");
10281                pw.println("  cmd may be one of:");
10282                pw.println("    a[ctivities]: activity stack state");
10283                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10284                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10285                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10286                pw.println("    o[om]: out of memory management");
10287                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10288                pw.println("    provider [COMP_SPEC]: provider client-side state");
10289                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10290                pw.println("    service [COMP_SPEC]: service client-side state");
10291                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10292                pw.println("    all: dump all activities");
10293                pw.println("    top: dump the top activity");
10294                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10295                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10296                pw.println("    a partial substring in a component name, a");
10297                pw.println("    hex object identifier.");
10298                pw.println("  -a: include all available server state.");
10299                pw.println("  -c: include client state.");
10300                return;
10301            } else {
10302                pw.println("Unknown argument: " + opt + "; use -h for help");
10303            }
10304        }
10305
10306        long origId = Binder.clearCallingIdentity();
10307        boolean more = false;
10308        // Is the caller requesting to dump a particular piece of data?
10309        if (opti < args.length) {
10310            String cmd = args[opti];
10311            opti++;
10312            if ("activities".equals(cmd) || "a".equals(cmd)) {
10313                synchronized (this) {
10314                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10315                }
10316            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10317                String[] newArgs;
10318                String name;
10319                if (opti >= args.length) {
10320                    name = null;
10321                    newArgs = EMPTY_STRING_ARRAY;
10322                } else {
10323                    name = args[opti];
10324                    opti++;
10325                    newArgs = new String[args.length - opti];
10326                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10327                            args.length - opti);
10328                }
10329                synchronized (this) {
10330                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10331                }
10332            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10333                String[] newArgs;
10334                String name;
10335                if (opti >= args.length) {
10336                    name = null;
10337                    newArgs = EMPTY_STRING_ARRAY;
10338                } else {
10339                    name = args[opti];
10340                    opti++;
10341                    newArgs = new String[args.length - opti];
10342                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10343                            args.length - opti);
10344                }
10345                synchronized (this) {
10346                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10347                }
10348            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10349                String[] newArgs;
10350                String name;
10351                if (opti >= args.length) {
10352                    name = null;
10353                    newArgs = EMPTY_STRING_ARRAY;
10354                } else {
10355                    name = args[opti];
10356                    opti++;
10357                    newArgs = new String[args.length - opti];
10358                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10359                            args.length - opti);
10360                }
10361                synchronized (this) {
10362                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10363                }
10364            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10365                synchronized (this) {
10366                    dumpOomLocked(fd, pw, args, opti, true);
10367                }
10368            } else if ("provider".equals(cmd)) {
10369                String[] newArgs;
10370                String name;
10371                if (opti >= args.length) {
10372                    name = null;
10373                    newArgs = EMPTY_STRING_ARRAY;
10374                } else {
10375                    name = args[opti];
10376                    opti++;
10377                    newArgs = new String[args.length - opti];
10378                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10379                }
10380                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10381                    pw.println("No providers match: " + name);
10382                    pw.println("Use -h for help.");
10383                }
10384            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10385                synchronized (this) {
10386                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10387                }
10388            } else if ("service".equals(cmd)) {
10389                String[] newArgs;
10390                String name;
10391                if (opti >= args.length) {
10392                    name = null;
10393                    newArgs = EMPTY_STRING_ARRAY;
10394                } else {
10395                    name = args[opti];
10396                    opti++;
10397                    newArgs = new String[args.length - opti];
10398                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10399                            args.length - opti);
10400                }
10401                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10402                    pw.println("No services match: " + name);
10403                    pw.println("Use -h for help.");
10404                }
10405            } else if ("package".equals(cmd)) {
10406                String[] newArgs;
10407                if (opti >= args.length) {
10408                    pw.println("package: no package name specified");
10409                    pw.println("Use -h for help.");
10410                } else {
10411                    dumpPackage = args[opti];
10412                    opti++;
10413                    newArgs = new String[args.length - opti];
10414                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10415                            args.length - opti);
10416                    args = newArgs;
10417                    opti = 0;
10418                    more = true;
10419                }
10420            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10421                synchronized (this) {
10422                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10423                }
10424            } else {
10425                // Dumping a single activity?
10426                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10427                    pw.println("Bad activity command, or no activities match: " + cmd);
10428                    pw.println("Use -h for help.");
10429                }
10430            }
10431            if (!more) {
10432                Binder.restoreCallingIdentity(origId);
10433                return;
10434            }
10435        }
10436
10437        // No piece of data specified, dump everything.
10438        synchronized (this) {
10439            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10440            pw.println();
10441            if (dumpAll) {
10442                pw.println("-------------------------------------------------------------------------------");
10443            }
10444            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10445            pw.println();
10446            if (dumpAll) {
10447                pw.println("-------------------------------------------------------------------------------");
10448            }
10449            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10450            pw.println();
10451            if (dumpAll) {
10452                pw.println("-------------------------------------------------------------------------------");
10453            }
10454            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10455            pw.println();
10456            if (dumpAll) {
10457                pw.println("-------------------------------------------------------------------------------");
10458            }
10459            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10460            pw.println();
10461            if (dumpAll) {
10462                pw.println("-------------------------------------------------------------------------------");
10463            }
10464            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10465        }
10466        Binder.restoreCallingIdentity(origId);
10467    }
10468
10469    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10470            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10471        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10472
10473        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10474                dumpPackage);
10475        boolean needSep = printedAnything;
10476
10477        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10478                dumpPackage, needSep, "  mFocusedActivity: ");
10479        if (printed) {
10480            printedAnything = true;
10481            needSep = false;
10482        }
10483
10484        if (dumpPackage == null) {
10485            if (needSep) {
10486                pw.println();
10487            }
10488            needSep = true;
10489            printedAnything = true;
10490            mStackSupervisor.dump(pw, "  ");
10491        }
10492
10493        if (mRecentTasks.size() > 0) {
10494            boolean printedHeader = false;
10495
10496            final int N = mRecentTasks.size();
10497            for (int i=0; i<N; i++) {
10498                TaskRecord tr = mRecentTasks.get(i);
10499                if (dumpPackage != null) {
10500                    if (tr.realActivity == null ||
10501                            !dumpPackage.equals(tr.realActivity)) {
10502                        continue;
10503                    }
10504                }
10505                if (!printedHeader) {
10506                    if (needSep) {
10507                        pw.println();
10508                    }
10509                    pw.println("  Recent tasks:");
10510                    printedHeader = true;
10511                    printedAnything = true;
10512                }
10513                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10514                        pw.println(tr);
10515                if (dumpAll) {
10516                    mRecentTasks.get(i).dump(pw, "    ");
10517                }
10518            }
10519        }
10520
10521        if (!printedAnything) {
10522            pw.println("  (nothing)");
10523        }
10524    }
10525
10526    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10527            int opti, boolean dumpAll, String dumpPackage) {
10528        boolean needSep = false;
10529        boolean printedAnything = false;
10530        int numPers = 0;
10531
10532        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10533
10534        if (dumpAll) {
10535            final int NP = mProcessNames.getMap().size();
10536            for (int ip=0; ip<NP; ip++) {
10537                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10538                final int NA = procs.size();
10539                for (int ia=0; ia<NA; ia++) {
10540                    ProcessRecord r = procs.valueAt(ia);
10541                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10542                        continue;
10543                    }
10544                    if (!needSep) {
10545                        pw.println("  All known processes:");
10546                        needSep = true;
10547                        printedAnything = true;
10548                    }
10549                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10550                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10551                        pw.print(" "); pw.println(r);
10552                    r.dump(pw, "    ");
10553                    if (r.persistent) {
10554                        numPers++;
10555                    }
10556                }
10557            }
10558        }
10559
10560        if (mIsolatedProcesses.size() > 0) {
10561            boolean printed = false;
10562            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10563                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10564                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10565                    continue;
10566                }
10567                if (!printed) {
10568                    if (needSep) {
10569                        pw.println();
10570                    }
10571                    pw.println("  Isolated process list (sorted by uid):");
10572                    printedAnything = true;
10573                    printed = true;
10574                    needSep = true;
10575                }
10576                pw.println(String.format("%sIsolated #%2d: %s",
10577                        "    ", i, r.toString()));
10578            }
10579        }
10580
10581        if (mLruProcesses.size() > 0) {
10582            if (needSep) {
10583                pw.println();
10584            }
10585            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10586                    pw.print(" total, non-act at ");
10587                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10588                    pw.print(", non-svc at ");
10589                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10590                    pw.println("):");
10591            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10592            needSep = true;
10593            printedAnything = true;
10594        }
10595
10596        if (dumpAll || dumpPackage != null) {
10597            synchronized (mPidsSelfLocked) {
10598                boolean printed = false;
10599                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10600                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10601                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10602                        continue;
10603                    }
10604                    if (!printed) {
10605                        if (needSep) pw.println();
10606                        needSep = true;
10607                        pw.println("  PID mappings:");
10608                        printed = true;
10609                        printedAnything = true;
10610                    }
10611                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10612                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10613                }
10614            }
10615        }
10616
10617        if (mForegroundProcesses.size() > 0) {
10618            synchronized (mPidsSelfLocked) {
10619                boolean printed = false;
10620                for (int i=0; i<mForegroundProcesses.size(); i++) {
10621                    ProcessRecord r = mPidsSelfLocked.get(
10622                            mForegroundProcesses.valueAt(i).pid);
10623                    if (dumpPackage != null && (r == null
10624                            || !r.pkgList.containsKey(dumpPackage))) {
10625                        continue;
10626                    }
10627                    if (!printed) {
10628                        if (needSep) pw.println();
10629                        needSep = true;
10630                        pw.println("  Foreground Processes:");
10631                        printed = true;
10632                        printedAnything = true;
10633                    }
10634                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10635                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10636                }
10637            }
10638        }
10639
10640        if (mPersistentStartingProcesses.size() > 0) {
10641            if (needSep) pw.println();
10642            needSep = true;
10643            printedAnything = true;
10644            pw.println("  Persisent processes that are starting:");
10645            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10646                    "Starting Norm", "Restarting PERS", dumpPackage);
10647        }
10648
10649        if (mRemovedProcesses.size() > 0) {
10650            if (needSep) pw.println();
10651            needSep = true;
10652            printedAnything = true;
10653            pw.println("  Processes that are being removed:");
10654            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10655                    "Removed Norm", "Removed PERS", dumpPackage);
10656        }
10657
10658        if (mProcessesOnHold.size() > 0) {
10659            if (needSep) pw.println();
10660            needSep = true;
10661            printedAnything = true;
10662            pw.println("  Processes that are on old until the system is ready:");
10663            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10664                    "OnHold Norm", "OnHold PERS", dumpPackage);
10665        }
10666
10667        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10668
10669        if (mProcessCrashTimes.getMap().size() > 0) {
10670            boolean printed = false;
10671            long now = SystemClock.uptimeMillis();
10672            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10673            final int NP = pmap.size();
10674            for (int ip=0; ip<NP; ip++) {
10675                String pname = pmap.keyAt(ip);
10676                SparseArray<Long> uids = pmap.valueAt(ip);
10677                final int N = uids.size();
10678                for (int i=0; i<N; i++) {
10679                    int puid = uids.keyAt(i);
10680                    ProcessRecord r = mProcessNames.get(pname, puid);
10681                    if (dumpPackage != null && (r == null
10682                            || !r.pkgList.containsKey(dumpPackage))) {
10683                        continue;
10684                    }
10685                    if (!printed) {
10686                        if (needSep) pw.println();
10687                        needSep = true;
10688                        pw.println("  Time since processes crashed:");
10689                        printed = true;
10690                        printedAnything = true;
10691                    }
10692                    pw.print("    Process "); pw.print(pname);
10693                            pw.print(" uid "); pw.print(puid);
10694                            pw.print(": last crashed ");
10695                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10696                            pw.println(" ago");
10697                }
10698            }
10699        }
10700
10701        if (mBadProcesses.getMap().size() > 0) {
10702            boolean printed = false;
10703            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10704            final int NP = pmap.size();
10705            for (int ip=0; ip<NP; ip++) {
10706                String pname = pmap.keyAt(ip);
10707                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10708                final int N = uids.size();
10709                for (int i=0; i<N; i++) {
10710                    int puid = uids.keyAt(i);
10711                    ProcessRecord r = mProcessNames.get(pname, puid);
10712                    if (dumpPackage != null && (r == null
10713                            || !r.pkgList.containsKey(dumpPackage))) {
10714                        continue;
10715                    }
10716                    if (!printed) {
10717                        if (needSep) pw.println();
10718                        needSep = true;
10719                        pw.println("  Bad processes:");
10720                        printedAnything = true;
10721                    }
10722                    BadProcessInfo info = uids.valueAt(i);
10723                    pw.print("    Bad process "); pw.print(pname);
10724                            pw.print(" uid "); pw.print(puid);
10725                            pw.print(": crashed at time "); pw.println(info.time);
10726                    if (info.shortMsg != null) {
10727                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10728                    }
10729                    if (info.longMsg != null) {
10730                        pw.print("      Long msg: "); pw.println(info.longMsg);
10731                    }
10732                    if (info.stack != null) {
10733                        pw.println("      Stack:");
10734                        int lastPos = 0;
10735                        for (int pos=0; pos<info.stack.length(); pos++) {
10736                            if (info.stack.charAt(pos) == '\n') {
10737                                pw.print("        ");
10738                                pw.write(info.stack, lastPos, pos-lastPos);
10739                                pw.println();
10740                                lastPos = pos+1;
10741                            }
10742                        }
10743                        if (lastPos < info.stack.length()) {
10744                            pw.print("        ");
10745                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10746                            pw.println();
10747                        }
10748                    }
10749                }
10750            }
10751        }
10752
10753        if (dumpPackage == null) {
10754            pw.println();
10755            needSep = false;
10756            pw.println("  mStartedUsers:");
10757            for (int i=0; i<mStartedUsers.size(); i++) {
10758                UserStartedState uss = mStartedUsers.valueAt(i);
10759                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10760                        pw.print(": "); uss.dump("", pw);
10761            }
10762            pw.print("  mStartedUserArray: [");
10763            for (int i=0; i<mStartedUserArray.length; i++) {
10764                if (i > 0) pw.print(", ");
10765                pw.print(mStartedUserArray[i]);
10766            }
10767            pw.println("]");
10768            pw.print("  mUserLru: [");
10769            for (int i=0; i<mUserLru.size(); i++) {
10770                if (i > 0) pw.print(", ");
10771                pw.print(mUserLru.get(i));
10772            }
10773            pw.println("]");
10774            if (dumpAll) {
10775                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10776            }
10777        }
10778        if (mHomeProcess != null && (dumpPackage == null
10779                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10780            if (needSep) {
10781                pw.println();
10782                needSep = false;
10783            }
10784            pw.println("  mHomeProcess: " + mHomeProcess);
10785        }
10786        if (mPreviousProcess != null && (dumpPackage == null
10787                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10788            if (needSep) {
10789                pw.println();
10790                needSep = false;
10791            }
10792            pw.println("  mPreviousProcess: " + mPreviousProcess);
10793        }
10794        if (dumpAll) {
10795            StringBuilder sb = new StringBuilder(128);
10796            sb.append("  mPreviousProcessVisibleTime: ");
10797            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10798            pw.println(sb);
10799        }
10800        if (mHeavyWeightProcess != null && (dumpPackage == null
10801                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10802            if (needSep) {
10803                pw.println();
10804                needSep = false;
10805            }
10806            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10807        }
10808        if (dumpPackage == null) {
10809            pw.println("  mConfiguration: " + mConfiguration);
10810        }
10811        if (dumpAll) {
10812            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10813            if (mCompatModePackages.getPackages().size() > 0) {
10814                boolean printed = false;
10815                for (Map.Entry<String, Integer> entry
10816                        : mCompatModePackages.getPackages().entrySet()) {
10817                    String pkg = entry.getKey();
10818                    int mode = entry.getValue();
10819                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10820                        continue;
10821                    }
10822                    if (!printed) {
10823                        pw.println("  mScreenCompatPackages:");
10824                        printed = true;
10825                    }
10826                    pw.print("    "); pw.print(pkg); pw.print(": ");
10827                            pw.print(mode); pw.println();
10828                }
10829            }
10830        }
10831        if (dumpPackage == null) {
10832            if (mSleeping || mWentToSleep || mLockScreenShown) {
10833                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10834                        + " mLockScreenShown " + mLockScreenShown);
10835            }
10836            if (mShuttingDown) {
10837                pw.println("  mShuttingDown=" + mShuttingDown);
10838            }
10839        }
10840        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10841                || mOrigWaitForDebugger) {
10842            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10843                    || dumpPackage.equals(mOrigDebugApp)) {
10844                if (needSep) {
10845                    pw.println();
10846                    needSep = false;
10847                }
10848                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10849                        + " mDebugTransient=" + mDebugTransient
10850                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10851            }
10852        }
10853        if (mOpenGlTraceApp != null) {
10854            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10855                if (needSep) {
10856                    pw.println();
10857                    needSep = false;
10858                }
10859                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10860            }
10861        }
10862        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10863                || mProfileFd != null) {
10864            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10865                if (needSep) {
10866                    pw.println();
10867                    needSep = false;
10868                }
10869                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10870                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10871                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10872                        + mAutoStopProfiler);
10873            }
10874        }
10875        if (dumpPackage == null) {
10876            if (mAlwaysFinishActivities || mController != null) {
10877                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10878                        + " mController=" + mController);
10879            }
10880            if (dumpAll) {
10881                pw.println("  Total persistent processes: " + numPers);
10882                pw.println("  mStartRunning=" + mStartRunning
10883                        + " mProcessesReady=" + mProcessesReady
10884                        + " mSystemReady=" + mSystemReady);
10885                pw.println("  mBooting=" + mBooting
10886                        + " mBooted=" + mBooted
10887                        + " mFactoryTest=" + mFactoryTest);
10888                pw.print("  mLastPowerCheckRealtime=");
10889                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10890                        pw.println("");
10891                pw.print("  mLastPowerCheckUptime=");
10892                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10893                        pw.println("");
10894                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10895                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10896                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10897                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10898                        + " (" + mLruProcesses.size() + " total)"
10899                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10900                        + " mNumServiceProcs=" + mNumServiceProcs
10901                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10902                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10903                        + " mLastMemoryLevel" + mLastMemoryLevel
10904                        + " mLastNumProcesses" + mLastNumProcesses);
10905                long now = SystemClock.uptimeMillis();
10906                pw.print("  mLastIdleTime=");
10907                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10908                        pw.print(" mLowRamSinceLastIdle=");
10909                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10910                        pw.println();
10911            }
10912        }
10913
10914        if (!printedAnything) {
10915            pw.println("  (nothing)");
10916        }
10917    }
10918
10919    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10920            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10921        if (mProcessesToGc.size() > 0) {
10922            boolean printed = false;
10923            long now = SystemClock.uptimeMillis();
10924            for (int i=0; i<mProcessesToGc.size(); i++) {
10925                ProcessRecord proc = mProcessesToGc.get(i);
10926                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10927                    continue;
10928                }
10929                if (!printed) {
10930                    if (needSep) pw.println();
10931                    needSep = true;
10932                    pw.println("  Processes that are waiting to GC:");
10933                    printed = true;
10934                }
10935                pw.print("    Process "); pw.println(proc);
10936                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10937                        pw.print(", last gced=");
10938                        pw.print(now-proc.lastRequestedGc);
10939                        pw.print(" ms ago, last lowMem=");
10940                        pw.print(now-proc.lastLowMemory);
10941                        pw.println(" ms ago");
10942
10943            }
10944        }
10945        return needSep;
10946    }
10947
10948    void printOomLevel(PrintWriter pw, String name, int adj) {
10949        pw.print("    ");
10950        if (adj >= 0) {
10951            pw.print(' ');
10952            if (adj < 10) pw.print(' ');
10953        } else {
10954            if (adj > -10) pw.print(' ');
10955        }
10956        pw.print(adj);
10957        pw.print(": ");
10958        pw.print(name);
10959        pw.print(" (");
10960        pw.print(mProcessList.getMemLevel(adj)/1024);
10961        pw.println(" kB)");
10962    }
10963
10964    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10965            int opti, boolean dumpAll) {
10966        boolean needSep = false;
10967
10968        if (mLruProcesses.size() > 0) {
10969            if (needSep) pw.println();
10970            needSep = true;
10971            pw.println("  OOM levels:");
10972            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10973            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10974            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10975            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10976            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10977            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10978            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10979            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10980            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
10981            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
10982            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
10983            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
10984            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
10985
10986            if (needSep) pw.println();
10987            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
10988                    pw.print(" total, non-act at ");
10989                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10990                    pw.print(", non-svc at ");
10991                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10992                    pw.println("):");
10993            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
10994            needSep = true;
10995        }
10996
10997        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
10998
10999        pw.println();
11000        pw.println("  mHomeProcess: " + mHomeProcess);
11001        pw.println("  mPreviousProcess: " + mPreviousProcess);
11002        if (mHeavyWeightProcess != null) {
11003            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11004        }
11005
11006        return true;
11007    }
11008
11009    /**
11010     * There are three ways to call this:
11011     *  - no provider specified: dump all the providers
11012     *  - a flattened component name that matched an existing provider was specified as the
11013     *    first arg: dump that one provider
11014     *  - the first arg isn't the flattened component name of an existing provider:
11015     *    dump all providers whose component contains the first arg as a substring
11016     */
11017    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11018            int opti, boolean dumpAll) {
11019        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11020    }
11021
11022    static class ItemMatcher {
11023        ArrayList<ComponentName> components;
11024        ArrayList<String> strings;
11025        ArrayList<Integer> objects;
11026        boolean all;
11027
11028        ItemMatcher() {
11029            all = true;
11030        }
11031
11032        void build(String name) {
11033            ComponentName componentName = ComponentName.unflattenFromString(name);
11034            if (componentName != null) {
11035                if (components == null) {
11036                    components = new ArrayList<ComponentName>();
11037                }
11038                components.add(componentName);
11039                all = false;
11040            } else {
11041                int objectId = 0;
11042                // Not a '/' separated full component name; maybe an object ID?
11043                try {
11044                    objectId = Integer.parseInt(name, 16);
11045                    if (objects == null) {
11046                        objects = new ArrayList<Integer>();
11047                    }
11048                    objects.add(objectId);
11049                    all = false;
11050                } catch (RuntimeException e) {
11051                    // Not an integer; just do string match.
11052                    if (strings == null) {
11053                        strings = new ArrayList<String>();
11054                    }
11055                    strings.add(name);
11056                    all = false;
11057                }
11058            }
11059        }
11060
11061        int build(String[] args, int opti) {
11062            for (; opti<args.length; opti++) {
11063                String name = args[opti];
11064                if ("--".equals(name)) {
11065                    return opti+1;
11066                }
11067                build(name);
11068            }
11069            return opti;
11070        }
11071
11072        boolean match(Object object, ComponentName comp) {
11073            if (all) {
11074                return true;
11075            }
11076            if (components != null) {
11077                for (int i=0; i<components.size(); i++) {
11078                    if (components.get(i).equals(comp)) {
11079                        return true;
11080                    }
11081                }
11082            }
11083            if (objects != null) {
11084                for (int i=0; i<objects.size(); i++) {
11085                    if (System.identityHashCode(object) == objects.get(i)) {
11086                        return true;
11087                    }
11088                }
11089            }
11090            if (strings != null) {
11091                String flat = comp.flattenToString();
11092                for (int i=0; i<strings.size(); i++) {
11093                    if (flat.contains(strings.get(i))) {
11094                        return true;
11095                    }
11096                }
11097            }
11098            return false;
11099        }
11100    }
11101
11102    /**
11103     * There are three things that cmd can be:
11104     *  - a flattened component name that matches an existing activity
11105     *  - the cmd arg isn't the flattened component name of an existing activity:
11106     *    dump all activity whose component contains the cmd as a substring
11107     *  - A hex number of the ActivityRecord object instance.
11108     */
11109    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11110            int opti, boolean dumpAll) {
11111        ArrayList<ActivityRecord> activities;
11112
11113        synchronized (this) {
11114            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11115        }
11116
11117        if (activities.size() <= 0) {
11118            return false;
11119        }
11120
11121        String[] newArgs = new String[args.length - opti];
11122        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11123
11124        TaskRecord lastTask = null;
11125        boolean needSep = false;
11126        for (int i=activities.size()-1; i>=0; i--) {
11127            ActivityRecord r = activities.get(i);
11128            if (needSep) {
11129                pw.println();
11130            }
11131            needSep = true;
11132            synchronized (this) {
11133                if (lastTask != r.task) {
11134                    lastTask = r.task;
11135                    pw.print("TASK "); pw.print(lastTask.affinity);
11136                            pw.print(" id="); pw.println(lastTask.taskId);
11137                    if (dumpAll) {
11138                        lastTask.dump(pw, "  ");
11139                    }
11140                }
11141            }
11142            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11143        }
11144        return true;
11145    }
11146
11147    /**
11148     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11149     * there is a thread associated with the activity.
11150     */
11151    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11152            final ActivityRecord r, String[] args, boolean dumpAll) {
11153        String innerPrefix = prefix + "  ";
11154        synchronized (this) {
11155            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11156                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11157                    pw.print(" pid=");
11158                    if (r.app != null) pw.println(r.app.pid);
11159                    else pw.println("(not running)");
11160            if (dumpAll) {
11161                r.dump(pw, innerPrefix);
11162            }
11163        }
11164        if (r.app != null && r.app.thread != null) {
11165            // flush anything that is already in the PrintWriter since the thread is going
11166            // to write to the file descriptor directly
11167            pw.flush();
11168            try {
11169                TransferPipe tp = new TransferPipe();
11170                try {
11171                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11172                            r.appToken, innerPrefix, args);
11173                    tp.go(fd);
11174                } finally {
11175                    tp.kill();
11176                }
11177            } catch (IOException e) {
11178                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11179            } catch (RemoteException e) {
11180                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11181            }
11182        }
11183    }
11184
11185    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11186            int opti, boolean dumpAll, String dumpPackage) {
11187        boolean needSep = false;
11188        boolean onlyHistory = false;
11189        boolean printedAnything = false;
11190
11191        if ("history".equals(dumpPackage)) {
11192            if (opti < args.length && "-s".equals(args[opti])) {
11193                dumpAll = false;
11194            }
11195            onlyHistory = true;
11196            dumpPackage = null;
11197        }
11198
11199        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11200        if (!onlyHistory && dumpAll) {
11201            if (mRegisteredReceivers.size() > 0) {
11202                boolean printed = false;
11203                Iterator it = mRegisteredReceivers.values().iterator();
11204                while (it.hasNext()) {
11205                    ReceiverList r = (ReceiverList)it.next();
11206                    if (dumpPackage != null && (r.app == null ||
11207                            !dumpPackage.equals(r.app.info.packageName))) {
11208                        continue;
11209                    }
11210                    if (!printed) {
11211                        pw.println("  Registered Receivers:");
11212                        needSep = true;
11213                        printed = true;
11214                        printedAnything = true;
11215                    }
11216                    pw.print("  * "); pw.println(r);
11217                    r.dump(pw, "    ");
11218                }
11219            }
11220
11221            if (mReceiverResolver.dump(pw, needSep ?
11222                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11223                    "    ", dumpPackage, false)) {
11224                needSep = true;
11225                printedAnything = true;
11226            }
11227        }
11228
11229        for (BroadcastQueue q : mBroadcastQueues) {
11230            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11231            printedAnything |= needSep;
11232        }
11233
11234        needSep = true;
11235
11236        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11237            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11238                if (needSep) {
11239                    pw.println();
11240                }
11241                needSep = true;
11242                printedAnything = true;
11243                pw.print("  Sticky broadcasts for user ");
11244                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11245                StringBuilder sb = new StringBuilder(128);
11246                for (Map.Entry<String, ArrayList<Intent>> ent
11247                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11248                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11249                    if (dumpAll) {
11250                        pw.println(":");
11251                        ArrayList<Intent> intents = ent.getValue();
11252                        final int N = intents.size();
11253                        for (int i=0; i<N; i++) {
11254                            sb.setLength(0);
11255                            sb.append("    Intent: ");
11256                            intents.get(i).toShortString(sb, false, true, false, false);
11257                            pw.println(sb.toString());
11258                            Bundle bundle = intents.get(i).getExtras();
11259                            if (bundle != null) {
11260                                pw.print("      ");
11261                                pw.println(bundle.toString());
11262                            }
11263                        }
11264                    } else {
11265                        pw.println("");
11266                    }
11267                }
11268            }
11269        }
11270
11271        if (!onlyHistory && dumpAll) {
11272            pw.println();
11273            for (BroadcastQueue queue : mBroadcastQueues) {
11274                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11275                        + queue.mBroadcastsScheduled);
11276            }
11277            pw.println("  mHandler:");
11278            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11279            needSep = true;
11280            printedAnything = true;
11281        }
11282
11283        if (!printedAnything) {
11284            pw.println("  (nothing)");
11285        }
11286    }
11287
11288    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11289            int opti, boolean dumpAll, String dumpPackage) {
11290        boolean needSep;
11291        boolean printedAnything = false;
11292
11293        ItemMatcher matcher = new ItemMatcher();
11294        matcher.build(args, opti);
11295
11296        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11297
11298        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11299        printedAnything |= needSep;
11300
11301        if (mLaunchingProviders.size() > 0) {
11302            boolean printed = false;
11303            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11304                ContentProviderRecord r = mLaunchingProviders.get(i);
11305                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11306                    continue;
11307                }
11308                if (!printed) {
11309                    if (needSep) pw.println();
11310                    needSep = true;
11311                    pw.println("  Launching content providers:");
11312                    printed = true;
11313                    printedAnything = true;
11314                }
11315                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11316                        pw.println(r);
11317            }
11318        }
11319
11320        if (mGrantedUriPermissions.size() > 0) {
11321            boolean printed = false;
11322            int dumpUid = -2;
11323            if (dumpPackage != null) {
11324                try {
11325                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11326                } catch (NameNotFoundException e) {
11327                    dumpUid = -1;
11328                }
11329            }
11330            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11331                int uid = mGrantedUriPermissions.keyAt(i);
11332                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11333                    continue;
11334                }
11335                ArrayMap<Uri, UriPermission> perms
11336                        = mGrantedUriPermissions.valueAt(i);
11337                if (!printed) {
11338                    if (needSep) pw.println();
11339                    needSep = true;
11340                    pw.println("  Granted Uri Permissions:");
11341                    printed = true;
11342                    printedAnything = true;
11343                }
11344                pw.print("  * UID "); pw.print(uid);
11345                        pw.println(" holds:");
11346                for (UriPermission perm : perms.values()) {
11347                    pw.print("    "); pw.println(perm);
11348                    if (dumpAll) {
11349                        perm.dump(pw, "      ");
11350                    }
11351                }
11352            }
11353        }
11354
11355        if (!printedAnything) {
11356            pw.println("  (nothing)");
11357        }
11358    }
11359
11360    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11361            int opti, boolean dumpAll, String dumpPackage) {
11362        boolean printed = false;
11363
11364        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11365
11366        if (mIntentSenderRecords.size() > 0) {
11367            Iterator<WeakReference<PendingIntentRecord>> it
11368                    = mIntentSenderRecords.values().iterator();
11369            while (it.hasNext()) {
11370                WeakReference<PendingIntentRecord> ref = it.next();
11371                PendingIntentRecord rec = ref != null ? ref.get(): null;
11372                if (dumpPackage != null && (rec == null
11373                        || !dumpPackage.equals(rec.key.packageName))) {
11374                    continue;
11375                }
11376                printed = true;
11377                if (rec != null) {
11378                    pw.print("  * "); pw.println(rec);
11379                    if (dumpAll) {
11380                        rec.dump(pw, "    ");
11381                    }
11382                } else {
11383                    pw.print("  * "); pw.println(ref);
11384                }
11385            }
11386        }
11387
11388        if (!printed) {
11389            pw.println("  (nothing)");
11390        }
11391    }
11392
11393    private static final int dumpProcessList(PrintWriter pw,
11394            ActivityManagerService service, List list,
11395            String prefix, String normalLabel, String persistentLabel,
11396            String dumpPackage) {
11397        int numPers = 0;
11398        final int N = list.size()-1;
11399        for (int i=N; i>=0; i--) {
11400            ProcessRecord r = (ProcessRecord)list.get(i);
11401            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11402                continue;
11403            }
11404            pw.println(String.format("%s%s #%2d: %s",
11405                    prefix, (r.persistent ? persistentLabel : normalLabel),
11406                    i, r.toString()));
11407            if (r.persistent) {
11408                numPers++;
11409            }
11410        }
11411        return numPers;
11412    }
11413
11414    private static final boolean dumpProcessOomList(PrintWriter pw,
11415            ActivityManagerService service, List<ProcessRecord> origList,
11416            String prefix, String normalLabel, String persistentLabel,
11417            boolean inclDetails, String dumpPackage) {
11418
11419        ArrayList<Pair<ProcessRecord, Integer>> list
11420                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11421        for (int i=0; i<origList.size(); i++) {
11422            ProcessRecord r = origList.get(i);
11423            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11424                continue;
11425            }
11426            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11427        }
11428
11429        if (list.size() <= 0) {
11430            return false;
11431        }
11432
11433        Comparator<Pair<ProcessRecord, Integer>> comparator
11434                = new Comparator<Pair<ProcessRecord, Integer>>() {
11435            @Override
11436            public int compare(Pair<ProcessRecord, Integer> object1,
11437                    Pair<ProcessRecord, Integer> object2) {
11438                if (object1.first.setAdj != object2.first.setAdj) {
11439                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11440                }
11441                if (object1.second.intValue() != object2.second.intValue()) {
11442                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11443                }
11444                return 0;
11445            }
11446        };
11447
11448        Collections.sort(list, comparator);
11449
11450        final long curRealtime = SystemClock.elapsedRealtime();
11451        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11452        final long curUptime = SystemClock.uptimeMillis();
11453        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11454
11455        for (int i=list.size()-1; i>=0; i--) {
11456            ProcessRecord r = list.get(i).first;
11457            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11458            char schedGroup;
11459            switch (r.setSchedGroup) {
11460                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11461                    schedGroup = 'B';
11462                    break;
11463                case Process.THREAD_GROUP_DEFAULT:
11464                    schedGroup = 'F';
11465                    break;
11466                default:
11467                    schedGroup = '?';
11468                    break;
11469            }
11470            char foreground;
11471            if (r.foregroundActivities) {
11472                foreground = 'A';
11473            } else if (r.foregroundServices) {
11474                foreground = 'S';
11475            } else {
11476                foreground = ' ';
11477            }
11478            String procState = ProcessList.makeProcStateString(r.curProcState);
11479            pw.print(prefix);
11480            pw.print(r.persistent ? persistentLabel : normalLabel);
11481            pw.print(" #");
11482            int num = (origList.size()-1)-list.get(i).second;
11483            if (num < 10) pw.print(' ');
11484            pw.print(num);
11485            pw.print(": ");
11486            pw.print(oomAdj);
11487            pw.print(' ');
11488            pw.print(schedGroup);
11489            pw.print('/');
11490            pw.print(foreground);
11491            pw.print('/');
11492            pw.print(procState);
11493            pw.print(" trm:");
11494            if (r.trimMemoryLevel < 10) pw.print(' ');
11495            pw.print(r.trimMemoryLevel);
11496            pw.print(' ');
11497            pw.print(r.toShortString());
11498            pw.print(" (");
11499            pw.print(r.adjType);
11500            pw.println(')');
11501            if (r.adjSource != null || r.adjTarget != null) {
11502                pw.print(prefix);
11503                pw.print("    ");
11504                if (r.adjTarget instanceof ComponentName) {
11505                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11506                } else if (r.adjTarget != null) {
11507                    pw.print(r.adjTarget.toString());
11508                } else {
11509                    pw.print("{null}");
11510                }
11511                pw.print("<=");
11512                if (r.adjSource instanceof ProcessRecord) {
11513                    pw.print("Proc{");
11514                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11515                    pw.println("}");
11516                } else if (r.adjSource != null) {
11517                    pw.println(r.adjSource.toString());
11518                } else {
11519                    pw.println("{null}");
11520                }
11521            }
11522            if (inclDetails) {
11523                pw.print(prefix);
11524                pw.print("    ");
11525                pw.print("oom: max="); pw.print(r.maxAdj);
11526                pw.print(" curRaw="); pw.print(r.curRawAdj);
11527                pw.print(" setRaw="); pw.print(r.setRawAdj);
11528                pw.print(" cur="); pw.print(r.curAdj);
11529                pw.print(" set="); pw.println(r.setAdj);
11530                pw.print(prefix);
11531                pw.print("    ");
11532                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11533                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11534                pw.print(" lastPss="); pw.print(r.lastPss);
11535                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11536                pw.print(prefix);
11537                pw.print("    ");
11538                pw.print("keeping="); pw.print(r.keeping);
11539                pw.print(" cached="); pw.print(r.cached);
11540                pw.print(" empty="); pw.print(r.empty);
11541                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11542
11543                if (!r.keeping) {
11544                    if (r.lastWakeTime != 0) {
11545                        long wtime;
11546                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11547                        synchronized (stats) {
11548                            wtime = stats.getProcessWakeTime(r.info.uid,
11549                                    r.pid, curRealtime);
11550                        }
11551                        long timeUsed = wtime - r.lastWakeTime;
11552                        pw.print(prefix);
11553                        pw.print("    ");
11554                        pw.print("keep awake over ");
11555                        TimeUtils.formatDuration(realtimeSince, pw);
11556                        pw.print(" used ");
11557                        TimeUtils.formatDuration(timeUsed, pw);
11558                        pw.print(" (");
11559                        pw.print((timeUsed*100)/realtimeSince);
11560                        pw.println("%)");
11561                    }
11562                    if (r.lastCpuTime != 0) {
11563                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11564                        pw.print(prefix);
11565                        pw.print("    ");
11566                        pw.print("run cpu over ");
11567                        TimeUtils.formatDuration(uptimeSince, pw);
11568                        pw.print(" used ");
11569                        TimeUtils.formatDuration(timeUsed, pw);
11570                        pw.print(" (");
11571                        pw.print((timeUsed*100)/uptimeSince);
11572                        pw.println("%)");
11573                    }
11574                }
11575            }
11576        }
11577        return true;
11578    }
11579
11580    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11581        ArrayList<ProcessRecord> procs;
11582        synchronized (this) {
11583            if (args != null && args.length > start
11584                    && args[start].charAt(0) != '-') {
11585                procs = new ArrayList<ProcessRecord>();
11586                int pid = -1;
11587                try {
11588                    pid = Integer.parseInt(args[start]);
11589                } catch (NumberFormatException e) {
11590                }
11591                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11592                    ProcessRecord proc = mLruProcesses.get(i);
11593                    if (proc.pid == pid) {
11594                        procs.add(proc);
11595                    } else if (proc.processName.equals(args[start])) {
11596                        procs.add(proc);
11597                    }
11598                }
11599                if (procs.size() <= 0) {
11600                    return null;
11601                }
11602            } else {
11603                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11604            }
11605        }
11606        return procs;
11607    }
11608
11609    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11610            PrintWriter pw, String[] args) {
11611        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11612        if (procs == null) {
11613            pw.println("No process found for: " + args[0]);
11614            return;
11615        }
11616
11617        long uptime = SystemClock.uptimeMillis();
11618        long realtime = SystemClock.elapsedRealtime();
11619        pw.println("Applications Graphics Acceleration Info:");
11620        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11621
11622        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11623            ProcessRecord r = procs.get(i);
11624            if (r.thread != null) {
11625                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11626                pw.flush();
11627                try {
11628                    TransferPipe tp = new TransferPipe();
11629                    try {
11630                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11631                        tp.go(fd);
11632                    } finally {
11633                        tp.kill();
11634                    }
11635                } catch (IOException e) {
11636                    pw.println("Failure while dumping the app: " + r);
11637                    pw.flush();
11638                } catch (RemoteException e) {
11639                    pw.println("Got a RemoteException while dumping the app " + r);
11640                    pw.flush();
11641                }
11642            }
11643        }
11644    }
11645
11646    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11647        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11648        if (procs == null) {
11649            pw.println("No process found for: " + args[0]);
11650            return;
11651        }
11652
11653        pw.println("Applications Database Info:");
11654
11655        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11656            ProcessRecord r = procs.get(i);
11657            if (r.thread != null) {
11658                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11659                pw.flush();
11660                try {
11661                    TransferPipe tp = new TransferPipe();
11662                    try {
11663                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11664                        tp.go(fd);
11665                    } finally {
11666                        tp.kill();
11667                    }
11668                } catch (IOException e) {
11669                    pw.println("Failure while dumping the app: " + r);
11670                    pw.flush();
11671                } catch (RemoteException e) {
11672                    pw.println("Got a RemoteException while dumping the app " + r);
11673                    pw.flush();
11674                }
11675            }
11676        }
11677    }
11678
11679    final static class MemItem {
11680        final boolean isProc;
11681        final String label;
11682        final String shortLabel;
11683        final long pss;
11684        final int id;
11685        final boolean hasActivities;
11686        ArrayList<MemItem> subitems;
11687
11688        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11689                boolean _hasActivities) {
11690            isProc = true;
11691            label = _label;
11692            shortLabel = _shortLabel;
11693            pss = _pss;
11694            id = _id;
11695            hasActivities = _hasActivities;
11696        }
11697
11698        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11699            isProc = false;
11700            label = _label;
11701            shortLabel = _shortLabel;
11702            pss = _pss;
11703            id = _id;
11704            hasActivities = false;
11705        }
11706    }
11707
11708    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11709            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11710        if (sort && !isCompact) {
11711            Collections.sort(items, new Comparator<MemItem>() {
11712                @Override
11713                public int compare(MemItem lhs, MemItem rhs) {
11714                    if (lhs.pss < rhs.pss) {
11715                        return 1;
11716                    } else if (lhs.pss > rhs.pss) {
11717                        return -1;
11718                    }
11719                    return 0;
11720                }
11721            });
11722        }
11723
11724        for (int i=0; i<items.size(); i++) {
11725            MemItem mi = items.get(i);
11726            if (!isCompact) {
11727                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11728            } else if (mi.isProc) {
11729                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11730                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11731                pw.println(mi.hasActivities ? ",a" : ",e");
11732            } else {
11733                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11734                pw.println(mi.pss);
11735            }
11736            if (mi.subitems != null) {
11737                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11738                        true, isCompact);
11739            }
11740        }
11741    }
11742
11743    // These are in KB.
11744    static final long[] DUMP_MEM_BUCKETS = new long[] {
11745        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11746        120*1024, 160*1024, 200*1024,
11747        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11748        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11749    };
11750
11751    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11752            boolean stackLike) {
11753        int start = label.lastIndexOf('.');
11754        if (start >= 0) start++;
11755        else start = 0;
11756        int end = label.length();
11757        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11758            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11759                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11760                out.append(bucket);
11761                out.append(stackLike ? "MB." : "MB ");
11762                out.append(label, start, end);
11763                return;
11764            }
11765        }
11766        out.append(memKB/1024);
11767        out.append(stackLike ? "MB." : "MB ");
11768        out.append(label, start, end);
11769    }
11770
11771    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11772            ProcessList.NATIVE_ADJ,
11773            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11774            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11775            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11776            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11777            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11778    };
11779    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11780            "Native",
11781            "System", "Persistent", "Foreground",
11782            "Visible", "Perceptible",
11783            "Heavy Weight", "Backup",
11784            "A Services", "Home",
11785            "Previous", "B Services", "Cached"
11786    };
11787    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11788            "native",
11789            "sys", "pers", "fore",
11790            "vis", "percept",
11791            "heavy", "backup",
11792            "servicea", "home",
11793            "prev", "serviceb", "cached"
11794    };
11795
11796    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11797            long realtime, boolean isCheckinRequest, boolean isCompact) {
11798        if (isCheckinRequest || isCompact) {
11799            // short checkin version
11800            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11801        } else {
11802            pw.println("Applications Memory Usage (kB):");
11803            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11804        }
11805    }
11806
11807    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11808            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11809        boolean dumpDetails = false;
11810        boolean dumpFullDetails = false;
11811        boolean dumpDalvik = false;
11812        boolean oomOnly = false;
11813        boolean isCompact = false;
11814        boolean localOnly = false;
11815
11816        int opti = 0;
11817        while (opti < args.length) {
11818            String opt = args[opti];
11819            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11820                break;
11821            }
11822            opti++;
11823            if ("-a".equals(opt)) {
11824                dumpDetails = true;
11825                dumpFullDetails = true;
11826                dumpDalvik = true;
11827            } else if ("-d".equals(opt)) {
11828                dumpDalvik = true;
11829            } else if ("-c".equals(opt)) {
11830                isCompact = true;
11831            } else if ("--oom".equals(opt)) {
11832                oomOnly = true;
11833            } else if ("--local".equals(opt)) {
11834                localOnly = true;
11835            } else if ("-h".equals(opt)) {
11836                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11837                pw.println("  -a: include all available information for each process.");
11838                pw.println("  -d: include dalvik details when dumping process details.");
11839                pw.println("  -c: dump in a compact machine-parseable representation.");
11840                pw.println("  --oom: only show processes organized by oom adj.");
11841                pw.println("  --local: only collect details locally, don't call process.");
11842                pw.println("If [process] is specified it can be the name or ");
11843                pw.println("pid of a specific process to dump.");
11844                return;
11845            } else {
11846                pw.println("Unknown argument: " + opt + "; use -h for help");
11847            }
11848        }
11849
11850        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11851        long uptime = SystemClock.uptimeMillis();
11852        long realtime = SystemClock.elapsedRealtime();
11853        final long[] tmpLong = new long[1];
11854
11855        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11856        if (procs == null) {
11857            // No Java processes.  Maybe they want to print a native process.
11858            if (args != null && args.length > opti
11859                    && args[opti].charAt(0) != '-') {
11860                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11861                        = new ArrayList<ProcessCpuTracker.Stats>();
11862                updateCpuStatsNow();
11863                int findPid = -1;
11864                try {
11865                    findPid = Integer.parseInt(args[opti]);
11866                } catch (NumberFormatException e) {
11867                }
11868                synchronized (mProcessCpuThread) {
11869                    final int N = mProcessCpuTracker.countStats();
11870                    for (int i=0; i<N; i++) {
11871                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11872                        if (st.pid == findPid || (st.baseName != null
11873                                && st.baseName.equals(args[opti]))) {
11874                            nativeProcs.add(st);
11875                        }
11876                    }
11877                }
11878                if (nativeProcs.size() > 0) {
11879                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11880                            isCompact);
11881                    Debug.MemoryInfo mi = null;
11882                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11883                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11884                        final int pid = r.pid;
11885                        if (!isCheckinRequest && dumpDetails) {
11886                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11887                        }
11888                        if (mi == null) {
11889                            mi = new Debug.MemoryInfo();
11890                        }
11891                        if (dumpDetails || (!brief && !oomOnly)) {
11892                            Debug.getMemoryInfo(pid, mi);
11893                        } else {
11894                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11895                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11896                        }
11897                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11898                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11899                        if (isCheckinRequest) {
11900                            pw.println();
11901                        }
11902                    }
11903                    return;
11904                }
11905            }
11906            pw.println("No process found for: " + args[opti]);
11907            return;
11908        }
11909
11910        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11911            dumpDetails = true;
11912        }
11913
11914        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11915
11916        String[] innerArgs = new String[args.length-opti];
11917        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11918
11919        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11920        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11921        long nativePss=0, dalvikPss=0, otherPss=0;
11922        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11923
11924        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11925        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11926                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11927
11928        long totalPss = 0;
11929        long cachedPss = 0;
11930
11931        Debug.MemoryInfo mi = null;
11932        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11933            final ProcessRecord r = procs.get(i);
11934            final IApplicationThread thread;
11935            final int pid;
11936            final int oomAdj;
11937            final boolean hasActivities;
11938            synchronized (this) {
11939                thread = r.thread;
11940                pid = r.pid;
11941                oomAdj = r.getSetAdjWithServices();
11942                hasActivities = r.activities.size() > 0;
11943            }
11944            if (thread != null) {
11945                if (!isCheckinRequest && dumpDetails) {
11946                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11947                }
11948                if (mi == null) {
11949                    mi = new Debug.MemoryInfo();
11950                }
11951                if (dumpDetails || (!brief && !oomOnly)) {
11952                    Debug.getMemoryInfo(pid, mi);
11953                } else {
11954                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11955                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11956                }
11957                if (dumpDetails) {
11958                    if (localOnly) {
11959                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11960                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11961                        if (isCheckinRequest) {
11962                            pw.println();
11963                        }
11964                    } else {
11965                        try {
11966                            pw.flush();
11967                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11968                                    dumpDalvik, innerArgs);
11969                        } catch (RemoteException e) {
11970                            if (!isCheckinRequest) {
11971                                pw.println("Got RemoteException!");
11972                                pw.flush();
11973                            }
11974                        }
11975                    }
11976                }
11977
11978                final long myTotalPss = mi.getTotalPss();
11979                final long myTotalUss = mi.getTotalUss();
11980
11981                synchronized (this) {
11982                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
11983                        // Record this for posterity if the process has been stable.
11984                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
11985                    }
11986                }
11987
11988                if (!isCheckinRequest && mi != null) {
11989                    totalPss += myTotalPss;
11990                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
11991                            (hasActivities ? " / activities)" : ")"),
11992                            r.processName, myTotalPss, pid, hasActivities);
11993                    procMems.add(pssItem);
11994                    procMemsMap.put(pid, pssItem);
11995
11996                    nativePss += mi.nativePss;
11997                    dalvikPss += mi.dalvikPss;
11998                    otherPss += mi.otherPss;
11999                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12000                        long mem = mi.getOtherPss(j);
12001                        miscPss[j] += mem;
12002                        otherPss -= mem;
12003                    }
12004
12005                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12006                        cachedPss += myTotalPss;
12007                    }
12008
12009                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12010                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12011                                || oomIndex == (oomPss.length-1)) {
12012                            oomPss[oomIndex] += myTotalPss;
12013                            if (oomProcs[oomIndex] == null) {
12014                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12015                            }
12016                            oomProcs[oomIndex].add(pssItem);
12017                            break;
12018                        }
12019                    }
12020                }
12021            }
12022        }
12023
12024        if (!isCheckinRequest && procs.size() > 1) {
12025            // If we are showing aggregations, also look for native processes to
12026            // include so that our aggregations are more accurate.
12027            updateCpuStatsNow();
12028            synchronized (mProcessCpuThread) {
12029                final int N = mProcessCpuTracker.countStats();
12030                for (int i=0; i<N; i++) {
12031                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12032                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12033                        if (mi == null) {
12034                            mi = new Debug.MemoryInfo();
12035                        }
12036                        if (!brief && !oomOnly) {
12037                            Debug.getMemoryInfo(st.pid, mi);
12038                        } else {
12039                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12040                            mi.nativePrivateDirty = (int)tmpLong[0];
12041                        }
12042
12043                        final long myTotalPss = mi.getTotalPss();
12044                        totalPss += myTotalPss;
12045
12046                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12047                                st.name, myTotalPss, st.pid, false);
12048                        procMems.add(pssItem);
12049
12050                        nativePss += mi.nativePss;
12051                        dalvikPss += mi.dalvikPss;
12052                        otherPss += mi.otherPss;
12053                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12054                            long mem = mi.getOtherPss(j);
12055                            miscPss[j] += mem;
12056                            otherPss -= mem;
12057                        }
12058                        oomPss[0] += myTotalPss;
12059                        if (oomProcs[0] == null) {
12060                            oomProcs[0] = new ArrayList<MemItem>();
12061                        }
12062                        oomProcs[0].add(pssItem);
12063                    }
12064                }
12065            }
12066
12067            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12068
12069            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12070            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12071            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12072            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12073                String label = Debug.MemoryInfo.getOtherLabel(j);
12074                catMems.add(new MemItem(label, label, miscPss[j], j));
12075            }
12076
12077            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12078            for (int j=0; j<oomPss.length; j++) {
12079                if (oomPss[j] != 0) {
12080                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12081                            : DUMP_MEM_OOM_LABEL[j];
12082                    MemItem item = new MemItem(label, label, oomPss[j],
12083                            DUMP_MEM_OOM_ADJ[j]);
12084                    item.subitems = oomProcs[j];
12085                    oomMems.add(item);
12086                }
12087            }
12088
12089            if (!brief && !oomOnly && !isCompact) {
12090                pw.println();
12091                pw.println("Total PSS by process:");
12092                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12093                pw.println();
12094            }
12095            if (!isCompact) {
12096                pw.println("Total PSS by OOM adjustment:");
12097            }
12098            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12099            if (!brief && !oomOnly) {
12100                PrintWriter out = categoryPw != null ? categoryPw : pw;
12101                if (!isCompact) {
12102                    out.println();
12103                    out.println("Total PSS by category:");
12104                }
12105                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12106            }
12107            if (!isCompact) {
12108                pw.println();
12109            }
12110            MemInfoReader memInfo = new MemInfoReader();
12111            memInfo.readMemInfo();
12112            if (!brief) {
12113                if (!isCompact) {
12114                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12115                    pw.println(" kB");
12116                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12117                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12118                            pw.print(cachedPss); pw.print(" cached pss + ");
12119                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12120                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12121                } else {
12122                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12123                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12124                            + memInfo.getFreeSizeKb()); pw.print(",");
12125                    pw.println(totalPss - cachedPss);
12126                }
12127            }
12128            if (!isCompact) {
12129                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12130                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12131                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12132                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12133                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12134                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12135                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12136                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12137                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12138                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12139                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12140            }
12141            if (!brief) {
12142                if (memInfo.getZramTotalSizeKb() != 0) {
12143                    if (!isCompact) {
12144                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12145                                pw.print(" kB physical used for ");
12146                                pw.print(memInfo.getSwapTotalSizeKb()
12147                                        - memInfo.getSwapFreeSizeKb());
12148                                pw.print(" kB in swap (");
12149                                pw.print(memInfo.getSwapTotalSizeKb());
12150                                pw.println(" kB total swap)");
12151                    } else {
12152                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12153                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12154                                pw.println(memInfo.getSwapFreeSizeKb());
12155                    }
12156                }
12157                final int[] SINGLE_LONG_FORMAT = new int[] {
12158                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12159                };
12160                long[] longOut = new long[1];
12161                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12162                        SINGLE_LONG_FORMAT, null, longOut, null);
12163                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12164                longOut[0] = 0;
12165                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12166                        SINGLE_LONG_FORMAT, null, longOut, null);
12167                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12168                longOut[0] = 0;
12169                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12170                        SINGLE_LONG_FORMAT, null, longOut, null);
12171                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12172                longOut[0] = 0;
12173                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12174                        SINGLE_LONG_FORMAT, null, longOut, null);
12175                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12176                if (!isCompact) {
12177                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12178                        pw.print("      KSM: "); pw.print(sharing);
12179                                pw.print(" kB saved from shared ");
12180                                pw.print(shared); pw.println(" kB");
12181                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12182                                pw.print(voltile); pw.println(" kB volatile");
12183                    }
12184                    pw.print("   Tuning: ");
12185                    pw.print(ActivityManager.staticGetMemoryClass());
12186                    pw.print(" (large ");
12187                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12188                    pw.print("), oom ");
12189                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12190                    pw.print(" kB");
12191                    pw.print(", restore limit ");
12192                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12193                    pw.print(" kB");
12194                    if (ActivityManager.isLowRamDeviceStatic()) {
12195                        pw.print(" (low-ram)");
12196                    }
12197                    if (ActivityManager.isHighEndGfx()) {
12198                        pw.print(" (high-end-gfx)");
12199                    }
12200                    pw.println();
12201                } else {
12202                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12203                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12204                    pw.println(voltile);
12205                    pw.print("tuning,");
12206                    pw.print(ActivityManager.staticGetMemoryClass());
12207                    pw.print(',');
12208                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12209                    pw.print(',');
12210                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12211                    if (ActivityManager.isLowRamDeviceStatic()) {
12212                        pw.print(",low-ram");
12213                    }
12214                    if (ActivityManager.isHighEndGfx()) {
12215                        pw.print(",high-end-gfx");
12216                    }
12217                    pw.println();
12218                }
12219            }
12220        }
12221    }
12222
12223    /**
12224     * Searches array of arguments for the specified string
12225     * @param args array of argument strings
12226     * @param value value to search for
12227     * @return true if the value is contained in the array
12228     */
12229    private static boolean scanArgs(String[] args, String value) {
12230        if (args != null) {
12231            for (String arg : args) {
12232                if (value.equals(arg)) {
12233                    return true;
12234                }
12235            }
12236        }
12237        return false;
12238    }
12239
12240    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12241            ContentProviderRecord cpr, boolean always) {
12242        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12243
12244        if (!inLaunching || always) {
12245            synchronized (cpr) {
12246                cpr.launchingApp = null;
12247                cpr.notifyAll();
12248            }
12249            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12250            String names[] = cpr.info.authority.split(";");
12251            for (int j = 0; j < names.length; j++) {
12252                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12253            }
12254        }
12255
12256        for (int i=0; i<cpr.connections.size(); i++) {
12257            ContentProviderConnection conn = cpr.connections.get(i);
12258            if (conn.waiting) {
12259                // If this connection is waiting for the provider, then we don't
12260                // need to mess with its process unless we are always removing
12261                // or for some reason the provider is not currently launching.
12262                if (inLaunching && !always) {
12263                    continue;
12264                }
12265            }
12266            ProcessRecord capp = conn.client;
12267            conn.dead = true;
12268            if (conn.stableCount > 0) {
12269                if (!capp.persistent && capp.thread != null
12270                        && capp.pid != 0
12271                        && capp.pid != MY_PID) {
12272                    killUnneededProcessLocked(capp, "depends on provider "
12273                            + cpr.name.flattenToShortString()
12274                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12275                }
12276            } else if (capp.thread != null && conn.provider.provider != null) {
12277                try {
12278                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12279                } catch (RemoteException e) {
12280                }
12281                // In the protocol here, we don't expect the client to correctly
12282                // clean up this connection, we'll just remove it.
12283                cpr.connections.remove(i);
12284                conn.client.conProviders.remove(conn);
12285            }
12286        }
12287
12288        if (inLaunching && always) {
12289            mLaunchingProviders.remove(cpr);
12290        }
12291        return inLaunching;
12292    }
12293
12294    /**
12295     * Main code for cleaning up a process when it has gone away.  This is
12296     * called both as a result of the process dying, or directly when stopping
12297     * a process when running in single process mode.
12298     */
12299    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12300            boolean restarting, boolean allowRestart, int index) {
12301        if (index >= 0) {
12302            removeLruProcessLocked(app);
12303            ProcessList.remove(app.pid);
12304        }
12305
12306        mProcessesToGc.remove(app);
12307        mPendingPssProcesses.remove(app);
12308
12309        // Dismiss any open dialogs.
12310        if (app.crashDialog != null && !app.forceCrashReport) {
12311            app.crashDialog.dismiss();
12312            app.crashDialog = null;
12313        }
12314        if (app.anrDialog != null) {
12315            app.anrDialog.dismiss();
12316            app.anrDialog = null;
12317        }
12318        if (app.waitDialog != null) {
12319            app.waitDialog.dismiss();
12320            app.waitDialog = null;
12321        }
12322
12323        app.crashing = false;
12324        app.notResponding = false;
12325
12326        app.resetPackageList(mProcessStats);
12327        app.unlinkDeathRecipient();
12328        app.makeInactive(mProcessStats);
12329        app.forcingToForeground = null;
12330        app.foregroundServices = false;
12331        app.foregroundActivities = false;
12332        app.hasShownUi = false;
12333        app.hasAboveClient = false;
12334
12335        mServices.killServicesLocked(app, allowRestart);
12336
12337        boolean restart = false;
12338
12339        // Remove published content providers.
12340        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12341            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12342            final boolean always = app.bad || !allowRestart;
12343            if (removeDyingProviderLocked(app, cpr, always) || always) {
12344                // We left the provider in the launching list, need to
12345                // restart it.
12346                restart = true;
12347            }
12348
12349            cpr.provider = null;
12350            cpr.proc = null;
12351        }
12352        app.pubProviders.clear();
12353
12354        // Take care of any launching providers waiting for this process.
12355        if (checkAppInLaunchingProvidersLocked(app, false)) {
12356            restart = true;
12357        }
12358
12359        // Unregister from connected content providers.
12360        if (!app.conProviders.isEmpty()) {
12361            for (int i=0; i<app.conProviders.size(); i++) {
12362                ContentProviderConnection conn = app.conProviders.get(i);
12363                conn.provider.connections.remove(conn);
12364            }
12365            app.conProviders.clear();
12366        }
12367
12368        // At this point there may be remaining entries in mLaunchingProviders
12369        // where we were the only one waiting, so they are no longer of use.
12370        // Look for these and clean up if found.
12371        // XXX Commented out for now.  Trying to figure out a way to reproduce
12372        // the actual situation to identify what is actually going on.
12373        if (false) {
12374            for (int i=0; i<mLaunchingProviders.size(); i++) {
12375                ContentProviderRecord cpr = (ContentProviderRecord)
12376                        mLaunchingProviders.get(i);
12377                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12378                    synchronized (cpr) {
12379                        cpr.launchingApp = null;
12380                        cpr.notifyAll();
12381                    }
12382                }
12383            }
12384        }
12385
12386        skipCurrentReceiverLocked(app);
12387
12388        // Unregister any receivers.
12389        for (int i=app.receivers.size()-1; i>=0; i--) {
12390            removeReceiverLocked(app.receivers.valueAt(i));
12391        }
12392        app.receivers.clear();
12393
12394        // If the app is undergoing backup, tell the backup manager about it
12395        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12396            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12397                    + mBackupTarget.appInfo + " died during backup");
12398            try {
12399                IBackupManager bm = IBackupManager.Stub.asInterface(
12400                        ServiceManager.getService(Context.BACKUP_SERVICE));
12401                bm.agentDisconnected(app.info.packageName);
12402            } catch (RemoteException e) {
12403                // can't happen; backup manager is local
12404            }
12405        }
12406
12407        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12408            ProcessChangeItem item = mPendingProcessChanges.get(i);
12409            if (item.pid == app.pid) {
12410                mPendingProcessChanges.remove(i);
12411                mAvailProcessChanges.add(item);
12412            }
12413        }
12414        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12415
12416        // If the caller is restarting this app, then leave it in its
12417        // current lists and let the caller take care of it.
12418        if (restarting) {
12419            return;
12420        }
12421
12422        if (!app.persistent || app.isolated) {
12423            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12424                    "Removing non-persistent process during cleanup: " + app);
12425            mProcessNames.remove(app.processName, app.uid);
12426            mIsolatedProcesses.remove(app.uid);
12427            if (mHeavyWeightProcess == app) {
12428                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12429                        mHeavyWeightProcess.userId, 0));
12430                mHeavyWeightProcess = null;
12431            }
12432        } else if (!app.removed) {
12433            // This app is persistent, so we need to keep its record around.
12434            // If it is not already on the pending app list, add it there
12435            // and start a new process for it.
12436            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12437                mPersistentStartingProcesses.add(app);
12438                restart = true;
12439            }
12440        }
12441        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12442                "Clean-up removing on hold: " + app);
12443        mProcessesOnHold.remove(app);
12444
12445        if (app == mHomeProcess) {
12446            mHomeProcess = null;
12447        }
12448        if (app == mPreviousProcess) {
12449            mPreviousProcess = null;
12450        }
12451
12452        if (restart && !app.isolated) {
12453            // We have components that still need to be running in the
12454            // process, so re-launch it.
12455            mProcessNames.put(app.processName, app.uid, app);
12456            startProcessLocked(app, "restart", app.processName);
12457        } else if (app.pid > 0 && app.pid != MY_PID) {
12458            // Goodbye!
12459            synchronized (mPidsSelfLocked) {
12460                mPidsSelfLocked.remove(app.pid);
12461                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12462            }
12463            app.setPid(0);
12464        }
12465    }
12466
12467    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12468        // Look through the content providers we are waiting to have launched,
12469        // and if any run in this process then either schedule a restart of
12470        // the process or kill the client waiting for it if this process has
12471        // gone bad.
12472        int NL = mLaunchingProviders.size();
12473        boolean restart = false;
12474        for (int i=0; i<NL; i++) {
12475            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12476            if (cpr.launchingApp == app) {
12477                if (!alwaysBad && !app.bad) {
12478                    restart = true;
12479                } else {
12480                    removeDyingProviderLocked(app, cpr, true);
12481                    // cpr should have been removed from mLaunchingProviders
12482                    NL = mLaunchingProviders.size();
12483                    i--;
12484                }
12485            }
12486        }
12487        return restart;
12488    }
12489
12490    // =========================================================
12491    // SERVICES
12492    // =========================================================
12493
12494    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12495            int flags) {
12496        enforceNotIsolatedCaller("getServices");
12497        synchronized (this) {
12498            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12499        }
12500    }
12501
12502    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12503        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12504        synchronized (this) {
12505            return mServices.getRunningServiceControlPanelLocked(name);
12506        }
12507    }
12508
12509    public ComponentName startService(IApplicationThread caller, Intent service,
12510            String resolvedType, int userId) {
12511        enforceNotIsolatedCaller("startService");
12512        // Refuse possible leaked file descriptors
12513        if (service != null && service.hasFileDescriptors() == true) {
12514            throw new IllegalArgumentException("File descriptors passed in Intent");
12515        }
12516
12517        if (DEBUG_SERVICE)
12518            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12519        synchronized(this) {
12520            final int callingPid = Binder.getCallingPid();
12521            final int callingUid = Binder.getCallingUid();
12522            final long origId = Binder.clearCallingIdentity();
12523            ComponentName res = mServices.startServiceLocked(caller, service,
12524                    resolvedType, callingPid, callingUid, userId);
12525            Binder.restoreCallingIdentity(origId);
12526            return res;
12527        }
12528    }
12529
12530    ComponentName startServiceInPackage(int uid,
12531            Intent service, String resolvedType, int userId) {
12532        synchronized(this) {
12533            if (DEBUG_SERVICE)
12534                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12535            final long origId = Binder.clearCallingIdentity();
12536            ComponentName res = mServices.startServiceLocked(null, service,
12537                    resolvedType, -1, uid, userId);
12538            Binder.restoreCallingIdentity(origId);
12539            return res;
12540        }
12541    }
12542
12543    public int stopService(IApplicationThread caller, Intent service,
12544            String resolvedType, int userId) {
12545        enforceNotIsolatedCaller("stopService");
12546        // Refuse possible leaked file descriptors
12547        if (service != null && service.hasFileDescriptors() == true) {
12548            throw new IllegalArgumentException("File descriptors passed in Intent");
12549        }
12550
12551        synchronized(this) {
12552            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12553        }
12554    }
12555
12556    public IBinder peekService(Intent service, String resolvedType) {
12557        enforceNotIsolatedCaller("peekService");
12558        // Refuse possible leaked file descriptors
12559        if (service != null && service.hasFileDescriptors() == true) {
12560            throw new IllegalArgumentException("File descriptors passed in Intent");
12561        }
12562        synchronized(this) {
12563            return mServices.peekServiceLocked(service, resolvedType);
12564        }
12565    }
12566
12567    public boolean stopServiceToken(ComponentName className, IBinder token,
12568            int startId) {
12569        synchronized(this) {
12570            return mServices.stopServiceTokenLocked(className, token, startId);
12571        }
12572    }
12573
12574    public void setServiceForeground(ComponentName className, IBinder token,
12575            int id, Notification notification, boolean removeNotification) {
12576        synchronized(this) {
12577            mServices.setServiceForegroundLocked(className, token, id, notification,
12578                    removeNotification);
12579        }
12580    }
12581
12582    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12583            boolean requireFull, String name, String callerPackage) {
12584        final int callingUserId = UserHandle.getUserId(callingUid);
12585        if (callingUserId != userId) {
12586            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12587                if ((requireFull || checkComponentPermission(
12588                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12589                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12590                        && checkComponentPermission(
12591                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12592                                callingPid, callingUid, -1, true)
12593                                != PackageManager.PERMISSION_GRANTED) {
12594                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12595                        // In this case, they would like to just execute as their
12596                        // owner user instead of failing.
12597                        userId = callingUserId;
12598                    } else {
12599                        StringBuilder builder = new StringBuilder(128);
12600                        builder.append("Permission Denial: ");
12601                        builder.append(name);
12602                        if (callerPackage != null) {
12603                            builder.append(" from ");
12604                            builder.append(callerPackage);
12605                        }
12606                        builder.append(" asks to run as user ");
12607                        builder.append(userId);
12608                        builder.append(" but is calling from user ");
12609                        builder.append(UserHandle.getUserId(callingUid));
12610                        builder.append("; this requires ");
12611                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12612                        if (!requireFull) {
12613                            builder.append(" or ");
12614                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12615                        }
12616                        String msg = builder.toString();
12617                        Slog.w(TAG, msg);
12618                        throw new SecurityException(msg);
12619                    }
12620                }
12621            }
12622            if (userId == UserHandle.USER_CURRENT
12623                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12624                // Note that we may be accessing this outside of a lock...
12625                // shouldn't be a big deal, if this is being called outside
12626                // of a locked context there is intrinsically a race with
12627                // the value the caller will receive and someone else changing it.
12628                userId = mCurrentUserId;
12629            }
12630            if (!allowAll && userId < 0) {
12631                throw new IllegalArgumentException(
12632                        "Call does not support special user #" + userId);
12633            }
12634        }
12635        return userId;
12636    }
12637
12638    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12639            String className, int flags) {
12640        boolean result = false;
12641        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12642            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12643                if (ActivityManager.checkUidPermission(
12644                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12645                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12646                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12647                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12648                            + " requests FLAG_SINGLE_USER, but app does not hold "
12649                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12650                    Slog.w(TAG, msg);
12651                    throw new SecurityException(msg);
12652                }
12653                result = true;
12654            }
12655        } else if (componentProcessName == aInfo.packageName) {
12656            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12657        } else if ("system".equals(componentProcessName)) {
12658            result = true;
12659        }
12660        if (DEBUG_MU) {
12661            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12662                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12663        }
12664        return result;
12665    }
12666
12667    public int bindService(IApplicationThread caller, IBinder token,
12668            Intent service, String resolvedType,
12669            IServiceConnection connection, int flags, int userId) {
12670        enforceNotIsolatedCaller("bindService");
12671        // Refuse possible leaked file descriptors
12672        if (service != null && service.hasFileDescriptors() == true) {
12673            throw new IllegalArgumentException("File descriptors passed in Intent");
12674        }
12675
12676        synchronized(this) {
12677            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12678                    connection, flags, userId);
12679        }
12680    }
12681
12682    public boolean unbindService(IServiceConnection connection) {
12683        synchronized (this) {
12684            return mServices.unbindServiceLocked(connection);
12685        }
12686    }
12687
12688    public void publishService(IBinder token, Intent intent, IBinder service) {
12689        // Refuse possible leaked file descriptors
12690        if (intent != null && intent.hasFileDescriptors() == true) {
12691            throw new IllegalArgumentException("File descriptors passed in Intent");
12692        }
12693
12694        synchronized(this) {
12695            if (!(token instanceof ServiceRecord)) {
12696                throw new IllegalArgumentException("Invalid service token");
12697            }
12698            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12699        }
12700    }
12701
12702    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12703        // Refuse possible leaked file descriptors
12704        if (intent != null && intent.hasFileDescriptors() == true) {
12705            throw new IllegalArgumentException("File descriptors passed in Intent");
12706        }
12707
12708        synchronized(this) {
12709            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12710        }
12711    }
12712
12713    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12714        synchronized(this) {
12715            if (!(token instanceof ServiceRecord)) {
12716                throw new IllegalArgumentException("Invalid service token");
12717            }
12718            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12719        }
12720    }
12721
12722    // =========================================================
12723    // BACKUP AND RESTORE
12724    // =========================================================
12725
12726    // Cause the target app to be launched if necessary and its backup agent
12727    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12728    // activity manager to announce its creation.
12729    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12730        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12731        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12732
12733        synchronized(this) {
12734            // !!! TODO: currently no check here that we're already bound
12735            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12736            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12737            synchronized (stats) {
12738                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12739            }
12740
12741            // Backup agent is now in use, its package can't be stopped.
12742            try {
12743                AppGlobals.getPackageManager().setPackageStoppedState(
12744                        app.packageName, false, UserHandle.getUserId(app.uid));
12745            } catch (RemoteException e) {
12746            } catch (IllegalArgumentException e) {
12747                Slog.w(TAG, "Failed trying to unstop package "
12748                        + app.packageName + ": " + e);
12749            }
12750
12751            BackupRecord r = new BackupRecord(ss, app, backupMode);
12752            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12753                    ? new ComponentName(app.packageName, app.backupAgentName)
12754                    : new ComponentName("android", "FullBackupAgent");
12755            // startProcessLocked() returns existing proc's record if it's already running
12756            ProcessRecord proc = startProcessLocked(app.processName, app,
12757                    false, 0, "backup", hostingName, false, false, false);
12758            if (proc == null) {
12759                Slog.e(TAG, "Unable to start backup agent process " + r);
12760                return false;
12761            }
12762
12763            r.app = proc;
12764            mBackupTarget = r;
12765            mBackupAppName = app.packageName;
12766
12767            // Try not to kill the process during backup
12768            updateOomAdjLocked(proc);
12769
12770            // If the process is already attached, schedule the creation of the backup agent now.
12771            // If it is not yet live, this will be done when it attaches to the framework.
12772            if (proc.thread != null) {
12773                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12774                try {
12775                    proc.thread.scheduleCreateBackupAgent(app,
12776                            compatibilityInfoForPackageLocked(app), backupMode);
12777                } catch (RemoteException e) {
12778                    // Will time out on the backup manager side
12779                }
12780            } else {
12781                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12782            }
12783            // Invariants: at this point, the target app process exists and the application
12784            // is either already running or in the process of coming up.  mBackupTarget and
12785            // mBackupAppName describe the app, so that when it binds back to the AM we
12786            // know that it's scheduled for a backup-agent operation.
12787        }
12788
12789        return true;
12790    }
12791
12792    @Override
12793    public void clearPendingBackup() {
12794        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12795        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12796
12797        synchronized (this) {
12798            mBackupTarget = null;
12799            mBackupAppName = null;
12800        }
12801    }
12802
12803    // A backup agent has just come up
12804    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12805        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12806                + " = " + agent);
12807
12808        synchronized(this) {
12809            if (!agentPackageName.equals(mBackupAppName)) {
12810                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12811                return;
12812            }
12813        }
12814
12815        long oldIdent = Binder.clearCallingIdentity();
12816        try {
12817            IBackupManager bm = IBackupManager.Stub.asInterface(
12818                    ServiceManager.getService(Context.BACKUP_SERVICE));
12819            bm.agentConnected(agentPackageName, agent);
12820        } catch (RemoteException e) {
12821            // can't happen; the backup manager service is local
12822        } catch (Exception e) {
12823            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12824            e.printStackTrace();
12825        } finally {
12826            Binder.restoreCallingIdentity(oldIdent);
12827        }
12828    }
12829
12830    // done with this agent
12831    public void unbindBackupAgent(ApplicationInfo appInfo) {
12832        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12833        if (appInfo == null) {
12834            Slog.w(TAG, "unbind backup agent for null app");
12835            return;
12836        }
12837
12838        synchronized(this) {
12839            try {
12840                if (mBackupAppName == null) {
12841                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12842                    return;
12843                }
12844
12845                if (!mBackupAppName.equals(appInfo.packageName)) {
12846                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12847                    return;
12848                }
12849
12850                // Not backing this app up any more; reset its OOM adjustment
12851                final ProcessRecord proc = mBackupTarget.app;
12852                updateOomAdjLocked(proc);
12853
12854                // If the app crashed during backup, 'thread' will be null here
12855                if (proc.thread != null) {
12856                    try {
12857                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12858                                compatibilityInfoForPackageLocked(appInfo));
12859                    } catch (Exception e) {
12860                        Slog.e(TAG, "Exception when unbinding backup agent:");
12861                        e.printStackTrace();
12862                    }
12863                }
12864            } finally {
12865                mBackupTarget = null;
12866                mBackupAppName = null;
12867            }
12868        }
12869    }
12870    // =========================================================
12871    // BROADCASTS
12872    // =========================================================
12873
12874    private final List getStickiesLocked(String action, IntentFilter filter,
12875            List cur, int userId) {
12876        final ContentResolver resolver = mContext.getContentResolver();
12877        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12878        if (stickies == null) {
12879            return cur;
12880        }
12881        final ArrayList<Intent> list = stickies.get(action);
12882        if (list == null) {
12883            return cur;
12884        }
12885        int N = list.size();
12886        for (int i=0; i<N; i++) {
12887            Intent intent = list.get(i);
12888            if (filter.match(resolver, intent, true, TAG) >= 0) {
12889                if (cur == null) {
12890                    cur = new ArrayList<Intent>();
12891                }
12892                cur.add(intent);
12893            }
12894        }
12895        return cur;
12896    }
12897
12898    boolean isPendingBroadcastProcessLocked(int pid) {
12899        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12900                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12901    }
12902
12903    void skipPendingBroadcastLocked(int pid) {
12904            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12905            for (BroadcastQueue queue : mBroadcastQueues) {
12906                queue.skipPendingBroadcastLocked(pid);
12907            }
12908    }
12909
12910    // The app just attached; send any pending broadcasts that it should receive
12911    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12912        boolean didSomething = false;
12913        for (BroadcastQueue queue : mBroadcastQueues) {
12914            didSomething |= queue.sendPendingBroadcastsLocked(app);
12915        }
12916        return didSomething;
12917    }
12918
12919    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12920            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12921        enforceNotIsolatedCaller("registerReceiver");
12922        int callingUid;
12923        int callingPid;
12924        synchronized(this) {
12925            ProcessRecord callerApp = null;
12926            if (caller != null) {
12927                callerApp = getRecordForAppLocked(caller);
12928                if (callerApp == null) {
12929                    throw new SecurityException(
12930                            "Unable to find app for caller " + caller
12931                            + " (pid=" + Binder.getCallingPid()
12932                            + ") when registering receiver " + receiver);
12933                }
12934                if (callerApp.info.uid != Process.SYSTEM_UID &&
12935                        !callerApp.pkgList.containsKey(callerPackage) &&
12936                        !"android".equals(callerPackage)) {
12937                    throw new SecurityException("Given caller package " + callerPackage
12938                            + " is not running in process " + callerApp);
12939                }
12940                callingUid = callerApp.info.uid;
12941                callingPid = callerApp.pid;
12942            } else {
12943                callerPackage = null;
12944                callingUid = Binder.getCallingUid();
12945                callingPid = Binder.getCallingPid();
12946            }
12947
12948            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12949                    true, true, "registerReceiver", callerPackage);
12950
12951            List allSticky = null;
12952
12953            // Look for any matching sticky broadcasts...
12954            Iterator actions = filter.actionsIterator();
12955            if (actions != null) {
12956                while (actions.hasNext()) {
12957                    String action = (String)actions.next();
12958                    allSticky = getStickiesLocked(action, filter, allSticky,
12959                            UserHandle.USER_ALL);
12960                    allSticky = getStickiesLocked(action, filter, allSticky,
12961                            UserHandle.getUserId(callingUid));
12962                }
12963            } else {
12964                allSticky = getStickiesLocked(null, filter, allSticky,
12965                        UserHandle.USER_ALL);
12966                allSticky = getStickiesLocked(null, filter, allSticky,
12967                        UserHandle.getUserId(callingUid));
12968            }
12969
12970            // The first sticky in the list is returned directly back to
12971            // the client.
12972            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12973
12974            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12975                    + ": " + sticky);
12976
12977            if (receiver == null) {
12978                return sticky;
12979            }
12980
12981            ReceiverList rl
12982                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12983            if (rl == null) {
12984                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
12985                        userId, receiver);
12986                if (rl.app != null) {
12987                    rl.app.receivers.add(rl);
12988                } else {
12989                    try {
12990                        receiver.asBinder().linkToDeath(rl, 0);
12991                    } catch (RemoteException e) {
12992                        return sticky;
12993                    }
12994                    rl.linkedToDeath = true;
12995                }
12996                mRegisteredReceivers.put(receiver.asBinder(), rl);
12997            } else if (rl.uid != callingUid) {
12998                throw new IllegalArgumentException(
12999                        "Receiver requested to register for uid " + callingUid
13000                        + " was previously registered for uid " + rl.uid);
13001            } else if (rl.pid != callingPid) {
13002                throw new IllegalArgumentException(
13003                        "Receiver requested to register for pid " + callingPid
13004                        + " was previously registered for pid " + rl.pid);
13005            } else if (rl.userId != userId) {
13006                throw new IllegalArgumentException(
13007                        "Receiver requested to register for user " + userId
13008                        + " was previously registered for user " + rl.userId);
13009            }
13010            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13011                    permission, callingUid, userId);
13012            rl.add(bf);
13013            if (!bf.debugCheck()) {
13014                Slog.w(TAG, "==> For Dynamic broadast");
13015            }
13016            mReceiverResolver.addFilter(bf);
13017
13018            // Enqueue broadcasts for all existing stickies that match
13019            // this filter.
13020            if (allSticky != null) {
13021                ArrayList receivers = new ArrayList();
13022                receivers.add(bf);
13023
13024                int N = allSticky.size();
13025                for (int i=0; i<N; i++) {
13026                    Intent intent = (Intent)allSticky.get(i);
13027                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13028                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13029                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13030                            null, null, false, true, true, -1);
13031                    queue.enqueueParallelBroadcastLocked(r);
13032                    queue.scheduleBroadcastsLocked();
13033                }
13034            }
13035
13036            return sticky;
13037        }
13038    }
13039
13040    public void unregisterReceiver(IIntentReceiver receiver) {
13041        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13042
13043        final long origId = Binder.clearCallingIdentity();
13044        try {
13045            boolean doTrim = false;
13046
13047            synchronized(this) {
13048                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13049                if (rl != null) {
13050                    if (rl.curBroadcast != null) {
13051                        BroadcastRecord r = rl.curBroadcast;
13052                        final boolean doNext = finishReceiverLocked(
13053                                receiver.asBinder(), r.resultCode, r.resultData,
13054                                r.resultExtras, r.resultAbort);
13055                        if (doNext) {
13056                            doTrim = true;
13057                            r.queue.processNextBroadcast(false);
13058                        }
13059                    }
13060
13061                    if (rl.app != null) {
13062                        rl.app.receivers.remove(rl);
13063                    }
13064                    removeReceiverLocked(rl);
13065                    if (rl.linkedToDeath) {
13066                        rl.linkedToDeath = false;
13067                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13068                    }
13069                }
13070            }
13071
13072            // If we actually concluded any broadcasts, we might now be able
13073            // to trim the recipients' apps from our working set
13074            if (doTrim) {
13075                trimApplications();
13076                return;
13077            }
13078
13079        } finally {
13080            Binder.restoreCallingIdentity(origId);
13081        }
13082    }
13083
13084    void removeReceiverLocked(ReceiverList rl) {
13085        mRegisteredReceivers.remove(rl.receiver.asBinder());
13086        int N = rl.size();
13087        for (int i=0; i<N; i++) {
13088            mReceiverResolver.removeFilter(rl.get(i));
13089        }
13090    }
13091
13092    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13093        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13094            ProcessRecord r = mLruProcesses.get(i);
13095            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13096                try {
13097                    r.thread.dispatchPackageBroadcast(cmd, packages);
13098                } catch (RemoteException ex) {
13099                }
13100            }
13101        }
13102    }
13103
13104    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13105            int[] users) {
13106        List<ResolveInfo> receivers = null;
13107        try {
13108            HashSet<ComponentName> singleUserReceivers = null;
13109            boolean scannedFirstReceivers = false;
13110            for (int user : users) {
13111                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13112                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13113                if (user != 0 && newReceivers != null) {
13114                    // If this is not the primary user, we need to check for
13115                    // any receivers that should be filtered out.
13116                    for (int i=0; i<newReceivers.size(); i++) {
13117                        ResolveInfo ri = newReceivers.get(i);
13118                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13119                            newReceivers.remove(i);
13120                            i--;
13121                        }
13122                    }
13123                }
13124                if (newReceivers != null && newReceivers.size() == 0) {
13125                    newReceivers = null;
13126                }
13127                if (receivers == null) {
13128                    receivers = newReceivers;
13129                } else if (newReceivers != null) {
13130                    // We need to concatenate the additional receivers
13131                    // found with what we have do far.  This would be easy,
13132                    // but we also need to de-dup any receivers that are
13133                    // singleUser.
13134                    if (!scannedFirstReceivers) {
13135                        // Collect any single user receivers we had already retrieved.
13136                        scannedFirstReceivers = true;
13137                        for (int i=0; i<receivers.size(); i++) {
13138                            ResolveInfo ri = receivers.get(i);
13139                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13140                                ComponentName cn = new ComponentName(
13141                                        ri.activityInfo.packageName, ri.activityInfo.name);
13142                                if (singleUserReceivers == null) {
13143                                    singleUserReceivers = new HashSet<ComponentName>();
13144                                }
13145                                singleUserReceivers.add(cn);
13146                            }
13147                        }
13148                    }
13149                    // Add the new results to the existing results, tracking
13150                    // and de-dupping single user receivers.
13151                    for (int i=0; i<newReceivers.size(); i++) {
13152                        ResolveInfo ri = newReceivers.get(i);
13153                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13154                            ComponentName cn = new ComponentName(
13155                                    ri.activityInfo.packageName, ri.activityInfo.name);
13156                            if (singleUserReceivers == null) {
13157                                singleUserReceivers = new HashSet<ComponentName>();
13158                            }
13159                            if (!singleUserReceivers.contains(cn)) {
13160                                singleUserReceivers.add(cn);
13161                                receivers.add(ri);
13162                            }
13163                        } else {
13164                            receivers.add(ri);
13165                        }
13166                    }
13167                }
13168            }
13169        } catch (RemoteException ex) {
13170            // pm is in same process, this will never happen.
13171        }
13172        return receivers;
13173    }
13174
13175    private final int broadcastIntentLocked(ProcessRecord callerApp,
13176            String callerPackage, Intent intent, String resolvedType,
13177            IIntentReceiver resultTo, int resultCode, String resultData,
13178            Bundle map, String requiredPermission, int appOp,
13179            boolean ordered, boolean sticky, int callingPid, int callingUid,
13180            int userId) {
13181        intent = new Intent(intent);
13182
13183        // By default broadcasts do not go to stopped apps.
13184        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13185
13186        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13187            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13188            + " ordered=" + ordered + " userid=" + userId);
13189        if ((resultTo != null) && !ordered) {
13190            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13191        }
13192
13193        userId = handleIncomingUser(callingPid, callingUid, userId,
13194                true, false, "broadcast", callerPackage);
13195
13196        // Make sure that the user who is receiving this broadcast is started.
13197        // If not, we will just skip it.
13198        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13199            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13200                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13201                Slog.w(TAG, "Skipping broadcast of " + intent
13202                        + ": user " + userId + " is stopped");
13203                return ActivityManager.BROADCAST_SUCCESS;
13204            }
13205        }
13206
13207        /*
13208         * Prevent non-system code (defined here to be non-persistent
13209         * processes) from sending protected broadcasts.
13210         */
13211        int callingAppId = UserHandle.getAppId(callingUid);
13212        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13213            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13214            callingUid == 0) {
13215            // Always okay.
13216        } else if (callerApp == null || !callerApp.persistent) {
13217            try {
13218                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13219                        intent.getAction())) {
13220                    String msg = "Permission Denial: not allowed to send broadcast "
13221                            + intent.getAction() + " from pid="
13222                            + callingPid + ", uid=" + callingUid;
13223                    Slog.w(TAG, msg);
13224                    throw new SecurityException(msg);
13225                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13226                    // Special case for compatibility: we don't want apps to send this,
13227                    // but historically it has not been protected and apps may be using it
13228                    // to poke their own app widget.  So, instead of making it protected,
13229                    // just limit it to the caller.
13230                    if (callerApp == null) {
13231                        String msg = "Permission Denial: not allowed to send broadcast "
13232                                + intent.getAction() + " from unknown caller.";
13233                        Slog.w(TAG, msg);
13234                        throw new SecurityException(msg);
13235                    } else if (intent.getComponent() != null) {
13236                        // They are good enough to send to an explicit component...  verify
13237                        // it is being sent to the calling app.
13238                        if (!intent.getComponent().getPackageName().equals(
13239                                callerApp.info.packageName)) {
13240                            String msg = "Permission Denial: not allowed to send broadcast "
13241                                    + intent.getAction() + " to "
13242                                    + intent.getComponent().getPackageName() + " from "
13243                                    + callerApp.info.packageName;
13244                            Slog.w(TAG, msg);
13245                            throw new SecurityException(msg);
13246                        }
13247                    } else {
13248                        // Limit broadcast to their own package.
13249                        intent.setPackage(callerApp.info.packageName);
13250                    }
13251                }
13252            } catch (RemoteException e) {
13253                Slog.w(TAG, "Remote exception", e);
13254                return ActivityManager.BROADCAST_SUCCESS;
13255            }
13256        }
13257
13258        // Handle special intents: if this broadcast is from the package
13259        // manager about a package being removed, we need to remove all of
13260        // its activities from the history stack.
13261        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13262                intent.getAction());
13263        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13264                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13265                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13266                || uidRemoved) {
13267            if (checkComponentPermission(
13268                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13269                    callingPid, callingUid, -1, true)
13270                    == PackageManager.PERMISSION_GRANTED) {
13271                if (uidRemoved) {
13272                    final Bundle intentExtras = intent.getExtras();
13273                    final int uid = intentExtras != null
13274                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13275                    if (uid >= 0) {
13276                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13277                        synchronized (bs) {
13278                            bs.removeUidStatsLocked(uid);
13279                        }
13280                        mAppOpsService.uidRemoved(uid);
13281                    }
13282                } else {
13283                    // If resources are unavailable just force stop all
13284                    // those packages and flush the attribute cache as well.
13285                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13286                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13287                        if (list != null && (list.length > 0)) {
13288                            for (String pkg : list) {
13289                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
13290                                        "storage unmount");
13291                            }
13292                            sendPackageBroadcastLocked(
13293                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13294                        }
13295                    } else {
13296                        Uri data = intent.getData();
13297                        String ssp;
13298                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13299                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13300                                    intent.getAction());
13301                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13302                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13303                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13304                                        false, userId, removed ? "pkg removed" : "pkg changed");
13305                            }
13306                            if (removed) {
13307                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13308                                        new String[] {ssp}, userId);
13309                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13310                                    mAppOpsService.packageRemoved(
13311                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13312
13313                                    // Remove all permissions granted from/to this package
13314                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13315                                }
13316                            }
13317                        }
13318                    }
13319                }
13320            } else {
13321                String msg = "Permission Denial: " + intent.getAction()
13322                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13323                        + ", uid=" + callingUid + ")"
13324                        + " requires "
13325                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13326                Slog.w(TAG, msg);
13327                throw new SecurityException(msg);
13328            }
13329
13330        // Special case for adding a package: by default turn on compatibility
13331        // mode.
13332        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13333            Uri data = intent.getData();
13334            String ssp;
13335            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13336                mCompatModePackages.handlePackageAddedLocked(ssp,
13337                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13338            }
13339        }
13340
13341        /*
13342         * If this is the time zone changed action, queue up a message that will reset the timezone
13343         * of all currently running processes. This message will get queued up before the broadcast
13344         * happens.
13345         */
13346        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13347            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13348        }
13349
13350        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13351            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13352        }
13353
13354        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13355            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13356            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13357        }
13358
13359        // Add to the sticky list if requested.
13360        if (sticky) {
13361            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13362                    callingPid, callingUid)
13363                    != PackageManager.PERMISSION_GRANTED) {
13364                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13365                        + callingPid + ", uid=" + callingUid
13366                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13367                Slog.w(TAG, msg);
13368                throw new SecurityException(msg);
13369            }
13370            if (requiredPermission != null) {
13371                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13372                        + " and enforce permission " + requiredPermission);
13373                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13374            }
13375            if (intent.getComponent() != null) {
13376                throw new SecurityException(
13377                        "Sticky broadcasts can't target a specific component");
13378            }
13379            // We use userId directly here, since the "all" target is maintained
13380            // as a separate set of sticky broadcasts.
13381            if (userId != UserHandle.USER_ALL) {
13382                // But first, if this is not a broadcast to all users, then
13383                // make sure it doesn't conflict with an existing broadcast to
13384                // all users.
13385                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13386                        UserHandle.USER_ALL);
13387                if (stickies != null) {
13388                    ArrayList<Intent> list = stickies.get(intent.getAction());
13389                    if (list != null) {
13390                        int N = list.size();
13391                        int i;
13392                        for (i=0; i<N; i++) {
13393                            if (intent.filterEquals(list.get(i))) {
13394                                throw new IllegalArgumentException(
13395                                        "Sticky broadcast " + intent + " for user "
13396                                        + userId + " conflicts with existing global broadcast");
13397                            }
13398                        }
13399                    }
13400                }
13401            }
13402            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13403            if (stickies == null) {
13404                stickies = new ArrayMap<String, ArrayList<Intent>>();
13405                mStickyBroadcasts.put(userId, stickies);
13406            }
13407            ArrayList<Intent> list = stickies.get(intent.getAction());
13408            if (list == null) {
13409                list = new ArrayList<Intent>();
13410                stickies.put(intent.getAction(), list);
13411            }
13412            int N = list.size();
13413            int i;
13414            for (i=0; i<N; i++) {
13415                if (intent.filterEquals(list.get(i))) {
13416                    // This sticky already exists, replace it.
13417                    list.set(i, new Intent(intent));
13418                    break;
13419                }
13420            }
13421            if (i >= N) {
13422                list.add(new Intent(intent));
13423            }
13424        }
13425
13426        int[] users;
13427        if (userId == UserHandle.USER_ALL) {
13428            // Caller wants broadcast to go to all started users.
13429            users = mStartedUserArray;
13430        } else {
13431            // Caller wants broadcast to go to one specific user.
13432            users = new int[] {userId};
13433        }
13434
13435        // Figure out who all will receive this broadcast.
13436        List receivers = null;
13437        List<BroadcastFilter> registeredReceivers = null;
13438        // Need to resolve the intent to interested receivers...
13439        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13440                 == 0) {
13441            receivers = collectReceiverComponents(intent, resolvedType, users);
13442        }
13443        if (intent.getComponent() == null) {
13444            registeredReceivers = mReceiverResolver.queryIntent(intent,
13445                    resolvedType, false, userId);
13446        }
13447
13448        final boolean replacePending =
13449                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13450
13451        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13452                + " replacePending=" + replacePending);
13453
13454        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13455        if (!ordered && NR > 0) {
13456            // If we are not serializing this broadcast, then send the
13457            // registered receivers separately so they don't wait for the
13458            // components to be launched.
13459            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13460            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13461                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13462                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13463                    ordered, sticky, false, userId);
13464            if (DEBUG_BROADCAST) Slog.v(
13465                    TAG, "Enqueueing parallel broadcast " + r);
13466            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13467            if (!replaced) {
13468                queue.enqueueParallelBroadcastLocked(r);
13469                queue.scheduleBroadcastsLocked();
13470            }
13471            registeredReceivers = null;
13472            NR = 0;
13473        }
13474
13475        // Merge into one list.
13476        int ir = 0;
13477        if (receivers != null) {
13478            // A special case for PACKAGE_ADDED: do not allow the package
13479            // being added to see this broadcast.  This prevents them from
13480            // using this as a back door to get run as soon as they are
13481            // installed.  Maybe in the future we want to have a special install
13482            // broadcast or such for apps, but we'd like to deliberately make
13483            // this decision.
13484            String skipPackages[] = null;
13485            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13486                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13487                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13488                Uri data = intent.getData();
13489                if (data != null) {
13490                    String pkgName = data.getSchemeSpecificPart();
13491                    if (pkgName != null) {
13492                        skipPackages = new String[] { pkgName };
13493                    }
13494                }
13495            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13496                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13497            }
13498            if (skipPackages != null && (skipPackages.length > 0)) {
13499                for (String skipPackage : skipPackages) {
13500                    if (skipPackage != null) {
13501                        int NT = receivers.size();
13502                        for (int it=0; it<NT; it++) {
13503                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13504                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13505                                receivers.remove(it);
13506                                it--;
13507                                NT--;
13508                            }
13509                        }
13510                    }
13511                }
13512            }
13513
13514            int NT = receivers != null ? receivers.size() : 0;
13515            int it = 0;
13516            ResolveInfo curt = null;
13517            BroadcastFilter curr = null;
13518            while (it < NT && ir < NR) {
13519                if (curt == null) {
13520                    curt = (ResolveInfo)receivers.get(it);
13521                }
13522                if (curr == null) {
13523                    curr = registeredReceivers.get(ir);
13524                }
13525                if (curr.getPriority() >= curt.priority) {
13526                    // Insert this broadcast record into the final list.
13527                    receivers.add(it, curr);
13528                    ir++;
13529                    curr = null;
13530                    it++;
13531                    NT++;
13532                } else {
13533                    // Skip to the next ResolveInfo in the final list.
13534                    it++;
13535                    curt = null;
13536                }
13537            }
13538        }
13539        while (ir < NR) {
13540            if (receivers == null) {
13541                receivers = new ArrayList();
13542            }
13543            receivers.add(registeredReceivers.get(ir));
13544            ir++;
13545        }
13546
13547        if ((receivers != null && receivers.size() > 0)
13548                || resultTo != null) {
13549            BroadcastQueue queue = broadcastQueueForIntent(intent);
13550            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13551                    callerPackage, callingPid, callingUid, resolvedType,
13552                    requiredPermission, appOp, receivers, resultTo, resultCode,
13553                    resultData, map, ordered, sticky, false, userId);
13554            if (DEBUG_BROADCAST) Slog.v(
13555                    TAG, "Enqueueing ordered broadcast " + r
13556                    + ": prev had " + queue.mOrderedBroadcasts.size());
13557            if (DEBUG_BROADCAST) {
13558                int seq = r.intent.getIntExtra("seq", -1);
13559                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13560            }
13561            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13562            if (!replaced) {
13563                queue.enqueueOrderedBroadcastLocked(r);
13564                queue.scheduleBroadcastsLocked();
13565            }
13566        }
13567
13568        return ActivityManager.BROADCAST_SUCCESS;
13569    }
13570
13571    final Intent verifyBroadcastLocked(Intent intent) {
13572        // Refuse possible leaked file descriptors
13573        if (intent != null && intent.hasFileDescriptors() == true) {
13574            throw new IllegalArgumentException("File descriptors passed in Intent");
13575        }
13576
13577        int flags = intent.getFlags();
13578
13579        if (!mProcessesReady) {
13580            // if the caller really truly claims to know what they're doing, go
13581            // ahead and allow the broadcast without launching any receivers
13582            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13583                intent = new Intent(intent);
13584                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13585            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13586                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13587                        + " before boot completion");
13588                throw new IllegalStateException("Cannot broadcast before boot completed");
13589            }
13590        }
13591
13592        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13593            throw new IllegalArgumentException(
13594                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13595        }
13596
13597        return intent;
13598    }
13599
13600    public final int broadcastIntent(IApplicationThread caller,
13601            Intent intent, String resolvedType, IIntentReceiver resultTo,
13602            int resultCode, String resultData, Bundle map,
13603            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13604        enforceNotIsolatedCaller("broadcastIntent");
13605        synchronized(this) {
13606            intent = verifyBroadcastLocked(intent);
13607
13608            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13609            final int callingPid = Binder.getCallingPid();
13610            final int callingUid = Binder.getCallingUid();
13611            final long origId = Binder.clearCallingIdentity();
13612            int res = broadcastIntentLocked(callerApp,
13613                    callerApp != null ? callerApp.info.packageName : null,
13614                    intent, resolvedType, resultTo,
13615                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13616                    callingPid, callingUid, userId);
13617            Binder.restoreCallingIdentity(origId);
13618            return res;
13619        }
13620    }
13621
13622    int broadcastIntentInPackage(String packageName, int uid,
13623            Intent intent, String resolvedType, IIntentReceiver resultTo,
13624            int resultCode, String resultData, Bundle map,
13625            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13626        synchronized(this) {
13627            intent = verifyBroadcastLocked(intent);
13628
13629            final long origId = Binder.clearCallingIdentity();
13630            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13631                    resultTo, resultCode, resultData, map, requiredPermission,
13632                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13633            Binder.restoreCallingIdentity(origId);
13634            return res;
13635        }
13636    }
13637
13638    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13639        // Refuse possible leaked file descriptors
13640        if (intent != null && intent.hasFileDescriptors() == true) {
13641            throw new IllegalArgumentException("File descriptors passed in Intent");
13642        }
13643
13644        userId = handleIncomingUser(Binder.getCallingPid(),
13645                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13646
13647        synchronized(this) {
13648            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13649                    != PackageManager.PERMISSION_GRANTED) {
13650                String msg = "Permission Denial: unbroadcastIntent() from pid="
13651                        + Binder.getCallingPid()
13652                        + ", uid=" + Binder.getCallingUid()
13653                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13654                Slog.w(TAG, msg);
13655                throw new SecurityException(msg);
13656            }
13657            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13658            if (stickies != null) {
13659                ArrayList<Intent> list = stickies.get(intent.getAction());
13660                if (list != null) {
13661                    int N = list.size();
13662                    int i;
13663                    for (i=0; i<N; i++) {
13664                        if (intent.filterEquals(list.get(i))) {
13665                            list.remove(i);
13666                            break;
13667                        }
13668                    }
13669                    if (list.size() <= 0) {
13670                        stickies.remove(intent.getAction());
13671                    }
13672                }
13673                if (stickies.size() <= 0) {
13674                    mStickyBroadcasts.remove(userId);
13675                }
13676            }
13677        }
13678    }
13679
13680    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13681            String resultData, Bundle resultExtras, boolean resultAbort) {
13682        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13683        if (r == null) {
13684            Slog.w(TAG, "finishReceiver called but not found on queue");
13685            return false;
13686        }
13687
13688        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13689    }
13690
13691    void backgroundServicesFinishedLocked(int userId) {
13692        for (BroadcastQueue queue : mBroadcastQueues) {
13693            queue.backgroundServicesFinishedLocked(userId);
13694        }
13695    }
13696
13697    public void finishReceiver(IBinder who, int resultCode, String resultData,
13698            Bundle resultExtras, boolean resultAbort) {
13699        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13700
13701        // Refuse possible leaked file descriptors
13702        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13703            throw new IllegalArgumentException("File descriptors passed in Bundle");
13704        }
13705
13706        final long origId = Binder.clearCallingIdentity();
13707        try {
13708            boolean doNext = false;
13709            BroadcastRecord r;
13710
13711            synchronized(this) {
13712                r = broadcastRecordForReceiverLocked(who);
13713                if (r != null) {
13714                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13715                        resultData, resultExtras, resultAbort, true);
13716                }
13717            }
13718
13719            if (doNext) {
13720                r.queue.processNextBroadcast(false);
13721            }
13722            trimApplications();
13723        } finally {
13724            Binder.restoreCallingIdentity(origId);
13725        }
13726    }
13727
13728    // =========================================================
13729    // INSTRUMENTATION
13730    // =========================================================
13731
13732    public boolean startInstrumentation(ComponentName className,
13733            String profileFile, int flags, Bundle arguments,
13734            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13735            int userId) {
13736        enforceNotIsolatedCaller("startInstrumentation");
13737        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13738                userId, false, true, "startInstrumentation", null);
13739        // Refuse possible leaked file descriptors
13740        if (arguments != null && arguments.hasFileDescriptors()) {
13741            throw new IllegalArgumentException("File descriptors passed in Bundle");
13742        }
13743
13744        synchronized(this) {
13745            InstrumentationInfo ii = null;
13746            ApplicationInfo ai = null;
13747            try {
13748                ii = mContext.getPackageManager().getInstrumentationInfo(
13749                    className, STOCK_PM_FLAGS);
13750                ai = AppGlobals.getPackageManager().getApplicationInfo(
13751                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13752            } catch (PackageManager.NameNotFoundException e) {
13753            } catch (RemoteException e) {
13754            }
13755            if (ii == null) {
13756                reportStartInstrumentationFailure(watcher, className,
13757                        "Unable to find instrumentation info for: " + className);
13758                return false;
13759            }
13760            if (ai == null) {
13761                reportStartInstrumentationFailure(watcher, className,
13762                        "Unable to find instrumentation target package: " + ii.targetPackage);
13763                return false;
13764            }
13765
13766            int match = mContext.getPackageManager().checkSignatures(
13767                    ii.targetPackage, ii.packageName);
13768            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13769                String msg = "Permission Denial: starting instrumentation "
13770                        + className + " from pid="
13771                        + Binder.getCallingPid()
13772                        + ", uid=" + Binder.getCallingPid()
13773                        + " not allowed because package " + ii.packageName
13774                        + " does not have a signature matching the target "
13775                        + ii.targetPackage;
13776                reportStartInstrumentationFailure(watcher, className, msg);
13777                throw new SecurityException(msg);
13778            }
13779
13780            final long origId = Binder.clearCallingIdentity();
13781            // Instrumentation can kill and relaunch even persistent processes
13782            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
13783                    "start instr");
13784            ProcessRecord app = addAppLocked(ai, false);
13785            app.instrumentationClass = className;
13786            app.instrumentationInfo = ai;
13787            app.instrumentationProfileFile = profileFile;
13788            app.instrumentationArguments = arguments;
13789            app.instrumentationWatcher = watcher;
13790            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13791            app.instrumentationResultClass = className;
13792            Binder.restoreCallingIdentity(origId);
13793        }
13794
13795        return true;
13796    }
13797
13798    /**
13799     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13800     * error to the logs, but if somebody is watching, send the report there too.  This enables
13801     * the "am" command to report errors with more information.
13802     *
13803     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13804     * @param cn The component name of the instrumentation.
13805     * @param report The error report.
13806     */
13807    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13808            ComponentName cn, String report) {
13809        Slog.w(TAG, report);
13810        try {
13811            if (watcher != null) {
13812                Bundle results = new Bundle();
13813                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13814                results.putString("Error", report);
13815                watcher.instrumentationStatus(cn, -1, results);
13816            }
13817        } catch (RemoteException e) {
13818            Slog.w(TAG, e);
13819        }
13820    }
13821
13822    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13823        if (app.instrumentationWatcher != null) {
13824            try {
13825                // NOTE:  IInstrumentationWatcher *must* be oneway here
13826                app.instrumentationWatcher.instrumentationFinished(
13827                    app.instrumentationClass,
13828                    resultCode,
13829                    results);
13830            } catch (RemoteException e) {
13831            }
13832        }
13833        if (app.instrumentationUiAutomationConnection != null) {
13834            try {
13835                app.instrumentationUiAutomationConnection.shutdown();
13836            } catch (RemoteException re) {
13837                /* ignore */
13838            }
13839            // Only a UiAutomation can set this flag and now that
13840            // it is finished we make sure it is reset to its default.
13841            mUserIsMonkey = false;
13842        }
13843        app.instrumentationWatcher = null;
13844        app.instrumentationUiAutomationConnection = null;
13845        app.instrumentationClass = null;
13846        app.instrumentationInfo = null;
13847        app.instrumentationProfileFile = null;
13848        app.instrumentationArguments = null;
13849
13850        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
13851                "finished inst");
13852    }
13853
13854    public void finishInstrumentation(IApplicationThread target,
13855            int resultCode, Bundle results) {
13856        int userId = UserHandle.getCallingUserId();
13857        // Refuse possible leaked file descriptors
13858        if (results != null && results.hasFileDescriptors()) {
13859            throw new IllegalArgumentException("File descriptors passed in Intent");
13860        }
13861
13862        synchronized(this) {
13863            ProcessRecord app = getRecordForAppLocked(target);
13864            if (app == null) {
13865                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13866                return;
13867            }
13868            final long origId = Binder.clearCallingIdentity();
13869            finishInstrumentationLocked(app, resultCode, results);
13870            Binder.restoreCallingIdentity(origId);
13871        }
13872    }
13873
13874    // =========================================================
13875    // CONFIGURATION
13876    // =========================================================
13877
13878    public ConfigurationInfo getDeviceConfigurationInfo() {
13879        ConfigurationInfo config = new ConfigurationInfo();
13880        synchronized (this) {
13881            config.reqTouchScreen = mConfiguration.touchscreen;
13882            config.reqKeyboardType = mConfiguration.keyboard;
13883            config.reqNavigation = mConfiguration.navigation;
13884            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13885                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13886                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13887            }
13888            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13889                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13890                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13891            }
13892            config.reqGlEsVersion = GL_ES_VERSION;
13893        }
13894        return config;
13895    }
13896
13897    ActivityStack getFocusedStack() {
13898        return mStackSupervisor.getFocusedStack();
13899    }
13900
13901    public Configuration getConfiguration() {
13902        Configuration ci;
13903        synchronized(this) {
13904            ci = new Configuration(mConfiguration);
13905        }
13906        return ci;
13907    }
13908
13909    public void updatePersistentConfiguration(Configuration values) {
13910        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13911                "updateConfiguration()");
13912        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13913                "updateConfiguration()");
13914        if (values == null) {
13915            throw new NullPointerException("Configuration must not be null");
13916        }
13917
13918        synchronized(this) {
13919            final long origId = Binder.clearCallingIdentity();
13920            updateConfigurationLocked(values, null, true, false);
13921            Binder.restoreCallingIdentity(origId);
13922        }
13923    }
13924
13925    public void updateConfiguration(Configuration values) {
13926        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13927                "updateConfiguration()");
13928
13929        synchronized(this) {
13930            if (values == null && mWindowManager != null) {
13931                // sentinel: fetch the current configuration from the window manager
13932                values = mWindowManager.computeNewConfiguration();
13933            }
13934
13935            if (mWindowManager != null) {
13936                mProcessList.applyDisplaySize(mWindowManager);
13937            }
13938
13939            final long origId = Binder.clearCallingIdentity();
13940            if (values != null) {
13941                Settings.System.clearConfiguration(values);
13942            }
13943            updateConfigurationLocked(values, null, false, false);
13944            Binder.restoreCallingIdentity(origId);
13945        }
13946    }
13947
13948    /**
13949     * Do either or both things: (1) change the current configuration, and (2)
13950     * make sure the given activity is running with the (now) current
13951     * configuration.  Returns true if the activity has been left running, or
13952     * false if <var>starting</var> is being destroyed to match the new
13953     * configuration.
13954     * @param persistent TODO
13955     */
13956    boolean updateConfigurationLocked(Configuration values,
13957            ActivityRecord starting, boolean persistent, boolean initLocale) {
13958        int changes = 0;
13959
13960        if (values != null) {
13961            Configuration newConfig = new Configuration(mConfiguration);
13962            changes = newConfig.updateFrom(values);
13963            if (changes != 0) {
13964                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13965                    Slog.i(TAG, "Updating configuration to: " + values);
13966                }
13967
13968                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13969
13970                if (values.locale != null && !initLocale) {
13971                    saveLocaleLocked(values.locale,
13972                                     !values.locale.equals(mConfiguration.locale),
13973                                     values.userSetLocale);
13974                }
13975
13976                mConfigurationSeq++;
13977                if (mConfigurationSeq <= 0) {
13978                    mConfigurationSeq = 1;
13979                }
13980                newConfig.seq = mConfigurationSeq;
13981                mConfiguration = newConfig;
13982                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
13983
13984                final Configuration configCopy = new Configuration(mConfiguration);
13985
13986                // TODO: If our config changes, should we auto dismiss any currently
13987                // showing dialogs?
13988                mShowDialogs = shouldShowDialogs(newConfig);
13989
13990                AttributeCache ac = AttributeCache.instance();
13991                if (ac != null) {
13992                    ac.updateConfiguration(configCopy);
13993                }
13994
13995                // Make sure all resources in our process are updated
13996                // right now, so that anyone who is going to retrieve
13997                // resource values after we return will be sure to get
13998                // the new ones.  This is especially important during
13999                // boot, where the first config change needs to guarantee
14000                // all resources have that config before following boot
14001                // code is executed.
14002                mSystemThread.applyConfigurationToResources(configCopy);
14003
14004                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14005                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14006                    msg.obj = new Configuration(configCopy);
14007                    mHandler.sendMessage(msg);
14008                }
14009
14010                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14011                    ProcessRecord app = mLruProcesses.get(i);
14012                    try {
14013                        if (app.thread != null) {
14014                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14015                                    + app.processName + " new config " + mConfiguration);
14016                            app.thread.scheduleConfigurationChanged(configCopy);
14017                        }
14018                    } catch (Exception e) {
14019                    }
14020                }
14021                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14022                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14023                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14024                        | Intent.FLAG_RECEIVER_FOREGROUND);
14025                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14026                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14027                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14028                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14029                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14030                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14031                    broadcastIntentLocked(null, null, intent,
14032                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14033                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14034                }
14035            }
14036        }
14037
14038        boolean kept = true;
14039        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14040        // mainStack is null during startup.
14041        if (mainStack != null) {
14042            if (changes != 0 && starting == null) {
14043                // If the configuration changed, and the caller is not already
14044                // in the process of starting an activity, then find the top
14045                // activity to check if its configuration needs to change.
14046                starting = mainStack.topRunningActivityLocked(null);
14047            }
14048
14049            if (starting != null) {
14050                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14051                // And we need to make sure at this point that all other activities
14052                // are made visible with the correct configuration.
14053                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14054            }
14055        }
14056
14057        if (values != null && mWindowManager != null) {
14058            mWindowManager.setNewConfiguration(mConfiguration);
14059        }
14060
14061        return kept;
14062    }
14063
14064    /**
14065     * Decide based on the configuration whether we should shouw the ANR,
14066     * crash, etc dialogs.  The idea is that if there is no affordnace to
14067     * press the on-screen buttons, we shouldn't show the dialog.
14068     *
14069     * A thought: SystemUI might also want to get told about this, the Power
14070     * dialog / global actions also might want different behaviors.
14071     */
14072    private static final boolean shouldShowDialogs(Configuration config) {
14073        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14074                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14075    }
14076
14077    /**
14078     * Save the locale.  You must be inside a synchronized (this) block.
14079     */
14080    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14081        if(isDiff) {
14082            SystemProperties.set("user.language", l.getLanguage());
14083            SystemProperties.set("user.region", l.getCountry());
14084        }
14085
14086        if(isPersist) {
14087            SystemProperties.set("persist.sys.language", l.getLanguage());
14088            SystemProperties.set("persist.sys.country", l.getCountry());
14089            SystemProperties.set("persist.sys.localevar", l.getVariant());
14090        }
14091    }
14092
14093    @Override
14094    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14095        ActivityRecord srec = ActivityRecord.forToken(token);
14096        return srec != null && srec.task.affinity != null &&
14097                srec.task.affinity.equals(destAffinity);
14098    }
14099
14100    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14101            Intent resultData) {
14102
14103        synchronized (this) {
14104            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14105            if (stack != null) {
14106                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14107            }
14108            return false;
14109        }
14110    }
14111
14112    public int getLaunchedFromUid(IBinder activityToken) {
14113        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14114        if (srec == null) {
14115            return -1;
14116        }
14117        return srec.launchedFromUid;
14118    }
14119
14120    public String getLaunchedFromPackage(IBinder activityToken) {
14121        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14122        if (srec == null) {
14123            return null;
14124        }
14125        return srec.launchedFromPackage;
14126    }
14127
14128    // =========================================================
14129    // LIFETIME MANAGEMENT
14130    // =========================================================
14131
14132    // Returns which broadcast queue the app is the current [or imminent] receiver
14133    // on, or 'null' if the app is not an active broadcast recipient.
14134    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14135        BroadcastRecord r = app.curReceiver;
14136        if (r != null) {
14137            return r.queue;
14138        }
14139
14140        // It's not the current receiver, but it might be starting up to become one
14141        synchronized (this) {
14142            for (BroadcastQueue queue : mBroadcastQueues) {
14143                r = queue.mPendingBroadcast;
14144                if (r != null && r.curApp == app) {
14145                    // found it; report which queue it's in
14146                    return queue;
14147                }
14148            }
14149        }
14150
14151        return null;
14152    }
14153
14154    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14155            boolean doingAll, long now) {
14156        if (mAdjSeq == app.adjSeq) {
14157            // This adjustment has already been computed.
14158            return app.curRawAdj;
14159        }
14160
14161        if (app.thread == null) {
14162            app.adjSeq = mAdjSeq;
14163            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14164            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14165            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14166        }
14167
14168        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14169        app.adjSource = null;
14170        app.adjTarget = null;
14171        app.empty = false;
14172        app.cached = false;
14173
14174        final int activitiesSize = app.activities.size();
14175
14176        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14177            // The max adjustment doesn't allow this app to be anything
14178            // below foreground, so it is not worth doing work for it.
14179            app.adjType = "fixed";
14180            app.adjSeq = mAdjSeq;
14181            app.curRawAdj = app.maxAdj;
14182            app.foregroundActivities = false;
14183            app.keeping = true;
14184            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14185            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14186            // System process can do UI, and when they do we want to have
14187            // them trim their memory after the user leaves the UI.  To
14188            // facilitate this, here we need to determine whether or not it
14189            // is currently showing UI.
14190            app.systemNoUi = true;
14191            if (app == TOP_APP) {
14192                app.systemNoUi = false;
14193            } else if (activitiesSize > 0) {
14194                for (int j = 0; j < activitiesSize; j++) {
14195                    final ActivityRecord r = app.activities.get(j);
14196                    if (r.visible) {
14197                        app.systemNoUi = false;
14198                    }
14199                }
14200            }
14201            if (!app.systemNoUi) {
14202                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14203            }
14204            return (app.curAdj=app.maxAdj);
14205        }
14206
14207        app.keeping = false;
14208        app.systemNoUi = false;
14209
14210        // Determine the importance of the process, starting with most
14211        // important to least, and assign an appropriate OOM adjustment.
14212        int adj;
14213        int schedGroup;
14214        int procState;
14215        boolean foregroundActivities = false;
14216        boolean interesting = false;
14217        BroadcastQueue queue;
14218        if (app == TOP_APP) {
14219            // The last app on the list is the foreground app.
14220            adj = ProcessList.FOREGROUND_APP_ADJ;
14221            schedGroup = Process.THREAD_GROUP_DEFAULT;
14222            app.adjType = "top-activity";
14223            foregroundActivities = true;
14224            interesting = true;
14225            procState = ActivityManager.PROCESS_STATE_TOP;
14226        } else if (app.instrumentationClass != null) {
14227            // Don't want to kill running instrumentation.
14228            adj = ProcessList.FOREGROUND_APP_ADJ;
14229            schedGroup = Process.THREAD_GROUP_DEFAULT;
14230            app.adjType = "instrumentation";
14231            interesting = true;
14232            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14233        } else if ((queue = isReceivingBroadcast(app)) != null) {
14234            // An app that is currently receiving a broadcast also
14235            // counts as being in the foreground for OOM killer purposes.
14236            // It's placed in a sched group based on the nature of the
14237            // broadcast as reflected by which queue it's active in.
14238            adj = ProcessList.FOREGROUND_APP_ADJ;
14239            schedGroup = (queue == mFgBroadcastQueue)
14240                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14241            app.adjType = "broadcast";
14242            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14243        } else if (app.executingServices.size() > 0) {
14244            // An app that is currently executing a service callback also
14245            // counts as being in the foreground.
14246            adj = ProcessList.FOREGROUND_APP_ADJ;
14247            schedGroup = app.execServicesFg ?
14248                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14249            app.adjType = "exec-service";
14250            procState = ActivityManager.PROCESS_STATE_SERVICE;
14251            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14252        } else {
14253            // As far as we know the process is empty.  We may change our mind later.
14254            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14255            // At this point we don't actually know the adjustment.  Use the cached adj
14256            // value that the caller wants us to.
14257            adj = cachedAdj;
14258            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14259            app.cached = true;
14260            app.empty = true;
14261            app.adjType = "cch-empty";
14262        }
14263
14264        // Examine all activities if not already foreground.
14265        if (!foregroundActivities && activitiesSize > 0) {
14266            for (int j = 0; j < activitiesSize; j++) {
14267                final ActivityRecord r = app.activities.get(j);
14268                if (r.app != app) {
14269                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14270                            + app + "?!?");
14271                    continue;
14272                }
14273                if (r.visible) {
14274                    // App has a visible activity; only upgrade adjustment.
14275                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14276                        adj = ProcessList.VISIBLE_APP_ADJ;
14277                        app.adjType = "visible";
14278                    }
14279                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14280                        procState = ActivityManager.PROCESS_STATE_TOP;
14281                    }
14282                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14283                    app.cached = false;
14284                    app.empty = false;
14285                    foregroundActivities = true;
14286                    break;
14287                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14288                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14289                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14290                        app.adjType = "pausing";
14291                    }
14292                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14293                        procState = ActivityManager.PROCESS_STATE_TOP;
14294                    }
14295                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14296                    app.cached = false;
14297                    app.empty = false;
14298                    foregroundActivities = true;
14299                } else if (r.state == ActivityState.STOPPING) {
14300                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14301                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14302                        app.adjType = "stopping";
14303                    }
14304                    // For the process state, we will at this point consider the
14305                    // process to be cached.  It will be cached either as an activity
14306                    // or empty depending on whether the activity is finishing.  We do
14307                    // this so that we can treat the process as cached for purposes of
14308                    // memory trimming (determing current memory level, trim command to
14309                    // send to process) since there can be an arbitrary number of stopping
14310                    // processes and they should soon all go into the cached state.
14311                    if (!r.finishing) {
14312                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14313                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14314                        }
14315                    }
14316                    app.cached = false;
14317                    app.empty = false;
14318                    foregroundActivities = true;
14319                } else {
14320                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14321                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14322                        app.adjType = "cch-act";
14323                    }
14324                }
14325            }
14326        }
14327
14328        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14329            if (app.foregroundServices) {
14330                // The user is aware of this app, so make it visible.
14331                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14332                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14333                app.cached = false;
14334                app.adjType = "fg-service";
14335                schedGroup = Process.THREAD_GROUP_DEFAULT;
14336            } else if (app.forcingToForeground != null) {
14337                // The user is aware of this app, so make it visible.
14338                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14339                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14340                app.cached = false;
14341                app.adjType = "force-fg";
14342                app.adjSource = app.forcingToForeground;
14343                schedGroup = Process.THREAD_GROUP_DEFAULT;
14344            }
14345        }
14346
14347        if (app.foregroundServices) {
14348            interesting = true;
14349        }
14350
14351        if (app == mHeavyWeightProcess) {
14352            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14353                // We don't want to kill the current heavy-weight process.
14354                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14355                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14356                app.cached = false;
14357                app.adjType = "heavy";
14358            }
14359            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14360                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14361            }
14362        }
14363
14364        if (app == mHomeProcess) {
14365            if (adj > ProcessList.HOME_APP_ADJ) {
14366                // This process is hosting what we currently consider to be the
14367                // home app, so we don't want to let it go into the background.
14368                adj = ProcessList.HOME_APP_ADJ;
14369                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14370                app.cached = false;
14371                app.adjType = "home";
14372            }
14373            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14374                procState = ActivityManager.PROCESS_STATE_HOME;
14375            }
14376        }
14377
14378        if (app == mPreviousProcess && app.activities.size() > 0) {
14379            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14380                // This was the previous process that showed UI to the user.
14381                // We want to try to keep it around more aggressively, to give
14382                // a good experience around switching between two apps.
14383                adj = ProcessList.PREVIOUS_APP_ADJ;
14384                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14385                app.cached = false;
14386                app.adjType = "previous";
14387            }
14388            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14389                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14390            }
14391        }
14392
14393        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14394                + " reason=" + app.adjType);
14395
14396        // By default, we use the computed adjustment.  It may be changed if
14397        // there are applications dependent on our services or providers, but
14398        // this gives us a baseline and makes sure we don't get into an
14399        // infinite recursion.
14400        app.adjSeq = mAdjSeq;
14401        app.curRawAdj = adj;
14402        app.hasStartedServices = false;
14403
14404        if (mBackupTarget != null && app == mBackupTarget.app) {
14405            // If possible we want to avoid killing apps while they're being backed up
14406            if (adj > ProcessList.BACKUP_APP_ADJ) {
14407                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14408                adj = ProcessList.BACKUP_APP_ADJ;
14409                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14410                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14411                }
14412                app.adjType = "backup";
14413                app.cached = false;
14414            }
14415            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14416                procState = ActivityManager.PROCESS_STATE_BACKUP;
14417            }
14418        }
14419
14420        boolean mayBeTop = false;
14421
14422        for (int is = app.services.size()-1;
14423                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14424                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14425                        || procState > ActivityManager.PROCESS_STATE_TOP);
14426                is--) {
14427            ServiceRecord s = app.services.valueAt(is);
14428            if (s.startRequested) {
14429                app.hasStartedServices = true;
14430                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14431                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14432                }
14433                if (app.hasShownUi && app != mHomeProcess) {
14434                    // If this process has shown some UI, let it immediately
14435                    // go to the LRU list because it may be pretty heavy with
14436                    // UI stuff.  We'll tag it with a label just to help
14437                    // debug and understand what is going on.
14438                    if (adj > ProcessList.SERVICE_ADJ) {
14439                        app.adjType = "cch-started-ui-services";
14440                    }
14441                } else {
14442                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14443                        // This service has seen some activity within
14444                        // recent memory, so we will keep its process ahead
14445                        // of the background processes.
14446                        if (adj > ProcessList.SERVICE_ADJ) {
14447                            adj = ProcessList.SERVICE_ADJ;
14448                            app.adjType = "started-services";
14449                            app.cached = false;
14450                        }
14451                    }
14452                    // If we have let the service slide into the background
14453                    // state, still have some text describing what it is doing
14454                    // even though the service no longer has an impact.
14455                    if (adj > ProcessList.SERVICE_ADJ) {
14456                        app.adjType = "cch-started-services";
14457                    }
14458                }
14459                // Don't kill this process because it is doing work; it
14460                // has said it is doing work.
14461                app.keeping = true;
14462            }
14463            for (int conni = s.connections.size()-1;
14464                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14465                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14466                            || procState > ActivityManager.PROCESS_STATE_TOP);
14467                    conni--) {
14468                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14469                for (int i = 0;
14470                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14471                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14472                                || procState > ActivityManager.PROCESS_STATE_TOP);
14473                        i++) {
14474                    // XXX should compute this based on the max of
14475                    // all connected clients.
14476                    ConnectionRecord cr = clist.get(i);
14477                    if (cr.binding.client == app) {
14478                        // Binding to ourself is not interesting.
14479                        continue;
14480                    }
14481                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14482                        ProcessRecord client = cr.binding.client;
14483                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14484                                TOP_APP, doingAll, now);
14485                        int clientProcState = client.curProcState;
14486                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14487                            // If the other app is cached for any reason, for purposes here
14488                            // we are going to consider it empty.  The specific cached state
14489                            // doesn't propagate except under certain conditions.
14490                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14491                        }
14492                        String adjType = null;
14493                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14494                            // Not doing bind OOM management, so treat
14495                            // this guy more like a started service.
14496                            if (app.hasShownUi && app != mHomeProcess) {
14497                                // If this process has shown some UI, let it immediately
14498                                // go to the LRU list because it may be pretty heavy with
14499                                // UI stuff.  We'll tag it with a label just to help
14500                                // debug and understand what is going on.
14501                                if (adj > clientAdj) {
14502                                    adjType = "cch-bound-ui-services";
14503                                }
14504                                app.cached = false;
14505                                clientAdj = adj;
14506                                clientProcState = procState;
14507                            } else {
14508                                if (now >= (s.lastActivity
14509                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14510                                    // This service has not seen activity within
14511                                    // recent memory, so allow it to drop to the
14512                                    // LRU list if there is no other reason to keep
14513                                    // it around.  We'll also tag it with a label just
14514                                    // to help debug and undertand what is going on.
14515                                    if (adj > clientAdj) {
14516                                        adjType = "cch-bound-services";
14517                                    }
14518                                    clientAdj = adj;
14519                                }
14520                            }
14521                        }
14522                        if (adj > clientAdj) {
14523                            // If this process has recently shown UI, and
14524                            // the process that is binding to it is less
14525                            // important than being visible, then we don't
14526                            // care about the binding as much as we care
14527                            // about letting this process get into the LRU
14528                            // list to be killed and restarted if needed for
14529                            // memory.
14530                            if (app.hasShownUi && app != mHomeProcess
14531                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14532                                adjType = "cch-bound-ui-services";
14533                            } else {
14534                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14535                                        |Context.BIND_IMPORTANT)) != 0) {
14536                                    adj = clientAdj;
14537                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14538                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14539                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14540                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14541                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14542                                    adj = clientAdj;
14543                                } else {
14544                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14545                                        adj = ProcessList.VISIBLE_APP_ADJ;
14546                                    }
14547                                }
14548                                if (!client.cached) {
14549                                    app.cached = false;
14550                                }
14551                                if (client.keeping) {
14552                                    app.keeping = true;
14553                                }
14554                                adjType = "service";
14555                            }
14556                        }
14557                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14558                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14559                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14560                            }
14561                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14562                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14563                                    // Special handling of clients who are in the top state.
14564                                    // We *may* want to consider this process to be in the
14565                                    // top state as well, but only if there is not another
14566                                    // reason for it to be running.  Being on the top is a
14567                                    // special state, meaning you are specifically running
14568                                    // for the current top app.  If the process is already
14569                                    // running in the background for some other reason, it
14570                                    // is more important to continue considering it to be
14571                                    // in the background state.
14572                                    mayBeTop = true;
14573                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14574                                } else {
14575                                    // Special handling for above-top states (persistent
14576                                    // processes).  These should not bring the current process
14577                                    // into the top state, since they are not on top.  Instead
14578                                    // give them the best state after that.
14579                                    clientProcState =
14580                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14581                                }
14582                            }
14583                        } else {
14584                            if (clientProcState <
14585                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14586                                clientProcState =
14587                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14588                            }
14589                        }
14590                        if (procState > clientProcState) {
14591                            procState = clientProcState;
14592                        }
14593                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14594                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14595                            app.pendingUiClean = true;
14596                        }
14597                        if (adjType != null) {
14598                            app.adjType = adjType;
14599                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14600                                    .REASON_SERVICE_IN_USE;
14601                            app.adjSource = cr.binding.client;
14602                            app.adjSourceOom = clientAdj;
14603                            app.adjTarget = s.name;
14604                        }
14605                    }
14606                    final ActivityRecord a = cr.activity;
14607                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14608                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14609                                (a.visible || a.state == ActivityState.RESUMED
14610                                 || a.state == ActivityState.PAUSING)) {
14611                            adj = ProcessList.FOREGROUND_APP_ADJ;
14612                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14613                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14614                            }
14615                            app.cached = false;
14616                            app.adjType = "service";
14617                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14618                                    .REASON_SERVICE_IN_USE;
14619                            app.adjSource = a;
14620                            app.adjSourceOom = adj;
14621                            app.adjTarget = s.name;
14622                        }
14623                    }
14624                }
14625            }
14626        }
14627
14628        for (int provi = app.pubProviders.size()-1;
14629                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14630                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14631                        || procState > ActivityManager.PROCESS_STATE_TOP);
14632                provi--) {
14633            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14634            for (int i = cpr.connections.size()-1;
14635                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14636                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14637                            || procState > ActivityManager.PROCESS_STATE_TOP);
14638                    i--) {
14639                ContentProviderConnection conn = cpr.connections.get(i);
14640                ProcessRecord client = conn.client;
14641                if (client == app) {
14642                    // Being our own client is not interesting.
14643                    continue;
14644                }
14645                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14646                int clientProcState = client.curProcState;
14647                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14648                    // If the other app is cached for any reason, for purposes here
14649                    // we are going to consider it empty.
14650                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14651                }
14652                if (adj > clientAdj) {
14653                    if (app.hasShownUi && app != mHomeProcess
14654                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14655                        app.adjType = "cch-ui-provider";
14656                    } else {
14657                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14658                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14659                        app.adjType = "provider";
14660                    }
14661                    app.cached &= client.cached;
14662                    app.keeping |= client.keeping;
14663                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14664                            .REASON_PROVIDER_IN_USE;
14665                    app.adjSource = client;
14666                    app.adjSourceOom = clientAdj;
14667                    app.adjTarget = cpr.name;
14668                }
14669                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14670                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14671                        // Special handling of clients who are in the top state.
14672                        // We *may* want to consider this process to be in the
14673                        // top state as well, but only if there is not another
14674                        // reason for it to be running.  Being on the top is a
14675                        // special state, meaning you are specifically running
14676                        // for the current top app.  If the process is already
14677                        // running in the background for some other reason, it
14678                        // is more important to continue considering it to be
14679                        // in the background state.
14680                        mayBeTop = true;
14681                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14682                    } else {
14683                        // Special handling for above-top states (persistent
14684                        // processes).  These should not bring the current process
14685                        // into the top state, since they are not on top.  Instead
14686                        // give them the best state after that.
14687                        clientProcState =
14688                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14689                    }
14690                }
14691                if (procState > clientProcState) {
14692                    procState = clientProcState;
14693                }
14694                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14695                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14696                }
14697            }
14698            // If the provider has external (non-framework) process
14699            // dependencies, ensure that its adjustment is at least
14700            // FOREGROUND_APP_ADJ.
14701            if (cpr.hasExternalProcessHandles()) {
14702                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14703                    adj = ProcessList.FOREGROUND_APP_ADJ;
14704                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14705                    app.cached = false;
14706                    app.keeping = true;
14707                    app.adjType = "provider";
14708                    app.adjTarget = cpr.name;
14709                }
14710                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14711                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14712                }
14713            }
14714        }
14715
14716        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14717            // A client of one of our services or providers is in the top state.  We
14718            // *may* want to be in the top state, but not if we are already running in
14719            // the background for some other reason.  For the decision here, we are going
14720            // to pick out a few specific states that we want to remain in when a client
14721            // is top (states that tend to be longer-term) and otherwise allow it to go
14722            // to the top state.
14723            switch (procState) {
14724                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14725                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14726                case ActivityManager.PROCESS_STATE_SERVICE:
14727                    // These all are longer-term states, so pull them up to the top
14728                    // of the background states, but not all the way to the top state.
14729                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14730                    break;
14731                default:
14732                    // Otherwise, top is a better choice, so take it.
14733                    procState = ActivityManager.PROCESS_STATE_TOP;
14734                    break;
14735            }
14736        }
14737
14738        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14739            // This is a cached process, but with client activities.  Mark it so.
14740            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14741            app.adjType = "cch-client-act";
14742        }
14743
14744        if (adj == ProcessList.SERVICE_ADJ) {
14745            if (doingAll) {
14746                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14747                mNewNumServiceProcs++;
14748                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14749                if (!app.serviceb) {
14750                    // This service isn't far enough down on the LRU list to
14751                    // normally be a B service, but if we are low on RAM and it
14752                    // is large we want to force it down since we would prefer to
14753                    // keep launcher over it.
14754                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14755                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14756                        app.serviceHighRam = true;
14757                        app.serviceb = true;
14758                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14759                    } else {
14760                        mNewNumAServiceProcs++;
14761                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14762                    }
14763                } else {
14764                    app.serviceHighRam = false;
14765                }
14766            }
14767            if (app.serviceb) {
14768                adj = ProcessList.SERVICE_B_ADJ;
14769            }
14770        }
14771
14772        app.curRawAdj = adj;
14773
14774        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14775        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14776        if (adj > app.maxAdj) {
14777            adj = app.maxAdj;
14778            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14779                schedGroup = Process.THREAD_GROUP_DEFAULT;
14780            }
14781        }
14782        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14783            app.keeping = true;
14784        }
14785
14786        // Do final modification to adj.  Everything we do between here and applying
14787        // the final setAdj must be done in this function, because we will also use
14788        // it when computing the final cached adj later.  Note that we don't need to
14789        // worry about this for max adj above, since max adj will always be used to
14790        // keep it out of the cached vaues.
14791        adj = app.modifyRawOomAdj(adj);
14792
14793        app.curProcState = procState;
14794
14795        int importance = app.memImportance;
14796        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14797            app.curAdj = adj;
14798            app.curSchedGroup = schedGroup;
14799            if (!interesting) {
14800                // For this reporting, if there is not something explicitly
14801                // interesting in this process then we will push it to the
14802                // background importance.
14803                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14804            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14805                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14806            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14807                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14808            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14809                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14810            } else if (adj >= ProcessList.SERVICE_ADJ) {
14811                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14812            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14813                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14814            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14815                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14816            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14817                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14818            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14819                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14820            } else {
14821                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14822            }
14823        }
14824
14825        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14826        if (foregroundActivities != app.foregroundActivities) {
14827            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14828        }
14829        if (changes != 0) {
14830            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14831            app.memImportance = importance;
14832            app.foregroundActivities = foregroundActivities;
14833            int i = mPendingProcessChanges.size()-1;
14834            ProcessChangeItem item = null;
14835            while (i >= 0) {
14836                item = mPendingProcessChanges.get(i);
14837                if (item.pid == app.pid) {
14838                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14839                    break;
14840                }
14841                i--;
14842            }
14843            if (i < 0) {
14844                // No existing item in pending changes; need a new one.
14845                final int NA = mAvailProcessChanges.size();
14846                if (NA > 0) {
14847                    item = mAvailProcessChanges.remove(NA-1);
14848                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14849                } else {
14850                    item = new ProcessChangeItem();
14851                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14852                }
14853                item.changes = 0;
14854                item.pid = app.pid;
14855                item.uid = app.info.uid;
14856                if (mPendingProcessChanges.size() == 0) {
14857                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14858                            "*** Enqueueing dispatch processes changed!");
14859                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14860                }
14861                mPendingProcessChanges.add(item);
14862            }
14863            item.changes |= changes;
14864            item.importance = importance;
14865            item.foregroundActivities = foregroundActivities;
14866            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14867                    + Integer.toHexString(System.identityHashCode(item))
14868                    + " " + app.toShortString() + ": changes=" + item.changes
14869                    + " importance=" + item.importance
14870                    + " foreground=" + item.foregroundActivities
14871                    + " type=" + app.adjType + " source=" + app.adjSource
14872                    + " target=" + app.adjTarget);
14873        }
14874
14875        return app.curRawAdj;
14876    }
14877
14878    /**
14879     * Schedule PSS collection of a process.
14880     */
14881    void requestPssLocked(ProcessRecord proc, int procState) {
14882        if (mPendingPssProcesses.contains(proc)) {
14883            return;
14884        }
14885        if (mPendingPssProcesses.size() == 0) {
14886            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14887        }
14888        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14889        proc.pssProcState = procState;
14890        mPendingPssProcesses.add(proc);
14891    }
14892
14893    /**
14894     * Schedule PSS collection of all processes.
14895     */
14896    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14897        if (!always) {
14898            if (now < (mLastFullPssTime +
14899                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14900                return;
14901            }
14902        }
14903        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14904        mLastFullPssTime = now;
14905        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14906        mPendingPssProcesses.clear();
14907        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14908            ProcessRecord app = mLruProcesses.get(i);
14909            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14910                app.pssProcState = app.setProcState;
14911                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14912                        mSleeping, now);
14913                mPendingPssProcesses.add(app);
14914            }
14915        }
14916        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14917    }
14918
14919    /**
14920     * Ask a given process to GC right now.
14921     */
14922    final void performAppGcLocked(ProcessRecord app) {
14923        try {
14924            app.lastRequestedGc = SystemClock.uptimeMillis();
14925            if (app.thread != null) {
14926                if (app.reportLowMemory) {
14927                    app.reportLowMemory = false;
14928                    app.thread.scheduleLowMemory();
14929                } else {
14930                    app.thread.processInBackground();
14931                }
14932            }
14933        } catch (Exception e) {
14934            // whatever.
14935        }
14936    }
14937
14938    /**
14939     * Returns true if things are idle enough to perform GCs.
14940     */
14941    private final boolean canGcNowLocked() {
14942        boolean processingBroadcasts = false;
14943        for (BroadcastQueue q : mBroadcastQueues) {
14944            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14945                processingBroadcasts = true;
14946            }
14947        }
14948        return !processingBroadcasts
14949                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14950    }
14951
14952    /**
14953     * Perform GCs on all processes that are waiting for it, but only
14954     * if things are idle.
14955     */
14956    final void performAppGcsLocked() {
14957        final int N = mProcessesToGc.size();
14958        if (N <= 0) {
14959            return;
14960        }
14961        if (canGcNowLocked()) {
14962            while (mProcessesToGc.size() > 0) {
14963                ProcessRecord proc = mProcessesToGc.remove(0);
14964                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14965                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14966                            <= SystemClock.uptimeMillis()) {
14967                        // To avoid spamming the system, we will GC processes one
14968                        // at a time, waiting a few seconds between each.
14969                        performAppGcLocked(proc);
14970                        scheduleAppGcsLocked();
14971                        return;
14972                    } else {
14973                        // It hasn't been long enough since we last GCed this
14974                        // process...  put it in the list to wait for its time.
14975                        addProcessToGcListLocked(proc);
14976                        break;
14977                    }
14978                }
14979            }
14980
14981            scheduleAppGcsLocked();
14982        }
14983    }
14984
14985    /**
14986     * If all looks good, perform GCs on all processes waiting for them.
14987     */
14988    final void performAppGcsIfAppropriateLocked() {
14989        if (canGcNowLocked()) {
14990            performAppGcsLocked();
14991            return;
14992        }
14993        // Still not idle, wait some more.
14994        scheduleAppGcsLocked();
14995    }
14996
14997    /**
14998     * Schedule the execution of all pending app GCs.
14999     */
15000    final void scheduleAppGcsLocked() {
15001        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15002
15003        if (mProcessesToGc.size() > 0) {
15004            // Schedule a GC for the time to the next process.
15005            ProcessRecord proc = mProcessesToGc.get(0);
15006            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15007
15008            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15009            long now = SystemClock.uptimeMillis();
15010            if (when < (now+GC_TIMEOUT)) {
15011                when = now + GC_TIMEOUT;
15012            }
15013            mHandler.sendMessageAtTime(msg, when);
15014        }
15015    }
15016
15017    /**
15018     * Add a process to the array of processes waiting to be GCed.  Keeps the
15019     * list in sorted order by the last GC time.  The process can't already be
15020     * on the list.
15021     */
15022    final void addProcessToGcListLocked(ProcessRecord proc) {
15023        boolean added = false;
15024        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15025            if (mProcessesToGc.get(i).lastRequestedGc <
15026                    proc.lastRequestedGc) {
15027                added = true;
15028                mProcessesToGc.add(i+1, proc);
15029                break;
15030            }
15031        }
15032        if (!added) {
15033            mProcessesToGc.add(0, proc);
15034        }
15035    }
15036
15037    /**
15038     * Set up to ask a process to GC itself.  This will either do it
15039     * immediately, or put it on the list of processes to gc the next
15040     * time things are idle.
15041     */
15042    final void scheduleAppGcLocked(ProcessRecord app) {
15043        long now = SystemClock.uptimeMillis();
15044        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15045            return;
15046        }
15047        if (!mProcessesToGc.contains(app)) {
15048            addProcessToGcListLocked(app);
15049            scheduleAppGcsLocked();
15050        }
15051    }
15052
15053    final void checkExcessivePowerUsageLocked(boolean doKills) {
15054        updateCpuStatsNow();
15055
15056        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15057        boolean doWakeKills = doKills;
15058        boolean doCpuKills = doKills;
15059        if (mLastPowerCheckRealtime == 0) {
15060            doWakeKills = false;
15061        }
15062        if (mLastPowerCheckUptime == 0) {
15063            doCpuKills = false;
15064        }
15065        if (stats.isScreenOn()) {
15066            doWakeKills = false;
15067        }
15068        final long curRealtime = SystemClock.elapsedRealtime();
15069        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15070        final long curUptime = SystemClock.uptimeMillis();
15071        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15072        mLastPowerCheckRealtime = curRealtime;
15073        mLastPowerCheckUptime = curUptime;
15074        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15075            doWakeKills = false;
15076        }
15077        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15078            doCpuKills = false;
15079        }
15080        int i = mLruProcesses.size();
15081        while (i > 0) {
15082            i--;
15083            ProcessRecord app = mLruProcesses.get(i);
15084            if (!app.keeping) {
15085                long wtime;
15086                synchronized (stats) {
15087                    wtime = stats.getProcessWakeTime(app.info.uid,
15088                            app.pid, curRealtime);
15089                }
15090                long wtimeUsed = wtime - app.lastWakeTime;
15091                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15092                if (DEBUG_POWER) {
15093                    StringBuilder sb = new StringBuilder(128);
15094                    sb.append("Wake for ");
15095                    app.toShortString(sb);
15096                    sb.append(": over ");
15097                    TimeUtils.formatDuration(realtimeSince, sb);
15098                    sb.append(" used ");
15099                    TimeUtils.formatDuration(wtimeUsed, sb);
15100                    sb.append(" (");
15101                    sb.append((wtimeUsed*100)/realtimeSince);
15102                    sb.append("%)");
15103                    Slog.i(TAG, sb.toString());
15104                    sb.setLength(0);
15105                    sb.append("CPU for ");
15106                    app.toShortString(sb);
15107                    sb.append(": over ");
15108                    TimeUtils.formatDuration(uptimeSince, sb);
15109                    sb.append(" used ");
15110                    TimeUtils.formatDuration(cputimeUsed, sb);
15111                    sb.append(" (");
15112                    sb.append((cputimeUsed*100)/uptimeSince);
15113                    sb.append("%)");
15114                    Slog.i(TAG, sb.toString());
15115                }
15116                // If a process has held a wake lock for more
15117                // than 50% of the time during this period,
15118                // that sounds bad.  Kill!
15119                if (doWakeKills && realtimeSince > 0
15120                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15121                    synchronized (stats) {
15122                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15123                                realtimeSince, wtimeUsed);
15124                    }
15125                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15126                            + " during " + realtimeSince);
15127                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15128                } else if (doCpuKills && uptimeSince > 0
15129                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15130                    synchronized (stats) {
15131                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15132                                uptimeSince, cputimeUsed);
15133                    }
15134                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15135                            + " during " + uptimeSince);
15136                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15137                } else {
15138                    app.lastWakeTime = wtime;
15139                    app.lastCpuTime = app.curCpuTime;
15140                }
15141            }
15142        }
15143    }
15144
15145    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15146            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15147        boolean success = true;
15148
15149        if (app.curRawAdj != app.setRawAdj) {
15150            if (wasKeeping && !app.keeping) {
15151                // This app is no longer something we want to keep.  Note
15152                // its current wake lock time to later know to kill it if
15153                // it is not behaving well.
15154                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15155                synchronized (stats) {
15156                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15157                            app.pid, SystemClock.elapsedRealtime());
15158                }
15159                app.lastCpuTime = app.curCpuTime;
15160            }
15161
15162            app.setRawAdj = app.curRawAdj;
15163        }
15164
15165        if (app.curAdj != app.setAdj) {
15166            ProcessList.setOomAdj(app.pid, app.curAdj);
15167            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15168                TAG, "Set " + app.pid + " " + app.processName +
15169                " adj " + app.curAdj + ": " + app.adjType);
15170            app.setAdj = app.curAdj;
15171        }
15172
15173        if (app.setSchedGroup != app.curSchedGroup) {
15174            app.setSchedGroup = app.curSchedGroup;
15175            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15176                    "Setting process group of " + app.processName
15177                    + " to " + app.curSchedGroup);
15178            if (app.waitingToKill != null &&
15179                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15180                killUnneededProcessLocked(app, app.waitingToKill);
15181                success = false;
15182            } else {
15183                if (true) {
15184                    long oldId = Binder.clearCallingIdentity();
15185                    try {
15186                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15187                    } catch (Exception e) {
15188                        Slog.w(TAG, "Failed setting process group of " + app.pid
15189                                + " to " + app.curSchedGroup);
15190                        e.printStackTrace();
15191                    } finally {
15192                        Binder.restoreCallingIdentity(oldId);
15193                    }
15194                } else {
15195                    if (app.thread != null) {
15196                        try {
15197                            app.thread.setSchedulingGroup(app.curSchedGroup);
15198                        } catch (RemoteException e) {
15199                        }
15200                    }
15201                }
15202                Process.setSwappiness(app.pid,
15203                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15204            }
15205        }
15206        if (app.repProcState != app.curProcState) {
15207            app.repProcState = app.curProcState;
15208            if (!reportingProcessState && app.thread != null) {
15209                try {
15210                    if (false) {
15211                        //RuntimeException h = new RuntimeException("here");
15212                        Slog.i(TAG, "Sending new process state " + app.repProcState
15213                                + " to " + app /*, h*/);
15214                    }
15215                    app.thread.setProcessState(app.repProcState);
15216                } catch (RemoteException e) {
15217                }
15218            }
15219        }
15220        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15221                app.setProcState)) {
15222            app.lastStateTime = now;
15223            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15224                    mSleeping, now);
15225            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15226                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15227                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15228                    + (app.nextPssTime-now) + ": " + app);
15229        } else {
15230            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15231                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15232                requestPssLocked(app, app.setProcState);
15233                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15234                        mSleeping, now);
15235            } else if (false && DEBUG_PSS) {
15236                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15237            }
15238        }
15239        if (app.setProcState != app.curProcState) {
15240            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15241                    "Proc state change of " + app.processName
15242                    + " to " + app.curProcState);
15243            app.setProcState = app.curProcState;
15244            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15245                app.notCachedSinceIdle = false;
15246            }
15247            if (!doingAll) {
15248                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15249            } else {
15250                app.procStateChanged = true;
15251            }
15252        }
15253        return success;
15254    }
15255
15256    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15257        if (proc.thread != null && proc.baseProcessTracker != null) {
15258            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15259        }
15260    }
15261
15262    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15263            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15264        if (app.thread == null) {
15265            return false;
15266        }
15267
15268        final boolean wasKeeping = app.keeping;
15269
15270        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15271
15272        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15273                reportingProcessState, now);
15274    }
15275
15276    private final ActivityRecord resumedAppLocked() {
15277        return mStackSupervisor.resumedAppLocked();
15278    }
15279
15280    final boolean updateOomAdjLocked(ProcessRecord app) {
15281        return updateOomAdjLocked(app, false);
15282    }
15283
15284    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15285        final ActivityRecord TOP_ACT = resumedAppLocked();
15286        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15287        final boolean wasCached = app.cached;
15288
15289        mAdjSeq++;
15290
15291        // This is the desired cached adjusment we want to tell it to use.
15292        // If our app is currently cached, we know it, and that is it.  Otherwise,
15293        // we don't know it yet, and it needs to now be cached we will then
15294        // need to do a complete oom adj.
15295        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15296                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15297        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15298                SystemClock.uptimeMillis());
15299        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15300            // Changed to/from cached state, so apps after it in the LRU
15301            // list may also be changed.
15302            updateOomAdjLocked();
15303        }
15304        return success;
15305    }
15306
15307    final void updateOomAdjLocked() {
15308        final ActivityRecord TOP_ACT = resumedAppLocked();
15309        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15310        final long now = SystemClock.uptimeMillis();
15311        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15312        final int N = mLruProcesses.size();
15313
15314        if (false) {
15315            RuntimeException e = new RuntimeException();
15316            e.fillInStackTrace();
15317            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15318        }
15319
15320        mAdjSeq++;
15321        mNewNumServiceProcs = 0;
15322        mNewNumAServiceProcs = 0;
15323
15324        final int emptyProcessLimit;
15325        final int cachedProcessLimit;
15326        if (mProcessLimit <= 0) {
15327            emptyProcessLimit = cachedProcessLimit = 0;
15328        } else if (mProcessLimit == 1) {
15329            emptyProcessLimit = 1;
15330            cachedProcessLimit = 0;
15331        } else {
15332            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15333            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15334        }
15335
15336        // Let's determine how many processes we have running vs.
15337        // how many slots we have for background processes; we may want
15338        // to put multiple processes in a slot of there are enough of
15339        // them.
15340        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15341                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15342        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15343        if (numEmptyProcs > cachedProcessLimit) {
15344            // If there are more empty processes than our limit on cached
15345            // processes, then use the cached process limit for the factor.
15346            // This ensures that the really old empty processes get pushed
15347            // down to the bottom, so if we are running low on memory we will
15348            // have a better chance at keeping around more cached processes
15349            // instead of a gazillion empty processes.
15350            numEmptyProcs = cachedProcessLimit;
15351        }
15352        int emptyFactor = numEmptyProcs/numSlots;
15353        if (emptyFactor < 1) emptyFactor = 1;
15354        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15355        if (cachedFactor < 1) cachedFactor = 1;
15356        int stepCached = 0;
15357        int stepEmpty = 0;
15358        int numCached = 0;
15359        int numEmpty = 0;
15360        int numTrimming = 0;
15361
15362        mNumNonCachedProcs = 0;
15363        mNumCachedHiddenProcs = 0;
15364
15365        // First update the OOM adjustment for each of the
15366        // application processes based on their current state.
15367        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15368        int nextCachedAdj = curCachedAdj+1;
15369        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15370        int nextEmptyAdj = curEmptyAdj+2;
15371        for (int i=N-1; i>=0; i--) {
15372            ProcessRecord app = mLruProcesses.get(i);
15373            if (!app.killedByAm && app.thread != null) {
15374                app.procStateChanged = false;
15375                final boolean wasKeeping = app.keeping;
15376                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15377
15378                // If we haven't yet assigned the final cached adj
15379                // to the process, do that now.
15380                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15381                    switch (app.curProcState) {
15382                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15383                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15384                            // This process is a cached process holding activities...
15385                            // assign it the next cached value for that type, and then
15386                            // step that cached level.
15387                            app.curRawAdj = curCachedAdj;
15388                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15389                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15390                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15391                                    + ")");
15392                            if (curCachedAdj != nextCachedAdj) {
15393                                stepCached++;
15394                                if (stepCached >= cachedFactor) {
15395                                    stepCached = 0;
15396                                    curCachedAdj = nextCachedAdj;
15397                                    nextCachedAdj += 2;
15398                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15399                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15400                                    }
15401                                }
15402                            }
15403                            break;
15404                        default:
15405                            // For everything else, assign next empty cached process
15406                            // level and bump that up.  Note that this means that
15407                            // long-running services that have dropped down to the
15408                            // cached level will be treated as empty (since their process
15409                            // state is still as a service), which is what we want.
15410                            app.curRawAdj = curEmptyAdj;
15411                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15412                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15413                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15414                                    + ")");
15415                            if (curEmptyAdj != nextEmptyAdj) {
15416                                stepEmpty++;
15417                                if (stepEmpty >= emptyFactor) {
15418                                    stepEmpty = 0;
15419                                    curEmptyAdj = nextEmptyAdj;
15420                                    nextEmptyAdj += 2;
15421                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15422                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15423                                    }
15424                                }
15425                            }
15426                            break;
15427                    }
15428                }
15429
15430                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15431
15432                // Count the number of process types.
15433                switch (app.curProcState) {
15434                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15435                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15436                        mNumCachedHiddenProcs++;
15437                        numCached++;
15438                        if (numCached > cachedProcessLimit) {
15439                            killUnneededProcessLocked(app, "cached #" + numCached);
15440                        }
15441                        break;
15442                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15443                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15444                                && app.lastActivityTime < oldTime) {
15445                            killUnneededProcessLocked(app, "empty for "
15446                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15447                                    / 1000) + "s");
15448                        } else {
15449                            numEmpty++;
15450                            if (numEmpty > emptyProcessLimit) {
15451                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15452                            }
15453                        }
15454                        break;
15455                    default:
15456                        mNumNonCachedProcs++;
15457                        break;
15458                }
15459
15460                if (app.isolated && app.services.size() <= 0) {
15461                    // If this is an isolated process, and there are no
15462                    // services running in it, then the process is no longer
15463                    // needed.  We agressively kill these because we can by
15464                    // definition not re-use the same process again, and it is
15465                    // good to avoid having whatever code was running in them
15466                    // left sitting around after no longer needed.
15467                    killUnneededProcessLocked(app, "isolated not needed");
15468                }
15469
15470                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15471                        && !app.killedByAm) {
15472                    numTrimming++;
15473                }
15474            }
15475        }
15476
15477        mNumServiceProcs = mNewNumServiceProcs;
15478
15479        // Now determine the memory trimming level of background processes.
15480        // Unfortunately we need to start at the back of the list to do this
15481        // properly.  We only do this if the number of background apps we
15482        // are managing to keep around is less than half the maximum we desire;
15483        // if we are keeping a good number around, we'll let them use whatever
15484        // memory they want.
15485        final int numCachedAndEmpty = numCached + numEmpty;
15486        int memFactor;
15487        if (numCached <= ProcessList.TRIM_CACHED_APPS
15488                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15489            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15490                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15491            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15492                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15493            } else {
15494                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15495            }
15496        } else {
15497            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15498        }
15499        // We always allow the memory level to go up (better).  We only allow it to go
15500        // down if we are in a state where that is allowed, *and* the total number of processes
15501        // has gone down since last time.
15502        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15503                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15504                + " last=" + mLastNumProcesses);
15505        if (memFactor > mLastMemoryLevel) {
15506            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15507                memFactor = mLastMemoryLevel;
15508                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15509            }
15510        }
15511        mLastMemoryLevel = memFactor;
15512        mLastNumProcesses = mLruProcesses.size();
15513        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15514        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15515        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15516            if (mLowRamStartTime == 0) {
15517                mLowRamStartTime = now;
15518            }
15519            int step = 0;
15520            int fgTrimLevel;
15521            switch (memFactor) {
15522                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15523                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15524                    break;
15525                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15526                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15527                    break;
15528                default:
15529                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15530                    break;
15531            }
15532            int factor = numTrimming/3;
15533            int minFactor = 2;
15534            if (mHomeProcess != null) minFactor++;
15535            if (mPreviousProcess != null) minFactor++;
15536            if (factor < minFactor) factor = minFactor;
15537            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15538            for (int i=N-1; i>=0; i--) {
15539                ProcessRecord app = mLruProcesses.get(i);
15540                if (allChanged || app.procStateChanged) {
15541                    setProcessTrackerState(app, trackerMemFactor, now);
15542                    app.procStateChanged = false;
15543                }
15544                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15545                        && !app.killedByAm) {
15546                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15547                        try {
15548                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15549                                    "Trimming memory of " + app.processName
15550                                    + " to " + curLevel);
15551                            app.thread.scheduleTrimMemory(curLevel);
15552                        } catch (RemoteException e) {
15553                        }
15554                        if (false) {
15555                            // For now we won't do this; our memory trimming seems
15556                            // to be good enough at this point that destroying
15557                            // activities causes more harm than good.
15558                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15559                                    && app != mHomeProcess && app != mPreviousProcess) {
15560                                // Need to do this on its own message because the stack may not
15561                                // be in a consistent state at this point.
15562                                // For these apps we will also finish their activities
15563                                // to help them free memory.
15564                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15565                            }
15566                        }
15567                    }
15568                    app.trimMemoryLevel = curLevel;
15569                    step++;
15570                    if (step >= factor) {
15571                        step = 0;
15572                        switch (curLevel) {
15573                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15574                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15575                                break;
15576                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15577                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15578                                break;
15579                        }
15580                    }
15581                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15582                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15583                            && app.thread != null) {
15584                        try {
15585                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15586                                    "Trimming memory of heavy-weight " + app.processName
15587                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15588                            app.thread.scheduleTrimMemory(
15589                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15590                        } catch (RemoteException e) {
15591                        }
15592                    }
15593                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15594                } else {
15595                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15596                            || app.systemNoUi) && app.pendingUiClean) {
15597                        // If this application is now in the background and it
15598                        // had done UI, then give it the special trim level to
15599                        // have it free UI resources.
15600                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15601                        if (app.trimMemoryLevel < level && app.thread != null) {
15602                            try {
15603                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15604                                        "Trimming memory of bg-ui " + app.processName
15605                                        + " to " + level);
15606                                app.thread.scheduleTrimMemory(level);
15607                            } catch (RemoteException e) {
15608                            }
15609                        }
15610                        app.pendingUiClean = false;
15611                    }
15612                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15613                        try {
15614                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15615                                    "Trimming memory of fg " + app.processName
15616                                    + " to " + fgTrimLevel);
15617                            app.thread.scheduleTrimMemory(fgTrimLevel);
15618                        } catch (RemoteException e) {
15619                        }
15620                    }
15621                    app.trimMemoryLevel = fgTrimLevel;
15622                }
15623            }
15624        } else {
15625            if (mLowRamStartTime != 0) {
15626                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15627                mLowRamStartTime = 0;
15628            }
15629            for (int i=N-1; i>=0; i--) {
15630                ProcessRecord app = mLruProcesses.get(i);
15631                if (allChanged || app.procStateChanged) {
15632                    setProcessTrackerState(app, trackerMemFactor, now);
15633                    app.procStateChanged = false;
15634                }
15635                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15636                        || app.systemNoUi) && app.pendingUiClean) {
15637                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15638                            && app.thread != null) {
15639                        try {
15640                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15641                                    "Trimming memory of ui hidden " + app.processName
15642                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15643                            app.thread.scheduleTrimMemory(
15644                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15645                        } catch (RemoteException e) {
15646                        }
15647                    }
15648                    app.pendingUiClean = false;
15649                }
15650                app.trimMemoryLevel = 0;
15651            }
15652        }
15653
15654        if (mAlwaysFinishActivities) {
15655            // Need to do this on its own message because the stack may not
15656            // be in a consistent state at this point.
15657            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15658        }
15659
15660        if (allChanged) {
15661            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15662        }
15663
15664        if (mProcessStats.shouldWriteNowLocked(now)) {
15665            mHandler.post(new Runnable() {
15666                @Override public void run() {
15667                    synchronized (ActivityManagerService.this) {
15668                        mProcessStats.writeStateAsyncLocked();
15669                    }
15670                }
15671            });
15672        }
15673
15674        if (DEBUG_OOM_ADJ) {
15675            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15676        }
15677    }
15678
15679    final void trimApplications() {
15680        synchronized (this) {
15681            int i;
15682
15683            // First remove any unused application processes whose package
15684            // has been removed.
15685            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15686                final ProcessRecord app = mRemovedProcesses.get(i);
15687                if (app.activities.size() == 0
15688                        && app.curReceiver == null && app.services.size() == 0) {
15689                    Slog.i(
15690                        TAG, "Exiting empty application process "
15691                        + app.processName + " ("
15692                        + (app.thread != null ? app.thread.asBinder() : null)
15693                        + ")\n");
15694                    if (app.pid > 0 && app.pid != MY_PID) {
15695                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15696                                app.processName, app.setAdj, "empty");
15697                        app.killedByAm = true;
15698                        Process.killProcessQuiet(app.pid);
15699                    } else {
15700                        try {
15701                            app.thread.scheduleExit();
15702                        } catch (Exception e) {
15703                            // Ignore exceptions.
15704                        }
15705                    }
15706                    cleanUpApplicationRecordLocked(app, false, true, -1);
15707                    mRemovedProcesses.remove(i);
15708
15709                    if (app.persistent) {
15710                        if (app.persistent) {
15711                            addAppLocked(app.info, false);
15712                        }
15713                    }
15714                }
15715            }
15716
15717            // Now update the oom adj for all processes.
15718            updateOomAdjLocked();
15719        }
15720    }
15721
15722    /** This method sends the specified signal to each of the persistent apps */
15723    public void signalPersistentProcesses(int sig) throws RemoteException {
15724        if (sig != Process.SIGNAL_USR1) {
15725            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15726        }
15727
15728        synchronized (this) {
15729            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15730                    != PackageManager.PERMISSION_GRANTED) {
15731                throw new SecurityException("Requires permission "
15732                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15733            }
15734
15735            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15736                ProcessRecord r = mLruProcesses.get(i);
15737                if (r.thread != null && r.persistent) {
15738                    Process.sendSignal(r.pid, sig);
15739                }
15740            }
15741        }
15742    }
15743
15744    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15745        if (proc == null || proc == mProfileProc) {
15746            proc = mProfileProc;
15747            path = mProfileFile;
15748            profileType = mProfileType;
15749            clearProfilerLocked();
15750        }
15751        if (proc == null) {
15752            return;
15753        }
15754        try {
15755            proc.thread.profilerControl(false, path, null, profileType);
15756        } catch (RemoteException e) {
15757            throw new IllegalStateException("Process disappeared");
15758        }
15759    }
15760
15761    private void clearProfilerLocked() {
15762        if (mProfileFd != null) {
15763            try {
15764                mProfileFd.close();
15765            } catch (IOException e) {
15766            }
15767        }
15768        mProfileApp = null;
15769        mProfileProc = null;
15770        mProfileFile = null;
15771        mProfileType = 0;
15772        mAutoStopProfiler = false;
15773    }
15774
15775    public boolean profileControl(String process, int userId, boolean start,
15776            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15777
15778        try {
15779            synchronized (this) {
15780                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15781                // its own permission.
15782                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15783                        != PackageManager.PERMISSION_GRANTED) {
15784                    throw new SecurityException("Requires permission "
15785                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15786                }
15787
15788                if (start && fd == null) {
15789                    throw new IllegalArgumentException("null fd");
15790                }
15791
15792                ProcessRecord proc = null;
15793                if (process != null) {
15794                    proc = findProcessLocked(process, userId, "profileControl");
15795                }
15796
15797                if (start && (proc == null || proc.thread == null)) {
15798                    throw new IllegalArgumentException("Unknown process: " + process);
15799                }
15800
15801                if (start) {
15802                    stopProfilerLocked(null, null, 0);
15803                    setProfileApp(proc.info, proc.processName, path, fd, false);
15804                    mProfileProc = proc;
15805                    mProfileType = profileType;
15806                    try {
15807                        fd = fd.dup();
15808                    } catch (IOException e) {
15809                        fd = null;
15810                    }
15811                    proc.thread.profilerControl(start, path, fd, profileType);
15812                    fd = null;
15813                    mProfileFd = null;
15814                } else {
15815                    stopProfilerLocked(proc, path, profileType);
15816                    if (fd != null) {
15817                        try {
15818                            fd.close();
15819                        } catch (IOException e) {
15820                        }
15821                    }
15822                }
15823
15824                return true;
15825            }
15826        } catch (RemoteException e) {
15827            throw new IllegalStateException("Process disappeared");
15828        } finally {
15829            if (fd != null) {
15830                try {
15831                    fd.close();
15832                } catch (IOException e) {
15833                }
15834            }
15835        }
15836    }
15837
15838    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15839        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15840                userId, true, true, callName, null);
15841        ProcessRecord proc = null;
15842        try {
15843            int pid = Integer.parseInt(process);
15844            synchronized (mPidsSelfLocked) {
15845                proc = mPidsSelfLocked.get(pid);
15846            }
15847        } catch (NumberFormatException e) {
15848        }
15849
15850        if (proc == null) {
15851            ArrayMap<String, SparseArray<ProcessRecord>> all
15852                    = mProcessNames.getMap();
15853            SparseArray<ProcessRecord> procs = all.get(process);
15854            if (procs != null && procs.size() > 0) {
15855                proc = procs.valueAt(0);
15856                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15857                    for (int i=1; i<procs.size(); i++) {
15858                        ProcessRecord thisProc = procs.valueAt(i);
15859                        if (thisProc.userId == userId) {
15860                            proc = thisProc;
15861                            break;
15862                        }
15863                    }
15864                }
15865            }
15866        }
15867
15868        return proc;
15869    }
15870
15871    public boolean dumpHeap(String process, int userId, boolean managed,
15872            String path, ParcelFileDescriptor fd) throws RemoteException {
15873
15874        try {
15875            synchronized (this) {
15876                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15877                // its own permission (same as profileControl).
15878                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15879                        != PackageManager.PERMISSION_GRANTED) {
15880                    throw new SecurityException("Requires permission "
15881                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15882                }
15883
15884                if (fd == null) {
15885                    throw new IllegalArgumentException("null fd");
15886                }
15887
15888                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15889                if (proc == null || proc.thread == null) {
15890                    throw new IllegalArgumentException("Unknown process: " + process);
15891                }
15892
15893                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15894                if (!isDebuggable) {
15895                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15896                        throw new SecurityException("Process not debuggable: " + proc);
15897                    }
15898                }
15899
15900                proc.thread.dumpHeap(managed, path, fd);
15901                fd = null;
15902                return true;
15903            }
15904        } catch (RemoteException e) {
15905            throw new IllegalStateException("Process disappeared");
15906        } finally {
15907            if (fd != null) {
15908                try {
15909                    fd.close();
15910                } catch (IOException e) {
15911                }
15912            }
15913        }
15914    }
15915
15916    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15917    public void monitor() {
15918        synchronized (this) { }
15919    }
15920
15921    void onCoreSettingsChange(Bundle settings) {
15922        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15923            ProcessRecord processRecord = mLruProcesses.get(i);
15924            try {
15925                if (processRecord.thread != null) {
15926                    processRecord.thread.setCoreSettings(settings);
15927                }
15928            } catch (RemoteException re) {
15929                /* ignore */
15930            }
15931        }
15932    }
15933
15934    // Multi-user methods
15935
15936    @Override
15937    public boolean switchUser(final int userId) {
15938        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15939                != PackageManager.PERMISSION_GRANTED) {
15940            String msg = "Permission Denial: switchUser() from pid="
15941                    + Binder.getCallingPid()
15942                    + ", uid=" + Binder.getCallingUid()
15943                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15944            Slog.w(TAG, msg);
15945            throw new SecurityException(msg);
15946        }
15947
15948        final long ident = Binder.clearCallingIdentity();
15949        try {
15950            synchronized (this) {
15951                final int oldUserId = mCurrentUserId;
15952                if (oldUserId == userId) {
15953                    return true;
15954                }
15955
15956                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15957                if (userInfo == null) {
15958                    Slog.w(TAG, "No user info for user #" + userId);
15959                    return false;
15960                }
15961
15962                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15963                        R.anim.screen_user_enter);
15964
15965                boolean needStart = false;
15966
15967                // If the user we are switching to is not currently started, then
15968                // we need to start it now.
15969                if (mStartedUsers.get(userId) == null) {
15970                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
15971                    updateStartedUserArrayLocked();
15972                    needStart = true;
15973                }
15974
15975                mCurrentUserId = userId;
15976                final Integer userIdInt = Integer.valueOf(userId);
15977                mUserLru.remove(userIdInt);
15978                mUserLru.add(userIdInt);
15979
15980                mWindowManager.setCurrentUser(userId);
15981
15982                // Once the internal notion of the active user has switched, we lock the device
15983                // with the option to show the user switcher on the keyguard.
15984                mWindowManager.lockNow(null);
15985
15986                final UserStartedState uss = mStartedUsers.get(userId);
15987
15988                // Make sure user is in the started state.  If it is currently
15989                // stopping, we need to knock that off.
15990                if (uss.mState == UserStartedState.STATE_STOPPING) {
15991                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
15992                    // so we can just fairly silently bring the user back from
15993                    // the almost-dead.
15994                    uss.mState = UserStartedState.STATE_RUNNING;
15995                    updateStartedUserArrayLocked();
15996                    needStart = true;
15997                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
15998                    // This means ACTION_SHUTDOWN has been sent, so we will
15999                    // need to treat this as a new boot of the user.
16000                    uss.mState = UserStartedState.STATE_BOOTING;
16001                    updateStartedUserArrayLocked();
16002                    needStart = true;
16003                }
16004
16005                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16006                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16007                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16008                        oldUserId, userId, uss));
16009                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16010                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16011                if (needStart) {
16012                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16013                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16014                            | Intent.FLAG_RECEIVER_FOREGROUND);
16015                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16016                    broadcastIntentLocked(null, null, intent,
16017                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16018                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16019                }
16020
16021                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16022                    if (userId != 0) {
16023                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16024                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16025                        broadcastIntentLocked(null, null, intent, null,
16026                                new IIntentReceiver.Stub() {
16027                                    public void performReceive(Intent intent, int resultCode,
16028                                            String data, Bundle extras, boolean ordered,
16029                                            boolean sticky, int sendingUser) {
16030                                        userInitialized(uss, userId);
16031                                    }
16032                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16033                                true, false, MY_PID, Process.SYSTEM_UID,
16034                                userId);
16035                        uss.initializing = true;
16036                    } else {
16037                        getUserManagerLocked().makeInitialized(userInfo.id);
16038                    }
16039                }
16040
16041                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16042                if (homeInFront) {
16043                    startHomeActivityLocked(userId);
16044                } else {
16045                    mStackSupervisor.resumeTopActivitiesLocked();
16046                }
16047
16048                EventLogTags.writeAmSwitchUser(userId);
16049                getUserManagerLocked().userForeground(userId);
16050                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16051                if (needStart) {
16052                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16053                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16054                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16055                    broadcastIntentLocked(null, null, intent,
16056                            null, new IIntentReceiver.Stub() {
16057                                @Override
16058                                public void performReceive(Intent intent, int resultCode, String data,
16059                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16060                                        throws RemoteException {
16061                                }
16062                            }, 0, null, null,
16063                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16064                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16065                }
16066            }
16067        } finally {
16068            Binder.restoreCallingIdentity(ident);
16069        }
16070
16071        return true;
16072    }
16073
16074    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16075        long ident = Binder.clearCallingIdentity();
16076        try {
16077            Intent intent;
16078            if (oldUserId >= 0) {
16079                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16080                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16081                        | Intent.FLAG_RECEIVER_FOREGROUND);
16082                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16083                broadcastIntentLocked(null, null, intent,
16084                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16085                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16086            }
16087            if (newUserId >= 0) {
16088                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16089                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16090                        | Intent.FLAG_RECEIVER_FOREGROUND);
16091                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16092                broadcastIntentLocked(null, null, intent,
16093                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16094                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16095                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16096                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16097                        | Intent.FLAG_RECEIVER_FOREGROUND);
16098                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16099                broadcastIntentLocked(null, null, intent,
16100                        null, null, 0, null, null,
16101                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16102                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16103            }
16104        } finally {
16105            Binder.restoreCallingIdentity(ident);
16106        }
16107    }
16108
16109    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16110            final int newUserId) {
16111        final int N = mUserSwitchObservers.beginBroadcast();
16112        if (N > 0) {
16113            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16114                int mCount = 0;
16115                @Override
16116                public void sendResult(Bundle data) throws RemoteException {
16117                    synchronized (ActivityManagerService.this) {
16118                        if (mCurUserSwitchCallback == this) {
16119                            mCount++;
16120                            if (mCount == N) {
16121                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16122                            }
16123                        }
16124                    }
16125                }
16126            };
16127            synchronized (this) {
16128                uss.switching = true;
16129                mCurUserSwitchCallback = callback;
16130            }
16131            for (int i=0; i<N; i++) {
16132                try {
16133                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16134                            newUserId, callback);
16135                } catch (RemoteException e) {
16136                }
16137            }
16138        } else {
16139            synchronized (this) {
16140                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16141            }
16142        }
16143        mUserSwitchObservers.finishBroadcast();
16144    }
16145
16146    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16147        synchronized (this) {
16148            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16149            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16150        }
16151    }
16152
16153    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16154        mCurUserSwitchCallback = null;
16155        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16156        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16157                oldUserId, newUserId, uss));
16158    }
16159
16160    void userInitialized(UserStartedState uss, int newUserId) {
16161        completeSwitchAndInitalize(uss, newUserId, true, false);
16162    }
16163
16164    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16165        completeSwitchAndInitalize(uss, newUserId, false, true);
16166    }
16167
16168    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16169            boolean clearInitializing, boolean clearSwitching) {
16170        boolean unfrozen = false;
16171        synchronized (this) {
16172            if (clearInitializing) {
16173                uss.initializing = false;
16174                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16175            }
16176            if (clearSwitching) {
16177                uss.switching = false;
16178            }
16179            if (!uss.switching && !uss.initializing) {
16180                mWindowManager.stopFreezingScreen();
16181                unfrozen = true;
16182            }
16183        }
16184        if (unfrozen) {
16185            final int N = mUserSwitchObservers.beginBroadcast();
16186            for (int i=0; i<N; i++) {
16187                try {
16188                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16189                } catch (RemoteException e) {
16190                }
16191            }
16192            mUserSwitchObservers.finishBroadcast();
16193        }
16194    }
16195
16196    void finishUserSwitch(UserStartedState uss) {
16197        synchronized (this) {
16198            if (uss.mState == UserStartedState.STATE_BOOTING
16199                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16200                uss.mState = UserStartedState.STATE_RUNNING;
16201                final int userId = uss.mHandle.getIdentifier();
16202                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16203                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16204                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16205                broadcastIntentLocked(null, null, intent,
16206                        null, null, 0, null, null,
16207                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16208                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16209            }
16210            int num = mUserLru.size();
16211            int i = 0;
16212            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16213                Integer oldUserId = mUserLru.get(i);
16214                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16215                if (oldUss == null) {
16216                    // Shouldn't happen, but be sane if it does.
16217                    mUserLru.remove(i);
16218                    num--;
16219                    continue;
16220                }
16221                if (oldUss.mState == UserStartedState.STATE_STOPPING
16222                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16223                    // This user is already stopping, doesn't count.
16224                    num--;
16225                    i++;
16226                    continue;
16227                }
16228                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16229                    // Owner and current can't be stopped, but count as running.
16230                    i++;
16231                    continue;
16232                }
16233                // This is a user to be stopped.
16234                stopUserLocked(oldUserId, null);
16235                num--;
16236                i++;
16237            }
16238        }
16239    }
16240
16241    @Override
16242    public int stopUser(final int userId, final IStopUserCallback callback) {
16243        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16244                != PackageManager.PERMISSION_GRANTED) {
16245            String msg = "Permission Denial: switchUser() from pid="
16246                    + Binder.getCallingPid()
16247                    + ", uid=" + Binder.getCallingUid()
16248                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16249            Slog.w(TAG, msg);
16250            throw new SecurityException(msg);
16251        }
16252        if (userId <= 0) {
16253            throw new IllegalArgumentException("Can't stop primary user " + userId);
16254        }
16255        synchronized (this) {
16256            return stopUserLocked(userId, callback);
16257        }
16258    }
16259
16260    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16261        if (mCurrentUserId == userId) {
16262            return ActivityManager.USER_OP_IS_CURRENT;
16263        }
16264
16265        final UserStartedState uss = mStartedUsers.get(userId);
16266        if (uss == null) {
16267            // User is not started, nothing to do...  but we do need to
16268            // callback if requested.
16269            if (callback != null) {
16270                mHandler.post(new Runnable() {
16271                    @Override
16272                    public void run() {
16273                        try {
16274                            callback.userStopped(userId);
16275                        } catch (RemoteException e) {
16276                        }
16277                    }
16278                });
16279            }
16280            return ActivityManager.USER_OP_SUCCESS;
16281        }
16282
16283        if (callback != null) {
16284            uss.mStopCallbacks.add(callback);
16285        }
16286
16287        if (uss.mState != UserStartedState.STATE_STOPPING
16288                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16289            uss.mState = UserStartedState.STATE_STOPPING;
16290            updateStartedUserArrayLocked();
16291
16292            long ident = Binder.clearCallingIdentity();
16293            try {
16294                // We are going to broadcast ACTION_USER_STOPPING and then
16295                // once that is done send a final ACTION_SHUTDOWN and then
16296                // stop the user.
16297                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16298                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16299                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16300                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16301                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16302                // This is the result receiver for the final shutdown broadcast.
16303                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16304                    @Override
16305                    public void performReceive(Intent intent, int resultCode, String data,
16306                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16307                        finishUserStop(uss);
16308                    }
16309                };
16310                // This is the result receiver for the initial stopping broadcast.
16311                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16312                    @Override
16313                    public void performReceive(Intent intent, int resultCode, String data,
16314                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16315                        // On to the next.
16316                        synchronized (ActivityManagerService.this) {
16317                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16318                                // Whoops, we are being started back up.  Abort, abort!
16319                                return;
16320                            }
16321                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16322                        }
16323                        broadcastIntentLocked(null, null, shutdownIntent,
16324                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16325                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16326                    }
16327                };
16328                // Kick things off.
16329                broadcastIntentLocked(null, null, stoppingIntent,
16330                        null, stoppingReceiver, 0, null, null,
16331                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16332                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16333            } finally {
16334                Binder.restoreCallingIdentity(ident);
16335            }
16336        }
16337
16338        return ActivityManager.USER_OP_SUCCESS;
16339    }
16340
16341    void finishUserStop(UserStartedState uss) {
16342        final int userId = uss.mHandle.getIdentifier();
16343        boolean stopped;
16344        ArrayList<IStopUserCallback> callbacks;
16345        synchronized (this) {
16346            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16347            if (mStartedUsers.get(userId) != uss) {
16348                stopped = false;
16349            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16350                stopped = false;
16351            } else {
16352                stopped = true;
16353                // User can no longer run.
16354                mStartedUsers.remove(userId);
16355                mUserLru.remove(Integer.valueOf(userId));
16356                updateStartedUserArrayLocked();
16357
16358                // Clean up all state and processes associated with the user.
16359                // Kill all the processes for the user.
16360                forceStopUserLocked(userId, "finish user");
16361            }
16362        }
16363
16364        for (int i=0; i<callbacks.size(); i++) {
16365            try {
16366                if (stopped) callbacks.get(i).userStopped(userId);
16367                else callbacks.get(i).userStopAborted(userId);
16368            } catch (RemoteException e) {
16369            }
16370        }
16371
16372        mStackSupervisor.removeUserLocked(userId);
16373    }
16374
16375    @Override
16376    public UserInfo getCurrentUser() {
16377        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16378                != PackageManager.PERMISSION_GRANTED) && (
16379                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16380                != PackageManager.PERMISSION_GRANTED)) {
16381            String msg = "Permission Denial: getCurrentUser() from pid="
16382                    + Binder.getCallingPid()
16383                    + ", uid=" + Binder.getCallingUid()
16384                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16385            Slog.w(TAG, msg);
16386            throw new SecurityException(msg);
16387        }
16388        synchronized (this) {
16389            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16390        }
16391    }
16392
16393    int getCurrentUserIdLocked() {
16394        return mCurrentUserId;
16395    }
16396
16397    @Override
16398    public boolean isUserRunning(int userId, boolean orStopped) {
16399        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16400                != PackageManager.PERMISSION_GRANTED) {
16401            String msg = "Permission Denial: isUserRunning() from pid="
16402                    + Binder.getCallingPid()
16403                    + ", uid=" + Binder.getCallingUid()
16404                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16405            Slog.w(TAG, msg);
16406            throw new SecurityException(msg);
16407        }
16408        synchronized (this) {
16409            return isUserRunningLocked(userId, orStopped);
16410        }
16411    }
16412
16413    boolean isUserRunningLocked(int userId, boolean orStopped) {
16414        UserStartedState state = mStartedUsers.get(userId);
16415        if (state == null) {
16416            return false;
16417        }
16418        if (orStopped) {
16419            return true;
16420        }
16421        return state.mState != UserStartedState.STATE_STOPPING
16422                && state.mState != UserStartedState.STATE_SHUTDOWN;
16423    }
16424
16425    @Override
16426    public int[] getRunningUserIds() {
16427        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16428                != PackageManager.PERMISSION_GRANTED) {
16429            String msg = "Permission Denial: isUserRunning() from pid="
16430                    + Binder.getCallingPid()
16431                    + ", uid=" + Binder.getCallingUid()
16432                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16433            Slog.w(TAG, msg);
16434            throw new SecurityException(msg);
16435        }
16436        synchronized (this) {
16437            return mStartedUserArray;
16438        }
16439    }
16440
16441    private void updateStartedUserArrayLocked() {
16442        int num = 0;
16443        for (int i=0; i<mStartedUsers.size();  i++) {
16444            UserStartedState uss = mStartedUsers.valueAt(i);
16445            // This list does not include stopping users.
16446            if (uss.mState != UserStartedState.STATE_STOPPING
16447                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16448                num++;
16449            }
16450        }
16451        mStartedUserArray = new int[num];
16452        num = 0;
16453        for (int i=0; i<mStartedUsers.size();  i++) {
16454            UserStartedState uss = mStartedUsers.valueAt(i);
16455            if (uss.mState != UserStartedState.STATE_STOPPING
16456                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16457                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16458                num++;
16459            }
16460        }
16461    }
16462
16463    @Override
16464    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16465        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16466                != PackageManager.PERMISSION_GRANTED) {
16467            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16468                    + Binder.getCallingPid()
16469                    + ", uid=" + Binder.getCallingUid()
16470                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16471            Slog.w(TAG, msg);
16472            throw new SecurityException(msg);
16473        }
16474
16475        mUserSwitchObservers.register(observer);
16476    }
16477
16478    @Override
16479    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16480        mUserSwitchObservers.unregister(observer);
16481    }
16482
16483    private boolean userExists(int userId) {
16484        if (userId == 0) {
16485            return true;
16486        }
16487        UserManagerService ums = getUserManagerLocked();
16488        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16489    }
16490
16491    int[] getUsersLocked() {
16492        UserManagerService ums = getUserManagerLocked();
16493        return ums != null ? ums.getUserIds() : new int[] { 0 };
16494    }
16495
16496    UserManagerService getUserManagerLocked() {
16497        if (mUserManager == null) {
16498            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16499            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16500        }
16501        return mUserManager;
16502    }
16503
16504    private int applyUserId(int uid, int userId) {
16505        return UserHandle.getUid(userId, uid);
16506    }
16507
16508    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16509        if (info == null) return null;
16510        ApplicationInfo newInfo = new ApplicationInfo(info);
16511        newInfo.uid = applyUserId(info.uid, userId);
16512        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16513                + info.packageName;
16514        return newInfo;
16515    }
16516
16517    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16518        if (aInfo == null
16519                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16520            return aInfo;
16521        }
16522
16523        ActivityInfo info = new ActivityInfo(aInfo);
16524        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16525        return info;
16526    }
16527}
16528