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