ActivityManagerService.java revision c6cf95c0f5f7250c65e40c441fe58d8cbfd114c9
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.readBooleanAttribute;
21import static com.android.internal.util.XmlUtils.readIntAttribute;
22import static com.android.internal.util.XmlUtils.readLongAttribute;
23import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
24import static com.android.internal.util.XmlUtils.writeIntAttribute;
25import static com.android.internal.util.XmlUtils.writeLongAttribute;
26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
28import static org.xmlpull.v1.XmlPullParser.START_TAG;
29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
30
31import android.Manifest;
32import android.app.AppOpsManager;
33import android.app.IActivityContainer;
34import android.app.IActivityContainerCallback;
35import android.app.IAppTask;
36import android.app.admin.DevicePolicyManager;
37import android.appwidget.AppWidgetManager;
38import android.graphics.Rect;
39import android.os.BatteryStats;
40import android.os.PersistableBundle;
41import android.service.voice.IVoiceInteractionSession;
42import android.util.ArrayMap;
43
44import com.android.internal.R;
45import com.android.internal.annotations.GuardedBy;
46import com.android.internal.app.IAppOpsService;
47import com.android.internal.app.IVoiceInteractor;
48import com.android.internal.app.ProcessMap;
49import com.android.internal.app.ProcessStats;
50import com.android.internal.content.PackageMonitor;
51import com.android.internal.os.BackgroundThread;
52import com.android.internal.os.BatteryStatsImpl;
53import com.android.internal.os.ProcessCpuTracker;
54import com.android.internal.os.TransferPipe;
55import com.android.internal.os.Zygote;
56import com.android.internal.util.FastPrintWriter;
57import com.android.internal.util.FastXmlSerializer;
58import com.android.internal.util.MemInfoReader;
59import com.android.internal.util.Preconditions;
60import com.android.server.AppOpsService;
61import com.android.server.AttributeCache;
62import com.android.server.IntentResolver;
63import com.android.server.LocalServices;
64import com.android.server.ServiceThread;
65import com.android.server.SystemService;
66import com.android.server.SystemServiceManager;
67import com.android.server.Watchdog;
68import com.android.server.am.ActivityStack.ActivityState;
69import com.android.server.firewall.IntentFirewall;
70import com.android.server.pm.UserManagerService;
71import com.android.server.wm.AppTransition;
72import com.android.server.wm.WindowManagerService;
73import com.google.android.collect.Lists;
74import com.google.android.collect.Maps;
75
76import libcore.io.IoUtils;
77
78import org.xmlpull.v1.XmlPullParser;
79import org.xmlpull.v1.XmlPullParserException;
80import org.xmlpull.v1.XmlSerializer;
81
82import android.app.Activity;
83import android.app.ActivityManager;
84import android.app.ActivityManager.RunningTaskInfo;
85import android.app.ActivityManager.StackInfo;
86import android.app.ActivityManagerInternal;
87import android.app.ActivityManagerNative;
88import android.app.ActivityOptions;
89import android.app.ActivityThread;
90import android.app.AlertDialog;
91import android.app.AppGlobals;
92import android.app.ApplicationErrorReport;
93import android.app.Dialog;
94import android.app.IActivityController;
95import android.app.IApplicationThread;
96import android.app.IInstrumentationWatcher;
97import android.app.INotificationManager;
98import android.app.IProcessObserver;
99import android.app.IServiceConnection;
100import android.app.IStopUserCallback;
101import android.app.IUiAutomationConnection;
102import android.app.IUserSwitchObserver;
103import android.app.Instrumentation;
104import android.app.Notification;
105import android.app.NotificationManager;
106import android.app.PendingIntent;
107import android.app.backup.IBackupManager;
108import android.content.ActivityNotFoundException;
109import android.content.BroadcastReceiver;
110import android.content.ClipData;
111import android.content.ComponentCallbacks2;
112import android.content.ComponentName;
113import android.content.ContentProvider;
114import android.content.ContentResolver;
115import android.content.Context;
116import android.content.DialogInterface;
117import android.content.IContentProvider;
118import android.content.IIntentReceiver;
119import android.content.IIntentSender;
120import android.content.Intent;
121import android.content.IntentFilter;
122import android.content.IntentSender;
123import android.content.pm.ActivityInfo;
124import android.content.pm.ApplicationInfo;
125import android.content.pm.ConfigurationInfo;
126import android.content.pm.IPackageDataObserver;
127import android.content.pm.IPackageManager;
128import android.content.pm.InstrumentationInfo;
129import android.content.pm.PackageInfo;
130import android.content.pm.PackageManager;
131import android.content.pm.ParceledListSlice;
132import android.content.pm.UserInfo;
133import android.content.pm.PackageManager.NameNotFoundException;
134import android.content.pm.PathPermission;
135import android.content.pm.ProviderInfo;
136import android.content.pm.ResolveInfo;
137import android.content.pm.ServiceInfo;
138import android.content.res.CompatibilityInfo;
139import android.content.res.Configuration;
140import android.graphics.Bitmap;
141import android.net.Proxy;
142import android.net.ProxyInfo;
143import android.net.Uri;
144import android.os.Binder;
145import android.os.Build;
146import android.os.Bundle;
147import android.os.Debug;
148import android.os.DropBoxManager;
149import android.os.Environment;
150import android.os.FactoryTest;
151import android.os.FileObserver;
152import android.os.FileUtils;
153import android.os.Handler;
154import android.os.IBinder;
155import android.os.IPermissionController;
156import android.os.IRemoteCallback;
157import android.os.IUserManager;
158import android.os.Looper;
159import android.os.Message;
160import android.os.Parcel;
161import android.os.ParcelFileDescriptor;
162import android.os.Process;
163import android.os.RemoteCallbackList;
164import android.os.RemoteException;
165import android.os.SELinux;
166import android.os.ServiceManager;
167import android.os.StrictMode;
168import android.os.SystemClock;
169import android.os.SystemProperties;
170import android.os.UpdateLock;
171import android.os.UserHandle;
172import android.provider.Settings;
173import android.text.format.DateUtils;
174import android.text.format.Time;
175import android.util.AtomicFile;
176import android.util.EventLog;
177import android.util.Log;
178import android.util.Pair;
179import android.util.PrintWriterPrinter;
180import android.util.Slog;
181import android.util.SparseArray;
182import android.util.TimeUtils;
183import android.util.Xml;
184import android.view.Gravity;
185import android.view.LayoutInflater;
186import android.view.View;
187import android.view.WindowManager;
188
189import java.io.BufferedInputStream;
190import java.io.BufferedOutputStream;
191import java.io.DataInputStream;
192import java.io.DataOutputStream;
193import java.io.File;
194import java.io.FileDescriptor;
195import java.io.FileInputStream;
196import java.io.FileNotFoundException;
197import java.io.FileOutputStream;
198import java.io.IOException;
199import java.io.InputStreamReader;
200import java.io.PrintWriter;
201import java.io.StringWriter;
202import java.lang.ref.WeakReference;
203import java.util.ArrayList;
204import java.util.Arrays;
205import java.util.Collections;
206import java.util.Comparator;
207import java.util.HashMap;
208import java.util.HashSet;
209import java.util.Iterator;
210import java.util.List;
211import java.util.Locale;
212import java.util.Map;
213import java.util.Set;
214import java.util.concurrent.atomic.AtomicBoolean;
215import java.util.concurrent.atomic.AtomicLong;
216
217public final class ActivityManagerService extends ActivityManagerNative
218        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
219    private static final String USER_DATA_DIR = "/data/user/";
220    static final String TAG = "ActivityManager";
221    static final String TAG_MU = "ActivityManagerServiceMU";
222    static final boolean DEBUG = false;
223    static final boolean localLOGV = DEBUG;
224    static final boolean DEBUG_BACKUP = localLOGV || false;
225    static final boolean DEBUG_BROADCAST = localLOGV || false;
226    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
227    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_CLEANUP = localLOGV || false;
229    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
230    static final boolean DEBUG_FOCUS = false;
231    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
232    static final boolean DEBUG_MU = localLOGV || false;
233    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
234    static final boolean DEBUG_LRU = localLOGV || false;
235    static final boolean DEBUG_PAUSE = localLOGV || false;
236    static final boolean DEBUG_POWER = localLOGV || false;
237    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
238    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
239    static final boolean DEBUG_PROCESSES = localLOGV || false;
240    static final boolean DEBUG_PROVIDER = localLOGV || false;
241    static final boolean DEBUG_RESULTS = localLOGV || false;
242    static final boolean DEBUG_SERVICE = localLOGV || false;
243    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
244    static final boolean DEBUG_STACK = localLOGV || false;
245    static final boolean DEBUG_SWITCH = localLOGV || false;
246    static final boolean DEBUG_TASKS = localLOGV || false;
247    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
248    static final boolean DEBUG_TRANSITION = localLOGV || false;
249    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
250    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
251    static final boolean DEBUG_VISBILITY = localLOGV || false;
252    static final boolean DEBUG_PSS = localLOGV || false;
253    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
254    static final boolean VALIDATE_TOKENS = false;
255    static final boolean SHOW_ACTIVITY_START_TIME = true;
256
257    // Control over CPU and battery monitoring.
258    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
259    static final boolean MONITOR_CPU_USAGE = true;
260    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
261    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
262    static final boolean MONITOR_THREAD_CPU_USAGE = false;
263
264    // The flags that are set for all calls we make to the package manager.
265    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
266
267    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
268
269    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
270
271    // Maximum number of recent tasks that we can remember.
272    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
273
274    // Amount of time after a call to stopAppSwitches() during which we will
275    // prevent further untrusted switches from happening.
276    static final long APP_SWITCH_DELAY_TIME = 5*1000;
277
278    // How long we wait for a launched process to attach to the activity manager
279    // before we decide it's never going to come up for real.
280    static final int PROC_START_TIMEOUT = 10*1000;
281
282    // How long we wait for a launched process to attach to the activity manager
283    // before we decide it's never going to come up for real, when the process was
284    // started with a wrapper for instrumentation (such as Valgrind) because it
285    // could take much longer than usual.
286    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
287
288    // How long to wait after going idle before forcing apps to GC.
289    static final int GC_TIMEOUT = 5*1000;
290
291    // The minimum amount of time between successive GC requests for a process.
292    static final int GC_MIN_INTERVAL = 60*1000;
293
294    // The minimum amount of time between successive PSS requests for a process.
295    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
296
297    // The minimum amount of time between successive PSS requests for a process
298    // when the request is due to the memory state being lowered.
299    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
300
301    // The rate at which we check for apps using excessive power -- 15 mins.
302    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
303
304    // The minimum sample duration we will allow before deciding we have
305    // enough data on wake locks to start killing things.
306    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
307
308    // The minimum sample duration we will allow before deciding we have
309    // enough data on CPU usage to start killing things.
310    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
311
312    // How long we allow a receiver to run before giving up on it.
313    static final int BROADCAST_FG_TIMEOUT = 10*1000;
314    static final int BROADCAST_BG_TIMEOUT = 60*1000;
315
316    // How long we wait until we timeout on key dispatching.
317    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
318
319    // How long we wait until we timeout on key dispatching during instrumentation.
320    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
321
322    // Amount of time we wait for observers to handle a user switch before
323    // giving up on them and unfreezing the screen.
324    static final int USER_SWITCH_TIMEOUT = 2*1000;
325
326    // Maximum number of users we allow to be running at a time.
327    static final int MAX_RUNNING_USERS = 3;
328
329    // How long to wait in getAssistContextExtras for the activity and foreground services
330    // to respond with the result.
331    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
332
333    // Maximum number of persisted Uri grants a package is allowed
334    static final int MAX_PERSISTED_URI_GRANTS = 128;
335
336    static final int MY_PID = Process.myPid();
337
338    static final String[] EMPTY_STRING_ARRAY = new String[0];
339
340    // How many bytes to write into the dropbox log before truncating
341    static final int DROPBOX_MAX_SIZE = 256 * 1024;
342
343    /** All system services */
344    SystemServiceManager mSystemServiceManager;
345
346    /** Run all ActivityStacks through this */
347    ActivityStackSupervisor mStackSupervisor;
348
349    public IntentFirewall mIntentFirewall;
350
351    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
352    // default actuion automatically.  Important for devices without direct input
353    // devices.
354    private boolean mShowDialogs = true;
355
356    /**
357     * Description of a request to start a new activity, which has been held
358     * due to app switches being disabled.
359     */
360    static class PendingActivityLaunch {
361        final ActivityRecord r;
362        final ActivityRecord sourceRecord;
363        final int startFlags;
364        final ActivityStack stack;
365
366        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
367                int _startFlags, ActivityStack _stack) {
368            r = _r;
369            sourceRecord = _sourceRecord;
370            startFlags = _startFlags;
371            stack = _stack;
372        }
373    }
374
375    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
376            = new ArrayList<PendingActivityLaunch>();
377
378    BroadcastQueue mFgBroadcastQueue;
379    BroadcastQueue mBgBroadcastQueue;
380    // Convenient for easy iteration over the queues. Foreground is first
381    // so that dispatch of foreground broadcasts gets precedence.
382    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
383
384    BroadcastQueue broadcastQueueForIntent(Intent intent) {
385        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
386        if (DEBUG_BACKGROUND_BROADCAST) {
387            Slog.i(TAG, "Broadcast intent " + intent + " on "
388                    + (isFg ? "foreground" : "background")
389                    + " queue");
390        }
391        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
392    }
393
394    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
395        for (BroadcastQueue queue : mBroadcastQueues) {
396            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
397            if (r != null) {
398                return r;
399            }
400        }
401        return null;
402    }
403
404    /**
405     * Activity we have told the window manager to have key focus.
406     */
407    ActivityRecord mFocusedActivity = null;
408
409    /**
410     * List of intents that were used to start the most recent tasks.
411     */
412    ArrayList<TaskRecord> mRecentTasks;
413
414    public class PendingAssistExtras extends Binder implements Runnable {
415        public final ActivityRecord activity;
416        public boolean haveResult = false;
417        public Bundle result = null;
418        public PendingAssistExtras(ActivityRecord _activity) {
419            activity = _activity;
420        }
421        @Override
422        public void run() {
423            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
424            synchronized (this) {
425                haveResult = true;
426                notifyAll();
427            }
428        }
429    }
430
431    final ArrayList<PendingAssistExtras> mPendingAssistExtras
432            = new ArrayList<PendingAssistExtras>();
433
434    /**
435     * Process management.
436     */
437    final ProcessList mProcessList = new ProcessList();
438
439    /**
440     * All of the applications we currently have running organized by name.
441     * The keys are strings of the application package name (as
442     * returned by the package manager), and the keys are ApplicationRecord
443     * objects.
444     */
445    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
446
447    /**
448     * Tracking long-term execution of processes to look for abuse and other
449     * bad app behavior.
450     */
451    final ProcessStatsService mProcessStats;
452
453    /**
454     * The currently running isolated processes.
455     */
456    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
457
458    /**
459     * Counter for assigning isolated process uids, to avoid frequently reusing the
460     * same ones.
461     */
462    int mNextIsolatedProcessUid = 0;
463
464    /**
465     * The currently running heavy-weight process, if any.
466     */
467    ProcessRecord mHeavyWeightProcess = null;
468
469    /**
470     * The last time that various processes have crashed.
471     */
472    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
473
474    /**
475     * Information about a process that is currently marked as bad.
476     */
477    static final class BadProcessInfo {
478        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
479            this.time = time;
480            this.shortMsg = shortMsg;
481            this.longMsg = longMsg;
482            this.stack = stack;
483        }
484
485        final long time;
486        final String shortMsg;
487        final String longMsg;
488        final String stack;
489    }
490
491    /**
492     * Set of applications that we consider to be bad, and will reject
493     * incoming broadcasts from (which the user has no control over).
494     * Processes are added to this set when they have crashed twice within
495     * a minimum amount of time; they are removed from it when they are
496     * later restarted (hopefully due to some user action).  The value is the
497     * time it was added to the list.
498     */
499    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
500
501    /**
502     * All of the processes we currently have running organized by pid.
503     * The keys are the pid running the application.
504     *
505     * <p>NOTE: This object is protected by its own lock, NOT the global
506     * activity manager lock!
507     */
508    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
509
510    /**
511     * All of the processes that have been forced to be foreground.  The key
512     * is the pid of the caller who requested it (we hold a death
513     * link on it).
514     */
515    abstract class ForegroundToken implements IBinder.DeathRecipient {
516        int pid;
517        IBinder token;
518    }
519    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
520
521    /**
522     * List of records for processes that someone had tried to start before the
523     * system was ready.  We don't start them at that point, but ensure they
524     * are started by the time booting is complete.
525     */
526    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
527
528    /**
529     * List of persistent applications that are in the process
530     * of being started.
531     */
532    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
533
534    /**
535     * Processes that are being forcibly torn down.
536     */
537    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
538
539    /**
540     * List of running applications, sorted by recent usage.
541     * The first entry in the list is the least recently used.
542     */
543    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
544
545    /**
546     * Where in mLruProcesses that the processes hosting activities start.
547     */
548    int mLruProcessActivityStart = 0;
549
550    /**
551     * Where in mLruProcesses that the processes hosting services start.
552     * This is after (lower index) than mLruProcessesActivityStart.
553     */
554    int mLruProcessServiceStart = 0;
555
556    /**
557     * List of processes that should gc as soon as things are idle.
558     */
559    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
560
561    /**
562     * Processes we want to collect PSS data from.
563     */
564    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
565
566    /**
567     * Last time we requested PSS data of all processes.
568     */
569    long mLastFullPssTime = SystemClock.uptimeMillis();
570
571    /**
572     * This is the process holding what we currently consider to be
573     * the "home" activity.
574     */
575    ProcessRecord mHomeProcess;
576
577    /**
578     * This is the process holding the activity the user last visited that
579     * is in a different process from the one they are currently in.
580     */
581    ProcessRecord mPreviousProcess;
582
583    /**
584     * The time at which the previous process was last visible.
585     */
586    long mPreviousProcessVisibleTime;
587
588    /**
589     * Which uses have been started, so are allowed to run code.
590     */
591    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
592
593    /**
594     * LRU list of history of current users.  Most recently current is at the end.
595     */
596    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
597
598    /**
599     * Constant array of the users that are currently started.
600     */
601    int[] mStartedUserArray = new int[] { 0 };
602
603    /**
604     * Registered observers of the user switching mechanics.
605     */
606    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
607            = new RemoteCallbackList<IUserSwitchObserver>();
608
609    /**
610     * Currently active user switch.
611     */
612    Object mCurUserSwitchCallback;
613
614    /**
615     * Packages that the user has asked to have run in screen size
616     * compatibility mode instead of filling the screen.
617     */
618    final CompatModePackages mCompatModePackages;
619
620    /**
621     * Set of IntentSenderRecord objects that are currently active.
622     */
623    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
624            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
625
626    /**
627     * Fingerprints (hashCode()) of stack traces that we've
628     * already logged DropBox entries for.  Guarded by itself.  If
629     * something (rogue user app) forces this over
630     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
631     */
632    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
633    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
634
635    /**
636     * Strict Mode background batched logging state.
637     *
638     * The string buffer is guarded by itself, and its lock is also
639     * used to determine if another batched write is already
640     * in-flight.
641     */
642    private final StringBuilder mStrictModeBuffer = new StringBuilder();
643
644    /**
645     * Keeps track of all IIntentReceivers that have been registered for
646     * broadcasts.  Hash keys are the receiver IBinder, hash value is
647     * a ReceiverList.
648     */
649    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
650            new HashMap<IBinder, ReceiverList>();
651
652    /**
653     * Resolver for broadcast intents to registered receivers.
654     * Holds BroadcastFilter (subclass of IntentFilter).
655     */
656    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
657            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
658        @Override
659        protected boolean allowFilterResult(
660                BroadcastFilter filter, List<BroadcastFilter> dest) {
661            IBinder target = filter.receiverList.receiver.asBinder();
662            for (int i=dest.size()-1; i>=0; i--) {
663                if (dest.get(i).receiverList.receiver.asBinder() == target) {
664                    return false;
665                }
666            }
667            return true;
668        }
669
670        @Override
671        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
672            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
673                    || userId == filter.owningUserId) {
674                return super.newResult(filter, match, userId);
675            }
676            return null;
677        }
678
679        @Override
680        protected BroadcastFilter[] newArray(int size) {
681            return new BroadcastFilter[size];
682        }
683
684        @Override
685        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
686            return packageName.equals(filter.packageName);
687        }
688    };
689
690    /**
691     * State of all active sticky broadcasts per user.  Keys are the action of the
692     * sticky Intent, values are an ArrayList of all broadcasted intents with
693     * that action (which should usually be one).  The SparseArray is keyed
694     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
695     * for stickies that are sent to all users.
696     */
697    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
698            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
699
700    final ActiveServices mServices;
701
702    /**
703     * Backup/restore process management
704     */
705    String mBackupAppName = null;
706    BackupRecord mBackupTarget = null;
707
708    final ProviderMap mProviderMap;
709
710    /**
711     * List of content providers who have clients waiting for them.  The
712     * application is currently being launched and the provider will be
713     * removed from this list once it is published.
714     */
715    final ArrayList<ContentProviderRecord> mLaunchingProviders
716            = new ArrayList<ContentProviderRecord>();
717
718    /**
719     * File storing persisted {@link #mGrantedUriPermissions}.
720     */
721    private final AtomicFile mGrantFile;
722
723    /** XML constants used in {@link #mGrantFile} */
724    private static final String TAG_URI_GRANTS = "uri-grants";
725    private static final String TAG_URI_GRANT = "uri-grant";
726    private static final String ATTR_USER_HANDLE = "userHandle";
727    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
728    private static final String ATTR_TARGET_USER_ID = "targetUserId";
729    private static final String ATTR_SOURCE_PKG = "sourcePkg";
730    private static final String ATTR_TARGET_PKG = "targetPkg";
731    private static final String ATTR_URI = "uri";
732    private static final String ATTR_MODE_FLAGS = "modeFlags";
733    private static final String ATTR_CREATED_TIME = "createdTime";
734    private static final String ATTR_PREFIX = "prefix";
735
736    /**
737     * Global set of specific {@link Uri} permissions that have been granted.
738     * This optimized lookup structure maps from {@link UriPermission#targetUid}
739     * to {@link UriPermission#uri} to {@link UriPermission}.
740     */
741    @GuardedBy("this")
742    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
743            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
744
745    public static class GrantUri {
746        public final int sourceUserId;
747        public final Uri uri;
748        public boolean prefix;
749
750        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
751            this.sourceUserId = sourceUserId;
752            this.uri = uri;
753            this.prefix = prefix;
754        }
755
756        @Override
757        public int hashCode() {
758            return toString().hashCode();
759        }
760
761        @Override
762        public boolean equals(Object o) {
763            if (o instanceof GrantUri) {
764                GrantUri other = (GrantUri) o;
765                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
766                        && prefix == other.prefix;
767            }
768            return false;
769        }
770
771        @Override
772        public String toString() {
773            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
774            if (prefix) result += " [prefix]";
775            return result;
776        }
777
778        public String toSafeString() {
779            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
780            if (prefix) result += " [prefix]";
781            return result;
782        }
783
784        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
785            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
786                    ContentProvider.getUriWithoutUserId(uri), false);
787        }
788    }
789
790    CoreSettingsObserver mCoreSettingsObserver;
791
792    /**
793     * Thread-local storage used to carry caller permissions over through
794     * indirect content-provider access.
795     */
796    private class Identity {
797        public int pid;
798        public int uid;
799
800        Identity(int _pid, int _uid) {
801            pid = _pid;
802            uid = _uid;
803        }
804    }
805
806    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
807
808    /**
809     * All information we have collected about the runtime performance of
810     * any user id that can impact battery performance.
811     */
812    final BatteryStatsService mBatteryStatsService;
813
814    /**
815     * Information about component usage
816     */
817    final UsageStatsService mUsageStatsService;
818
819    /**
820     * Information about and control over application operations
821     */
822    final AppOpsService mAppOpsService;
823
824    /**
825     * Save recent tasks information across reboots.
826     */
827    final TaskPersister mTaskPersister;
828
829    /**
830     * Current configuration information.  HistoryRecord objects are given
831     * a reference to this object to indicate which configuration they are
832     * currently running in, so this object must be kept immutable.
833     */
834    Configuration mConfiguration = new Configuration();
835
836    /**
837     * Current sequencing integer of the configuration, for skipping old
838     * configurations.
839     */
840    int mConfigurationSeq = 0;
841
842    /**
843     * Hardware-reported OpenGLES version.
844     */
845    final int GL_ES_VERSION;
846
847    /**
848     * List of initialization arguments to pass to all processes when binding applications to them.
849     * For example, references to the commonly used services.
850     */
851    HashMap<String, IBinder> mAppBindArgs;
852
853    /**
854     * Temporary to avoid allocations.  Protected by main lock.
855     */
856    final StringBuilder mStringBuilder = new StringBuilder(256);
857
858    /**
859     * Used to control how we initialize the service.
860     */
861    ComponentName mTopComponent;
862    String mTopAction = Intent.ACTION_MAIN;
863    String mTopData;
864    boolean mProcessesReady = false;
865    boolean mSystemReady = false;
866    boolean mBooting = false;
867    boolean mWaitingUpdate = false;
868    boolean mDidUpdate = false;
869    boolean mOnBattery = false;
870    boolean mLaunchWarningShown = false;
871
872    Context mContext;
873
874    int mFactoryTest;
875
876    boolean mCheckedForSetup;
877
878    /**
879     * The time at which we will allow normal application switches again,
880     * after a call to {@link #stopAppSwitches()}.
881     */
882    long mAppSwitchesAllowedTime;
883
884    /**
885     * This is set to true after the first switch after mAppSwitchesAllowedTime
886     * is set; any switches after that will clear the time.
887     */
888    boolean mDidAppSwitch;
889
890    /**
891     * Last time (in realtime) at which we checked for power usage.
892     */
893    long mLastPowerCheckRealtime;
894
895    /**
896     * Last time (in uptime) at which we checked for power usage.
897     */
898    long mLastPowerCheckUptime;
899
900    /**
901     * Set while we are wanting to sleep, to prevent any
902     * activities from being started/resumed.
903     */
904    private boolean mSleeping = false;
905
906    /**
907     * Set while we are running a voice interaction.  This overrides
908     * sleeping while it is active.
909     */
910    private boolean mRunningVoice = false;
911
912    /**
913     * State of external calls telling us if the device is asleep.
914     */
915    private boolean mWentToSleep = false;
916
917    /**
918     * State of external call telling us if the lock screen is shown.
919     */
920    private boolean mLockScreenShown = false;
921
922    /**
923     * Set if we are shutting down the system, similar to sleeping.
924     */
925    boolean mShuttingDown = false;
926
927    /**
928     * Current sequence id for oom_adj computation traversal.
929     */
930    int mAdjSeq = 0;
931
932    /**
933     * Current sequence id for process LRU updating.
934     */
935    int mLruSeq = 0;
936
937    /**
938     * Keep track of the non-cached/empty process we last found, to help
939     * determine how to distribute cached/empty processes next time.
940     */
941    int mNumNonCachedProcs = 0;
942
943    /**
944     * Keep track of the number of cached hidden procs, to balance oom adj
945     * distribution between those and empty procs.
946     */
947    int mNumCachedHiddenProcs = 0;
948
949    /**
950     * Keep track of the number of service processes we last found, to
951     * determine on the next iteration which should be B services.
952     */
953    int mNumServiceProcs = 0;
954    int mNewNumAServiceProcs = 0;
955    int mNewNumServiceProcs = 0;
956
957    /**
958     * Allow the current computed overall memory level of the system to go down?
959     * This is set to false when we are killing processes for reasons other than
960     * memory management, so that the now smaller process list will not be taken as
961     * an indication that memory is tighter.
962     */
963    boolean mAllowLowerMemLevel = false;
964
965    /**
966     * The last computed memory level, for holding when we are in a state that
967     * processes are going away for other reasons.
968     */
969    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
970
971    /**
972     * The last total number of process we have, to determine if changes actually look
973     * like a shrinking number of process due to lower RAM.
974     */
975    int mLastNumProcesses;
976
977    /**
978     * The uptime of the last time we performed idle maintenance.
979     */
980    long mLastIdleTime = SystemClock.uptimeMillis();
981
982    /**
983     * Total time spent with RAM that has been added in the past since the last idle time.
984     */
985    long mLowRamTimeSinceLastIdle = 0;
986
987    /**
988     * If RAM is currently low, when that horrible situation started.
989     */
990    long mLowRamStartTime = 0;
991
992    /**
993     * For reporting to battery stats the current top application.
994     */
995    private String mCurResumedPackage = null;
996    private int mCurResumedUid = -1;
997
998    /**
999     * For reporting to battery stats the apps currently running foreground
1000     * service.  The ProcessMap is package/uid tuples; each of these contain
1001     * an array of the currently foreground processes.
1002     */
1003    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1004            = new ProcessMap<ArrayList<ProcessRecord>>();
1005
1006    /**
1007     * This is set if we had to do a delayed dexopt of an app before launching
1008     * it, to increase the ANR timeouts in that case.
1009     */
1010    boolean mDidDexOpt;
1011
1012    /**
1013     * Set if the systemServer made a call to enterSafeMode.
1014     */
1015    boolean mSafeMode;
1016
1017    String mDebugApp = null;
1018    boolean mWaitForDebugger = false;
1019    boolean mDebugTransient = false;
1020    String mOrigDebugApp = null;
1021    boolean mOrigWaitForDebugger = false;
1022    boolean mAlwaysFinishActivities = false;
1023    IActivityController mController = null;
1024    String mProfileApp = null;
1025    ProcessRecord mProfileProc = null;
1026    String mProfileFile;
1027    ParcelFileDescriptor mProfileFd;
1028    int mProfileType = 0;
1029    boolean mAutoStopProfiler = false;
1030    String mOpenGlTraceApp = null;
1031
1032    static class ProcessChangeItem {
1033        static final int CHANGE_ACTIVITIES = 1<<0;
1034        static final int CHANGE_PROCESS_STATE = 1<<1;
1035        int changes;
1036        int uid;
1037        int pid;
1038        int processState;
1039        boolean foregroundActivities;
1040    }
1041
1042    final RemoteCallbackList<IProcessObserver> mProcessObservers
1043            = new RemoteCallbackList<IProcessObserver>();
1044    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1045
1046    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1047            = new ArrayList<ProcessChangeItem>();
1048    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1049            = new ArrayList<ProcessChangeItem>();
1050
1051    /**
1052     * Runtime CPU use collection thread.  This object's lock is used to
1053     * protect all related state.
1054     */
1055    final Thread mProcessCpuThread;
1056
1057    /**
1058     * Used to collect process stats when showing not responding dialog.
1059     * Protected by mProcessCpuThread.
1060     */
1061    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1062            MONITOR_THREAD_CPU_USAGE);
1063    final AtomicLong mLastCpuTime = new AtomicLong(0);
1064    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1065
1066    long mLastWriteTime = 0;
1067
1068    /**
1069     * Used to retain an update lock when the foreground activity is in
1070     * immersive mode.
1071     */
1072    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1073
1074    /**
1075     * Set to true after the system has finished booting.
1076     */
1077    boolean mBooted = false;
1078
1079    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1080    int mProcessLimitOverride = -1;
1081
1082    WindowManagerService mWindowManager;
1083
1084    final ActivityThread mSystemThread;
1085
1086    int mCurrentUserId = 0;
1087    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1088    private UserManagerService mUserManager;
1089
1090    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1091        final ProcessRecord mApp;
1092        final int mPid;
1093        final IApplicationThread mAppThread;
1094
1095        AppDeathRecipient(ProcessRecord app, int pid,
1096                IApplicationThread thread) {
1097            if (localLOGV) Slog.v(
1098                TAG, "New death recipient " + this
1099                + " for thread " + thread.asBinder());
1100            mApp = app;
1101            mPid = pid;
1102            mAppThread = thread;
1103        }
1104
1105        @Override
1106        public void binderDied() {
1107            if (localLOGV) Slog.v(
1108                TAG, "Death received in " + this
1109                + " for thread " + mAppThread.asBinder());
1110            synchronized(ActivityManagerService.this) {
1111                appDiedLocked(mApp, mPid, mAppThread);
1112            }
1113        }
1114    }
1115
1116    static final int SHOW_ERROR_MSG = 1;
1117    static final int SHOW_NOT_RESPONDING_MSG = 2;
1118    static final int SHOW_FACTORY_ERROR_MSG = 3;
1119    static final int UPDATE_CONFIGURATION_MSG = 4;
1120    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1121    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1122    static final int SERVICE_TIMEOUT_MSG = 12;
1123    static final int UPDATE_TIME_ZONE = 13;
1124    static final int SHOW_UID_ERROR_MSG = 14;
1125    static final int IM_FEELING_LUCKY_MSG = 15;
1126    static final int PROC_START_TIMEOUT_MSG = 20;
1127    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1128    static final int KILL_APPLICATION_MSG = 22;
1129    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1130    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1131    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1132    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1133    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1134    static final int CLEAR_DNS_CACHE_MSG = 28;
1135    static final int UPDATE_HTTP_PROXY_MSG = 29;
1136    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1137    static final int DISPATCH_PROCESSES_CHANGED = 31;
1138    static final int DISPATCH_PROCESS_DIED = 32;
1139    static final int REPORT_MEM_USAGE_MSG = 33;
1140    static final int REPORT_USER_SWITCH_MSG = 34;
1141    static final int CONTINUE_USER_SWITCH_MSG = 35;
1142    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1143    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1144    static final int PERSIST_URI_GRANTS_MSG = 38;
1145    static final int REQUEST_ALL_PSS_MSG = 39;
1146    static final int START_PROFILES_MSG = 40;
1147    static final int UPDATE_TIME = 41;
1148    static final int SYSTEM_USER_START_MSG = 42;
1149    static final int SYSTEM_USER_CURRENT_MSG = 43;
1150
1151    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1152    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1153    static final int FIRST_COMPAT_MODE_MSG = 300;
1154    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1155
1156    AlertDialog mUidAlert;
1157    CompatModeDialog mCompatModeDialog;
1158    long mLastMemUsageReportTime = 0;
1159
1160    /**
1161     * Flag whether the current user is a "monkey", i.e. whether
1162     * the UI is driven by a UI automation tool.
1163     */
1164    private boolean mUserIsMonkey;
1165
1166    final ServiceThread mHandlerThread;
1167    final MainHandler mHandler;
1168
1169    final class MainHandler extends Handler {
1170        public MainHandler(Looper looper) {
1171            super(looper, null, true);
1172        }
1173
1174        @Override
1175        public void handleMessage(Message msg) {
1176            switch (msg.what) {
1177            case SHOW_ERROR_MSG: {
1178                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1179                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1180                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1181                synchronized (ActivityManagerService.this) {
1182                    ProcessRecord proc = (ProcessRecord)data.get("app");
1183                    AppErrorResult res = (AppErrorResult) data.get("result");
1184                    if (proc != null && proc.crashDialog != null) {
1185                        Slog.e(TAG, "App already has crash dialog: " + proc);
1186                        if (res != null) {
1187                            res.set(0);
1188                        }
1189                        return;
1190                    }
1191                    if (!showBackground && UserHandle.getAppId(proc.uid)
1192                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1193                            && proc.pid != MY_PID) {
1194                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1195                        if (res != null) {
1196                            res.set(0);
1197                        }
1198                        return;
1199                    }
1200                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1201                        Dialog d = new AppErrorDialog(mContext,
1202                                ActivityManagerService.this, res, proc);
1203                        d.show();
1204                        proc.crashDialog = d;
1205                    } else {
1206                        // The device is asleep, so just pretend that the user
1207                        // saw a crash dialog and hit "force quit".
1208                        if (res != null) {
1209                            res.set(0);
1210                        }
1211                    }
1212                }
1213
1214                ensureBootCompleted();
1215            } break;
1216            case SHOW_NOT_RESPONDING_MSG: {
1217                synchronized (ActivityManagerService.this) {
1218                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1219                    ProcessRecord proc = (ProcessRecord)data.get("app");
1220                    if (proc != null && proc.anrDialog != null) {
1221                        Slog.e(TAG, "App already has anr dialog: " + proc);
1222                        return;
1223                    }
1224
1225                    Intent intent = new Intent("android.intent.action.ANR");
1226                    if (!mProcessesReady) {
1227                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1228                                | Intent.FLAG_RECEIVER_FOREGROUND);
1229                    }
1230                    broadcastIntentLocked(null, null, intent,
1231                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1232                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1233
1234                    if (mShowDialogs) {
1235                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1236                                mContext, proc, (ActivityRecord)data.get("activity"),
1237                                msg.arg1 != 0);
1238                        d.show();
1239                        proc.anrDialog = d;
1240                    } else {
1241                        // Just kill the app if there is no dialog to be shown.
1242                        killAppAtUsersRequest(proc, null);
1243                    }
1244                }
1245
1246                ensureBootCompleted();
1247            } break;
1248            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1249                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1250                synchronized (ActivityManagerService.this) {
1251                    ProcessRecord proc = (ProcessRecord) data.get("app");
1252                    if (proc == null) {
1253                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1254                        break;
1255                    }
1256                    if (proc.crashDialog != null) {
1257                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1258                        return;
1259                    }
1260                    AppErrorResult res = (AppErrorResult) data.get("result");
1261                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1262                        Dialog d = new StrictModeViolationDialog(mContext,
1263                                ActivityManagerService.this, res, proc);
1264                        d.show();
1265                        proc.crashDialog = d;
1266                    } else {
1267                        // The device is asleep, so just pretend that the user
1268                        // saw a crash dialog and hit "force quit".
1269                        res.set(0);
1270                    }
1271                }
1272                ensureBootCompleted();
1273            } break;
1274            case SHOW_FACTORY_ERROR_MSG: {
1275                Dialog d = new FactoryErrorDialog(
1276                    mContext, msg.getData().getCharSequence("msg"));
1277                d.show();
1278                ensureBootCompleted();
1279            } break;
1280            case UPDATE_CONFIGURATION_MSG: {
1281                final ContentResolver resolver = mContext.getContentResolver();
1282                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1283            } break;
1284            case GC_BACKGROUND_PROCESSES_MSG: {
1285                synchronized (ActivityManagerService.this) {
1286                    performAppGcsIfAppropriateLocked();
1287                }
1288            } break;
1289            case WAIT_FOR_DEBUGGER_MSG: {
1290                synchronized (ActivityManagerService.this) {
1291                    ProcessRecord app = (ProcessRecord)msg.obj;
1292                    if (msg.arg1 != 0) {
1293                        if (!app.waitedForDebugger) {
1294                            Dialog d = new AppWaitingForDebuggerDialog(
1295                                    ActivityManagerService.this,
1296                                    mContext, app);
1297                            app.waitDialog = d;
1298                            app.waitedForDebugger = true;
1299                            d.show();
1300                        }
1301                    } else {
1302                        if (app.waitDialog != null) {
1303                            app.waitDialog.dismiss();
1304                            app.waitDialog = null;
1305                        }
1306                    }
1307                }
1308            } break;
1309            case SERVICE_TIMEOUT_MSG: {
1310                if (mDidDexOpt) {
1311                    mDidDexOpt = false;
1312                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1313                    nmsg.obj = msg.obj;
1314                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1315                    return;
1316                }
1317                mServices.serviceTimeout((ProcessRecord)msg.obj);
1318            } break;
1319            case UPDATE_TIME_ZONE: {
1320                synchronized (ActivityManagerService.this) {
1321                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1322                        ProcessRecord r = mLruProcesses.get(i);
1323                        if (r.thread != null) {
1324                            try {
1325                                r.thread.updateTimeZone();
1326                            } catch (RemoteException ex) {
1327                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1328                            }
1329                        }
1330                    }
1331                }
1332            } break;
1333            case CLEAR_DNS_CACHE_MSG: {
1334                synchronized (ActivityManagerService.this) {
1335                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1336                        ProcessRecord r = mLruProcesses.get(i);
1337                        if (r.thread != null) {
1338                            try {
1339                                r.thread.clearDnsCache();
1340                            } catch (RemoteException ex) {
1341                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1342                            }
1343                        }
1344                    }
1345                }
1346            } break;
1347            case UPDATE_HTTP_PROXY_MSG: {
1348                ProxyInfo proxy = (ProxyInfo)msg.obj;
1349                String host = "";
1350                String port = "";
1351                String exclList = "";
1352                Uri pacFileUrl = Uri.EMPTY;
1353                if (proxy != null) {
1354                    host = proxy.getHost();
1355                    port = Integer.toString(proxy.getPort());
1356                    exclList = proxy.getExclusionListAsString();
1357                    pacFileUrl = proxy.getPacFileUrl();
1358                }
1359                synchronized (ActivityManagerService.this) {
1360                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1361                        ProcessRecord r = mLruProcesses.get(i);
1362                        if (r.thread != null) {
1363                            try {
1364                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1365                            } catch (RemoteException ex) {
1366                                Slog.w(TAG, "Failed to update http proxy for: " +
1367                                        r.info.processName);
1368                            }
1369                        }
1370                    }
1371                }
1372            } break;
1373            case SHOW_UID_ERROR_MSG: {
1374                String title = "System UIDs Inconsistent";
1375                String text = "UIDs on the system are inconsistent, you need to wipe your"
1376                        + " data partition or your device will be unstable.";
1377                Log.e(TAG, title + ": " + text);
1378                if (mShowDialogs) {
1379                    // XXX This is a temporary dialog, no need to localize.
1380                    AlertDialog d = new BaseErrorDialog(mContext);
1381                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1382                    d.setCancelable(false);
1383                    d.setTitle(title);
1384                    d.setMessage(text);
1385                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1386                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1387                    mUidAlert = d;
1388                    d.show();
1389                }
1390            } break;
1391            case IM_FEELING_LUCKY_MSG: {
1392                if (mUidAlert != null) {
1393                    mUidAlert.dismiss();
1394                    mUidAlert = null;
1395                }
1396            } break;
1397            case PROC_START_TIMEOUT_MSG: {
1398                if (mDidDexOpt) {
1399                    mDidDexOpt = false;
1400                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1401                    nmsg.obj = msg.obj;
1402                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1403                    return;
1404                }
1405                ProcessRecord app = (ProcessRecord)msg.obj;
1406                synchronized (ActivityManagerService.this) {
1407                    processStartTimedOutLocked(app);
1408                }
1409            } break;
1410            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1411                synchronized (ActivityManagerService.this) {
1412                    doPendingActivityLaunchesLocked(true);
1413                }
1414            } break;
1415            case KILL_APPLICATION_MSG: {
1416                synchronized (ActivityManagerService.this) {
1417                    int appid = msg.arg1;
1418                    boolean restart = (msg.arg2 == 1);
1419                    Bundle bundle = (Bundle)msg.obj;
1420                    String pkg = bundle.getString("pkg");
1421                    String reason = bundle.getString("reason");
1422                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1423                            false, UserHandle.USER_ALL, reason);
1424                }
1425            } break;
1426            case FINALIZE_PENDING_INTENT_MSG: {
1427                ((PendingIntentRecord)msg.obj).completeFinalize();
1428            } break;
1429            case POST_HEAVY_NOTIFICATION_MSG: {
1430                INotificationManager inm = NotificationManager.getService();
1431                if (inm == null) {
1432                    return;
1433                }
1434
1435                ActivityRecord root = (ActivityRecord)msg.obj;
1436                ProcessRecord process = root.app;
1437                if (process == null) {
1438                    return;
1439                }
1440
1441                try {
1442                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1443                    String text = mContext.getString(R.string.heavy_weight_notification,
1444                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1445                    Notification notification = new Notification();
1446                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1447                    notification.when = 0;
1448                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1449                    notification.tickerText = text;
1450                    notification.defaults = 0; // please be quiet
1451                    notification.sound = null;
1452                    notification.vibrate = null;
1453                    notification.setLatestEventInfo(context, text,
1454                            mContext.getText(R.string.heavy_weight_notification_detail),
1455                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1456                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1457                                    new UserHandle(root.userId)));
1458
1459                    try {
1460                        int[] outId = new int[1];
1461                        inm.enqueueNotificationWithTag("android", "android", null,
1462                                R.string.heavy_weight_notification,
1463                                notification, outId, root.userId);
1464                    } catch (RuntimeException e) {
1465                        Slog.w(ActivityManagerService.TAG,
1466                                "Error showing notification for heavy-weight app", e);
1467                    } catch (RemoteException e) {
1468                    }
1469                } catch (NameNotFoundException e) {
1470                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1471                }
1472            } break;
1473            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1474                INotificationManager inm = NotificationManager.getService();
1475                if (inm == null) {
1476                    return;
1477                }
1478                try {
1479                    inm.cancelNotificationWithTag("android", null,
1480                            R.string.heavy_weight_notification,  msg.arg1);
1481                } catch (RuntimeException e) {
1482                    Slog.w(ActivityManagerService.TAG,
1483                            "Error canceling notification for service", e);
1484                } catch (RemoteException e) {
1485                }
1486            } break;
1487            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1488                synchronized (ActivityManagerService.this) {
1489                    checkExcessivePowerUsageLocked(true);
1490                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1491                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1492                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1493                }
1494            } break;
1495            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1496                synchronized (ActivityManagerService.this) {
1497                    ActivityRecord ar = (ActivityRecord)msg.obj;
1498                    if (mCompatModeDialog != null) {
1499                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1500                                ar.info.applicationInfo.packageName)) {
1501                            return;
1502                        }
1503                        mCompatModeDialog.dismiss();
1504                        mCompatModeDialog = null;
1505                    }
1506                    if (ar != null && false) {
1507                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1508                                ar.packageName)) {
1509                            int mode = mCompatModePackages.computeCompatModeLocked(
1510                                    ar.info.applicationInfo);
1511                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1512                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1513                                mCompatModeDialog = new CompatModeDialog(
1514                                        ActivityManagerService.this, mContext,
1515                                        ar.info.applicationInfo);
1516                                mCompatModeDialog.show();
1517                            }
1518                        }
1519                    }
1520                }
1521                break;
1522            }
1523            case DISPATCH_PROCESSES_CHANGED: {
1524                dispatchProcessesChanged();
1525                break;
1526            }
1527            case DISPATCH_PROCESS_DIED: {
1528                final int pid = msg.arg1;
1529                final int uid = msg.arg2;
1530                dispatchProcessDied(pid, uid);
1531                break;
1532            }
1533            case REPORT_MEM_USAGE_MSG: {
1534                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1535                Thread thread = new Thread() {
1536                    @Override public void run() {
1537                        final SparseArray<ProcessMemInfo> infoMap
1538                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1539                        for (int i=0, N=memInfos.size(); i<N; i++) {
1540                            ProcessMemInfo mi = memInfos.get(i);
1541                            infoMap.put(mi.pid, mi);
1542                        }
1543                        updateCpuStatsNow();
1544                        synchronized (mProcessCpuThread) {
1545                            final int N = mProcessCpuTracker.countStats();
1546                            for (int i=0; i<N; i++) {
1547                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1548                                if (st.vsize > 0) {
1549                                    long pss = Debug.getPss(st.pid, null);
1550                                    if (pss > 0) {
1551                                        if (infoMap.indexOfKey(st.pid) < 0) {
1552                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1553                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1554                                            mi.pss = pss;
1555                                            memInfos.add(mi);
1556                                        }
1557                                    }
1558                                }
1559                            }
1560                        }
1561
1562                        long totalPss = 0;
1563                        for (int i=0, N=memInfos.size(); i<N; i++) {
1564                            ProcessMemInfo mi = memInfos.get(i);
1565                            if (mi.pss == 0) {
1566                                mi.pss = Debug.getPss(mi.pid, null);
1567                            }
1568                            totalPss += mi.pss;
1569                        }
1570                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1571                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1572                                if (lhs.oomAdj != rhs.oomAdj) {
1573                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1574                                }
1575                                if (lhs.pss != rhs.pss) {
1576                                    return lhs.pss < rhs.pss ? 1 : -1;
1577                                }
1578                                return 0;
1579                            }
1580                        });
1581
1582                        StringBuilder tag = new StringBuilder(128);
1583                        StringBuilder stack = new StringBuilder(128);
1584                        tag.append("Low on memory -- ");
1585                        appendMemBucket(tag, totalPss, "total", false);
1586                        appendMemBucket(stack, totalPss, "total", true);
1587
1588                        StringBuilder logBuilder = new StringBuilder(1024);
1589                        logBuilder.append("Low on memory:\n");
1590
1591                        boolean firstLine = true;
1592                        int lastOomAdj = Integer.MIN_VALUE;
1593                        for (int i=0, N=memInfos.size(); i<N; i++) {
1594                            ProcessMemInfo mi = memInfos.get(i);
1595
1596                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1597                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1598                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1599                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1600                                if (lastOomAdj != mi.oomAdj) {
1601                                    lastOomAdj = mi.oomAdj;
1602                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1603                                        tag.append(" / ");
1604                                    }
1605                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1606                                        if (firstLine) {
1607                                            stack.append(":");
1608                                            firstLine = false;
1609                                        }
1610                                        stack.append("\n\t at ");
1611                                    } else {
1612                                        stack.append("$");
1613                                    }
1614                                } else {
1615                                    tag.append(" ");
1616                                    stack.append("$");
1617                                }
1618                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1619                                    appendMemBucket(tag, mi.pss, mi.name, false);
1620                                }
1621                                appendMemBucket(stack, mi.pss, mi.name, true);
1622                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1623                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1624                                    stack.append("(");
1625                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1626                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1627                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1628                                            stack.append(":");
1629                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1630                                        }
1631                                    }
1632                                    stack.append(")");
1633                                }
1634                            }
1635
1636                            logBuilder.append("  ");
1637                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1638                            logBuilder.append(' ');
1639                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1640                            logBuilder.append(' ');
1641                            ProcessList.appendRamKb(logBuilder, mi.pss);
1642                            logBuilder.append(" kB: ");
1643                            logBuilder.append(mi.name);
1644                            logBuilder.append(" (");
1645                            logBuilder.append(mi.pid);
1646                            logBuilder.append(") ");
1647                            logBuilder.append(mi.adjType);
1648                            logBuilder.append('\n');
1649                            if (mi.adjReason != null) {
1650                                logBuilder.append("                      ");
1651                                logBuilder.append(mi.adjReason);
1652                                logBuilder.append('\n');
1653                            }
1654                        }
1655
1656                        logBuilder.append("           ");
1657                        ProcessList.appendRamKb(logBuilder, totalPss);
1658                        logBuilder.append(" kB: TOTAL\n");
1659
1660                        long[] infos = new long[Debug.MEMINFO_COUNT];
1661                        Debug.getMemInfo(infos);
1662                        logBuilder.append("  MemInfo: ");
1663                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1664                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1665                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1666                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1667                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1668                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1669                            logBuilder.append("  ZRAM: ");
1670                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1671                            logBuilder.append(" kB RAM, ");
1672                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1673                            logBuilder.append(" kB swap total, ");
1674                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1675                            logBuilder.append(" kB swap free\n");
1676                        }
1677                        Slog.i(TAG, logBuilder.toString());
1678
1679                        StringBuilder dropBuilder = new StringBuilder(1024);
1680                        /*
1681                        StringWriter oomSw = new StringWriter();
1682                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1683                        StringWriter catSw = new StringWriter();
1684                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1685                        String[] emptyArgs = new String[] { };
1686                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1687                        oomPw.flush();
1688                        String oomString = oomSw.toString();
1689                        */
1690                        dropBuilder.append(stack);
1691                        dropBuilder.append('\n');
1692                        dropBuilder.append('\n');
1693                        dropBuilder.append(logBuilder);
1694                        dropBuilder.append('\n');
1695                        /*
1696                        dropBuilder.append(oomString);
1697                        dropBuilder.append('\n');
1698                        */
1699                        StringWriter catSw = new StringWriter();
1700                        synchronized (ActivityManagerService.this) {
1701                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1702                            String[] emptyArgs = new String[] { };
1703                            catPw.println();
1704                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1705                            catPw.println();
1706                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1707                                    false, false, null);
1708                            catPw.println();
1709                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1710                            catPw.flush();
1711                        }
1712                        dropBuilder.append(catSw.toString());
1713                        addErrorToDropBox("lowmem", null, "system_server", null,
1714                                null, tag.toString(), dropBuilder.toString(), null, null);
1715                        //Slog.i(TAG, "Sent to dropbox:");
1716                        //Slog.i(TAG, dropBuilder.toString());
1717                        synchronized (ActivityManagerService.this) {
1718                            long now = SystemClock.uptimeMillis();
1719                            if (mLastMemUsageReportTime < now) {
1720                                mLastMemUsageReportTime = now;
1721                            }
1722                        }
1723                    }
1724                };
1725                thread.start();
1726                break;
1727            }
1728            case REPORT_USER_SWITCH_MSG: {
1729                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1730                break;
1731            }
1732            case CONTINUE_USER_SWITCH_MSG: {
1733                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1734                break;
1735            }
1736            case USER_SWITCH_TIMEOUT_MSG: {
1737                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1738                break;
1739            }
1740            case IMMERSIVE_MODE_LOCK_MSG: {
1741                final boolean nextState = (msg.arg1 != 0);
1742                if (mUpdateLock.isHeld() != nextState) {
1743                    if (DEBUG_IMMERSIVE) {
1744                        final ActivityRecord r = (ActivityRecord) msg.obj;
1745                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1746                    }
1747                    if (nextState) {
1748                        mUpdateLock.acquire();
1749                    } else {
1750                        mUpdateLock.release();
1751                    }
1752                }
1753                break;
1754            }
1755            case PERSIST_URI_GRANTS_MSG: {
1756                writeGrantedUriPermissions();
1757                break;
1758            }
1759            case REQUEST_ALL_PSS_MSG: {
1760                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1761                break;
1762            }
1763            case START_PROFILES_MSG: {
1764                synchronized (ActivityManagerService.this) {
1765                    startProfilesLocked();
1766                }
1767                break;
1768            }
1769            case UPDATE_TIME: {
1770                synchronized (ActivityManagerService.this) {
1771                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1772                        ProcessRecord r = mLruProcesses.get(i);
1773                        if (r.thread != null) {
1774                            try {
1775                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1776                            } catch (RemoteException ex) {
1777                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1778                            }
1779                        }
1780                    }
1781                }
1782                break;
1783            }
1784            case SYSTEM_USER_START_MSG: {
1785                mSystemServiceManager.startUser(msg.arg1);
1786                break;
1787            }
1788            case SYSTEM_USER_CURRENT_MSG: {
1789                mSystemServiceManager.switchUser(msg.arg1);
1790                break;
1791            }
1792            }
1793        }
1794    };
1795
1796    static final int COLLECT_PSS_BG_MSG = 1;
1797
1798    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1799        @Override
1800        public void handleMessage(Message msg) {
1801            switch (msg.what) {
1802            case COLLECT_PSS_BG_MSG: {
1803                int i=0, num=0;
1804                long start = SystemClock.uptimeMillis();
1805                long[] tmp = new long[1];
1806                do {
1807                    ProcessRecord proc;
1808                    int procState;
1809                    int pid;
1810                    synchronized (ActivityManagerService.this) {
1811                        if (i >= mPendingPssProcesses.size()) {
1812                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1813                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1814                            mPendingPssProcesses.clear();
1815                            return;
1816                        }
1817                        proc = mPendingPssProcesses.get(i);
1818                        procState = proc.pssProcState;
1819                        if (proc.thread != null && procState == proc.setProcState) {
1820                            pid = proc.pid;
1821                        } else {
1822                            proc = null;
1823                            pid = 0;
1824                        }
1825                        i++;
1826                    }
1827                    if (proc != null) {
1828                        long pss = Debug.getPss(pid, tmp);
1829                        synchronized (ActivityManagerService.this) {
1830                            if (proc.thread != null && proc.setProcState == procState
1831                                    && proc.pid == pid) {
1832                                num++;
1833                                proc.lastPssTime = SystemClock.uptimeMillis();
1834                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1835                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1836                                        + ": " + pss + " lastPss=" + proc.lastPss
1837                                        + " state=" + ProcessList.makeProcStateString(procState));
1838                                if (proc.initialIdlePss == 0) {
1839                                    proc.initialIdlePss = pss;
1840                                }
1841                                proc.lastPss = pss;
1842                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1843                                    proc.lastCachedPss = pss;
1844                                }
1845                            }
1846                        }
1847                    }
1848                } while (true);
1849            }
1850            }
1851        }
1852    };
1853
1854    /**
1855     * Monitor for package changes and update our internal state.
1856     */
1857    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1858        @Override
1859        public void onPackageRemoved(String packageName, int uid) {
1860            // Remove all tasks with activities in the specified package from the list of recent tasks
1861            synchronized (ActivityManagerService.this) {
1862                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1863                    TaskRecord tr = mRecentTasks.get(i);
1864                    ComponentName cn = tr.intent.getComponent();
1865                    if (cn != null && cn.getPackageName().equals(packageName)) {
1866                        // If the package name matches, remove the task and kill the process
1867                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1868                    }
1869                }
1870            }
1871        }
1872
1873        @Override
1874        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1875            onPackageModified(packageName);
1876            return true;
1877        }
1878
1879        @Override
1880        public void onPackageModified(String packageName) {
1881            final PackageManager pm = mContext.getPackageManager();
1882            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1883                    new ArrayList<Pair<Intent, Integer>>();
1884            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1885            // Copy the list of recent tasks so that we don't hold onto the lock on
1886            // ActivityManagerService for long periods while checking if components exist.
1887            synchronized (ActivityManagerService.this) {
1888                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1889                    TaskRecord tr = mRecentTasks.get(i);
1890                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1891                }
1892            }
1893            // Check the recent tasks and filter out all tasks with components that no longer exist.
1894            Intent tmpI = new Intent();
1895            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1896                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1897                ComponentName cn = p.first.getComponent();
1898                if (cn != null && cn.getPackageName().equals(packageName)) {
1899                    try {
1900                        // Add the task to the list to remove if the component no longer exists
1901                        tmpI.setComponent(cn);
1902                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1903                            tasksToRemove.add(p.second);
1904                        }
1905                    } catch (Exception e) {}
1906                }
1907            }
1908            // Prune all the tasks with removed components from the list of recent tasks
1909            synchronized (ActivityManagerService.this) {
1910                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1911                    // Remove the task but don't kill the process (since other components in that
1912                    // package may still be running and in the background)
1913                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1914                }
1915            }
1916        }
1917
1918        @Override
1919        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1920            // Force stop the specified packages
1921            if (packages != null) {
1922                for (String pkg : packages) {
1923                    synchronized (ActivityManagerService.this) {
1924                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1925                                "finished booting")) {
1926                            return true;
1927                        }
1928                    }
1929                }
1930            }
1931            return false;
1932        }
1933    };
1934
1935    public void setSystemProcess() {
1936        try {
1937            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1938            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1939            ServiceManager.addService("meminfo", new MemBinder(this));
1940            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1941            ServiceManager.addService("dbinfo", new DbBinder(this));
1942            if (MONITOR_CPU_USAGE) {
1943                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1944            }
1945            ServiceManager.addService("permission", new PermissionController(this));
1946
1947            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1948                    "android", STOCK_PM_FLAGS);
1949            mSystemThread.installSystemApplicationInfo(info);
1950
1951            synchronized (this) {
1952                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1953                app.persistent = true;
1954                app.pid = MY_PID;
1955                app.maxAdj = ProcessList.SYSTEM_ADJ;
1956                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1957                mProcessNames.put(app.processName, app.uid, app);
1958                synchronized (mPidsSelfLocked) {
1959                    mPidsSelfLocked.put(app.pid, app);
1960                }
1961                updateLruProcessLocked(app, false, null);
1962                updateOomAdjLocked();
1963            }
1964        } catch (PackageManager.NameNotFoundException e) {
1965            throw new RuntimeException(
1966                    "Unable to find android system package", e);
1967        }
1968    }
1969
1970    public void setWindowManager(WindowManagerService wm) {
1971        mWindowManager = wm;
1972        mStackSupervisor.setWindowManager(wm);
1973    }
1974
1975    public void startObservingNativeCrashes() {
1976        final NativeCrashListener ncl = new NativeCrashListener(this);
1977        ncl.start();
1978    }
1979
1980    public IAppOpsService getAppOpsService() {
1981        return mAppOpsService;
1982    }
1983
1984    static class MemBinder extends Binder {
1985        ActivityManagerService mActivityManagerService;
1986        MemBinder(ActivityManagerService activityManagerService) {
1987            mActivityManagerService = activityManagerService;
1988        }
1989
1990        @Override
1991        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1992            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1993                    != PackageManager.PERMISSION_GRANTED) {
1994                pw.println("Permission Denial: can't dump meminfo from from pid="
1995                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1996                        + " without permission " + android.Manifest.permission.DUMP);
1997                return;
1998            }
1999
2000            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2001        }
2002    }
2003
2004    static class GraphicsBinder extends Binder {
2005        ActivityManagerService mActivityManagerService;
2006        GraphicsBinder(ActivityManagerService activityManagerService) {
2007            mActivityManagerService = activityManagerService;
2008        }
2009
2010        @Override
2011        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2012            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2013                    != PackageManager.PERMISSION_GRANTED) {
2014                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2015                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2016                        + " without permission " + android.Manifest.permission.DUMP);
2017                return;
2018            }
2019
2020            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2021        }
2022    }
2023
2024    static class DbBinder extends Binder {
2025        ActivityManagerService mActivityManagerService;
2026        DbBinder(ActivityManagerService activityManagerService) {
2027            mActivityManagerService = activityManagerService;
2028        }
2029
2030        @Override
2031        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2032            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2033                    != PackageManager.PERMISSION_GRANTED) {
2034                pw.println("Permission Denial: can't dump dbinfo from from pid="
2035                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2036                        + " without permission " + android.Manifest.permission.DUMP);
2037                return;
2038            }
2039
2040            mActivityManagerService.dumpDbInfo(fd, pw, args);
2041        }
2042    }
2043
2044    static class CpuBinder extends Binder {
2045        ActivityManagerService mActivityManagerService;
2046        CpuBinder(ActivityManagerService activityManagerService) {
2047            mActivityManagerService = activityManagerService;
2048        }
2049
2050        @Override
2051        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2052            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2053                    != PackageManager.PERMISSION_GRANTED) {
2054                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2055                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2056                        + " without permission " + android.Manifest.permission.DUMP);
2057                return;
2058            }
2059
2060            synchronized (mActivityManagerService.mProcessCpuThread) {
2061                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2062                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2063                        SystemClock.uptimeMillis()));
2064            }
2065        }
2066    }
2067
2068    public static final class Lifecycle extends SystemService {
2069        private final ActivityManagerService mService;
2070
2071        public Lifecycle(Context context) {
2072            super(context);
2073            mService = new ActivityManagerService(context);
2074        }
2075
2076        @Override
2077        public void onStart() {
2078            mService.start();
2079        }
2080
2081        public ActivityManagerService getService() {
2082            return mService;
2083        }
2084    }
2085
2086    // Note: This method is invoked on the main thread but may need to attach various
2087    // handlers to other threads.  So take care to be explicit about the looper.
2088    public ActivityManagerService(Context systemContext) {
2089        mContext = systemContext;
2090        mFactoryTest = FactoryTest.getMode();
2091        mSystemThread = ActivityThread.currentActivityThread();
2092
2093        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2094
2095        mHandlerThread = new ServiceThread(TAG,
2096                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2097        mHandlerThread.start();
2098        mHandler = new MainHandler(mHandlerThread.getLooper());
2099
2100        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2101                "foreground", BROADCAST_FG_TIMEOUT, false);
2102        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2103                "background", BROADCAST_BG_TIMEOUT, true);
2104        mBroadcastQueues[0] = mFgBroadcastQueue;
2105        mBroadcastQueues[1] = mBgBroadcastQueue;
2106
2107        mServices = new ActiveServices(this);
2108        mProviderMap = new ProviderMap(this);
2109
2110        // TODO: Move creation of battery stats service outside of activity manager service.
2111        File dataDir = Environment.getDataDirectory();
2112        File systemDir = new File(dataDir, "system");
2113        systemDir.mkdirs();
2114        mBatteryStatsService = new BatteryStatsService(new File(
2115                systemDir, "batterystats.bin").toString(), mHandler);
2116        mBatteryStatsService.getActiveStatistics().readLocked();
2117        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2118        mOnBattery = DEBUG_POWER ? true
2119                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2120        mBatteryStatsService.getActiveStatistics().setCallback(this);
2121
2122        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2123
2124        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2125        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2126
2127        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2128
2129        // User 0 is the first and only user that runs at boot.
2130        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2131        mUserLru.add(Integer.valueOf(0));
2132        updateStartedUserArrayLocked();
2133
2134        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2135            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2136
2137        mConfiguration.setToDefaults();
2138        mConfiguration.setLocale(Locale.getDefault());
2139
2140        mConfigurationSeq = mConfiguration.seq = 1;
2141        mProcessCpuTracker.init();
2142
2143        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2144        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2145        mStackSupervisor = new ActivityStackSupervisor(this);
2146        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2147
2148        mProcessCpuThread = new Thread("CpuTracker") {
2149            @Override
2150            public void run() {
2151                while (true) {
2152                    try {
2153                        try {
2154                            synchronized(this) {
2155                                final long now = SystemClock.uptimeMillis();
2156                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2157                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2158                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2159                                //        + ", write delay=" + nextWriteDelay);
2160                                if (nextWriteDelay < nextCpuDelay) {
2161                                    nextCpuDelay = nextWriteDelay;
2162                                }
2163                                if (nextCpuDelay > 0) {
2164                                    mProcessCpuMutexFree.set(true);
2165                                    this.wait(nextCpuDelay);
2166                                }
2167                            }
2168                        } catch (InterruptedException e) {
2169                        }
2170                        updateCpuStatsNow();
2171                    } catch (Exception e) {
2172                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2173                    }
2174                }
2175            }
2176        };
2177
2178        Watchdog.getInstance().addMonitor(this);
2179        Watchdog.getInstance().addThread(mHandler);
2180    }
2181
2182    public void setSystemServiceManager(SystemServiceManager mgr) {
2183        mSystemServiceManager = mgr;
2184    }
2185
2186    private void start() {
2187        mProcessCpuThread.start();
2188
2189        mBatteryStatsService.publish(mContext);
2190        mUsageStatsService.publish(mContext);
2191        mAppOpsService.publish(mContext);
2192
2193        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2194    }
2195
2196    @Override
2197    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2198            throws RemoteException {
2199        if (code == SYSPROPS_TRANSACTION) {
2200            // We need to tell all apps about the system property change.
2201            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2202            synchronized(this) {
2203                final int NP = mProcessNames.getMap().size();
2204                for (int ip=0; ip<NP; ip++) {
2205                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2206                    final int NA = apps.size();
2207                    for (int ia=0; ia<NA; ia++) {
2208                        ProcessRecord app = apps.valueAt(ia);
2209                        if (app.thread != null) {
2210                            procs.add(app.thread.asBinder());
2211                        }
2212                    }
2213                }
2214            }
2215
2216            int N = procs.size();
2217            for (int i=0; i<N; i++) {
2218                Parcel data2 = Parcel.obtain();
2219                try {
2220                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2221                } catch (RemoteException e) {
2222                }
2223                data2.recycle();
2224            }
2225        }
2226        try {
2227            return super.onTransact(code, data, reply, flags);
2228        } catch (RuntimeException e) {
2229            // The activity manager only throws security exceptions, so let's
2230            // log all others.
2231            if (!(e instanceof SecurityException)) {
2232                Slog.wtf(TAG, "Activity Manager Crash", e);
2233            }
2234            throw e;
2235        }
2236    }
2237
2238    void updateCpuStats() {
2239        final long now = SystemClock.uptimeMillis();
2240        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2241            return;
2242        }
2243        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2244            synchronized (mProcessCpuThread) {
2245                mProcessCpuThread.notify();
2246            }
2247        }
2248    }
2249
2250    void updateCpuStatsNow() {
2251        synchronized (mProcessCpuThread) {
2252            mProcessCpuMutexFree.set(false);
2253            final long now = SystemClock.uptimeMillis();
2254            boolean haveNewCpuStats = false;
2255
2256            if (MONITOR_CPU_USAGE &&
2257                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2258                mLastCpuTime.set(now);
2259                haveNewCpuStats = true;
2260                mProcessCpuTracker.update();
2261                //Slog.i(TAG, mProcessCpu.printCurrentState());
2262                //Slog.i(TAG, "Total CPU usage: "
2263                //        + mProcessCpu.getTotalCpuPercent() + "%");
2264
2265                // Slog the cpu usage if the property is set.
2266                if ("true".equals(SystemProperties.get("events.cpu"))) {
2267                    int user = mProcessCpuTracker.getLastUserTime();
2268                    int system = mProcessCpuTracker.getLastSystemTime();
2269                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2270                    int irq = mProcessCpuTracker.getLastIrqTime();
2271                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2272                    int idle = mProcessCpuTracker.getLastIdleTime();
2273
2274                    int total = user + system + iowait + irq + softIrq + idle;
2275                    if (total == 0) total = 1;
2276
2277                    EventLog.writeEvent(EventLogTags.CPU,
2278                            ((user+system+iowait+irq+softIrq) * 100) / total,
2279                            (user * 100) / total,
2280                            (system * 100) / total,
2281                            (iowait * 100) / total,
2282                            (irq * 100) / total,
2283                            (softIrq * 100) / total);
2284                }
2285            }
2286
2287            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2288            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2289            synchronized(bstats) {
2290                synchronized(mPidsSelfLocked) {
2291                    if (haveNewCpuStats) {
2292                        if (mOnBattery) {
2293                            int perc = bstats.startAddingCpuLocked();
2294                            int totalUTime = 0;
2295                            int totalSTime = 0;
2296                            final int N = mProcessCpuTracker.countStats();
2297                            for (int i=0; i<N; i++) {
2298                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2299                                if (!st.working) {
2300                                    continue;
2301                                }
2302                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2303                                int otherUTime = (st.rel_utime*perc)/100;
2304                                int otherSTime = (st.rel_stime*perc)/100;
2305                                totalUTime += otherUTime;
2306                                totalSTime += otherSTime;
2307                                if (pr != null) {
2308                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2309                                    if (ps == null || !ps.isActive()) {
2310                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2311                                                pr.info.uid, pr.processName);
2312                                    }
2313                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2314                                            st.rel_stime-otherSTime);
2315                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2316                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2317                                } else {
2318                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2319                                    if (ps == null || !ps.isActive()) {
2320                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2321                                                bstats.mapUid(st.uid), st.name);
2322                                    }
2323                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2324                                            st.rel_stime-otherSTime);
2325                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2326                                }
2327                            }
2328                            bstats.finishAddingCpuLocked(perc, totalUTime,
2329                                    totalSTime, cpuSpeedTimes);
2330                        }
2331                    }
2332                }
2333
2334                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2335                    mLastWriteTime = now;
2336                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2337                }
2338            }
2339        }
2340    }
2341
2342    @Override
2343    public void batteryNeedsCpuUpdate() {
2344        updateCpuStatsNow();
2345    }
2346
2347    @Override
2348    public void batteryPowerChanged(boolean onBattery) {
2349        // When plugging in, update the CPU stats first before changing
2350        // the plug state.
2351        updateCpuStatsNow();
2352        synchronized (this) {
2353            synchronized(mPidsSelfLocked) {
2354                mOnBattery = DEBUG_POWER ? true : onBattery;
2355            }
2356        }
2357    }
2358
2359    /**
2360     * Initialize the application bind args. These are passed to each
2361     * process when the bindApplication() IPC is sent to the process. They're
2362     * lazily setup to make sure the services are running when they're asked for.
2363     */
2364    private HashMap<String, IBinder> getCommonServicesLocked() {
2365        if (mAppBindArgs == null) {
2366            mAppBindArgs = new HashMap<String, IBinder>();
2367
2368            // Setup the application init args
2369            mAppBindArgs.put("package", ServiceManager.getService("package"));
2370            mAppBindArgs.put("window", ServiceManager.getService("window"));
2371            mAppBindArgs.put(Context.ALARM_SERVICE,
2372                    ServiceManager.getService(Context.ALARM_SERVICE));
2373        }
2374        return mAppBindArgs;
2375    }
2376
2377    final void setFocusedActivityLocked(ActivityRecord r) {
2378        if (mFocusedActivity != r) {
2379            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2380            mFocusedActivity = r;
2381            if (r.task != null && r.task.voiceInteractor != null) {
2382                startRunningVoiceLocked();
2383            } else {
2384                finishRunningVoiceLocked();
2385            }
2386            mStackSupervisor.setFocusedStack(r);
2387            if (r != null) {
2388                mWindowManager.setFocusedApp(r.appToken, true);
2389            }
2390            applyUpdateLockStateLocked(r);
2391        }
2392    }
2393
2394    final void clearFocusedActivity(ActivityRecord r) {
2395        if (mFocusedActivity == r) {
2396            mFocusedActivity = null;
2397        }
2398    }
2399
2400    @Override
2401    public void setFocusedStack(int stackId) {
2402        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2403        synchronized (ActivityManagerService.this) {
2404            ActivityStack stack = mStackSupervisor.getStack(stackId);
2405            if (stack != null) {
2406                ActivityRecord r = stack.topRunningActivityLocked(null);
2407                if (r != null) {
2408                    setFocusedActivityLocked(r);
2409                }
2410            }
2411        }
2412    }
2413
2414    @Override
2415    public void notifyActivityDrawn(IBinder token) {
2416        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2417        synchronized (this) {
2418            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2419            if (r != null) {
2420                r.task.stack.notifyActivityDrawnLocked(r);
2421            }
2422        }
2423    }
2424
2425    final void applyUpdateLockStateLocked(ActivityRecord r) {
2426        // Modifications to the UpdateLock state are done on our handler, outside
2427        // the activity manager's locks.  The new state is determined based on the
2428        // state *now* of the relevant activity record.  The object is passed to
2429        // the handler solely for logging detail, not to be consulted/modified.
2430        final boolean nextState = r != null && r.immersive;
2431        mHandler.sendMessage(
2432                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2433    }
2434
2435    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2436        Message msg = Message.obtain();
2437        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2438        msg.obj = r.task.askedCompatMode ? null : r;
2439        mHandler.sendMessage(msg);
2440    }
2441
2442    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2443            String what, Object obj, ProcessRecord srcApp) {
2444        app.lastActivityTime = now;
2445
2446        if (app.activities.size() > 0) {
2447            // Don't want to touch dependent processes that are hosting activities.
2448            return index;
2449        }
2450
2451        int lrui = mLruProcesses.lastIndexOf(app);
2452        if (lrui < 0) {
2453            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2454                    + what + " " + obj + " from " + srcApp);
2455            return index;
2456        }
2457
2458        if (lrui >= index) {
2459            // Don't want to cause this to move dependent processes *back* in the
2460            // list as if they were less frequently used.
2461            return index;
2462        }
2463
2464        if (lrui >= mLruProcessActivityStart) {
2465            // Don't want to touch dependent processes that are hosting activities.
2466            return index;
2467        }
2468
2469        mLruProcesses.remove(lrui);
2470        if (index > 0) {
2471            index--;
2472        }
2473        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2474                + " in LRU list: " + app);
2475        mLruProcesses.add(index, app);
2476        return index;
2477    }
2478
2479    final void removeLruProcessLocked(ProcessRecord app) {
2480        int lrui = mLruProcesses.lastIndexOf(app);
2481        if (lrui >= 0) {
2482            if (lrui <= mLruProcessActivityStart) {
2483                mLruProcessActivityStart--;
2484            }
2485            if (lrui <= mLruProcessServiceStart) {
2486                mLruProcessServiceStart--;
2487            }
2488            mLruProcesses.remove(lrui);
2489        }
2490    }
2491
2492    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2493            ProcessRecord client) {
2494        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2495                || app.treatLikeActivity;
2496        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2497        if (!activityChange && hasActivity) {
2498            // The process has activities, so we are only allowing activity-based adjustments
2499            // to move it.  It should be kept in the front of the list with other
2500            // processes that have activities, and we don't want those to change their
2501            // order except due to activity operations.
2502            return;
2503        }
2504
2505        mLruSeq++;
2506        final long now = SystemClock.uptimeMillis();
2507        app.lastActivityTime = now;
2508
2509        // First a quick reject: if the app is already at the position we will
2510        // put it, then there is nothing to do.
2511        if (hasActivity) {
2512            final int N = mLruProcesses.size();
2513            if (N > 0 && mLruProcesses.get(N-1) == app) {
2514                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2515                return;
2516            }
2517        } else {
2518            if (mLruProcessServiceStart > 0
2519                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2520                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2521                return;
2522            }
2523        }
2524
2525        int lrui = mLruProcesses.lastIndexOf(app);
2526
2527        if (app.persistent && lrui >= 0) {
2528            // We don't care about the position of persistent processes, as long as
2529            // they are in the list.
2530            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2531            return;
2532        }
2533
2534        /* In progress: compute new position first, so we can avoid doing work
2535           if the process is not actually going to move.  Not yet working.
2536        int addIndex;
2537        int nextIndex;
2538        boolean inActivity = false, inService = false;
2539        if (hasActivity) {
2540            // Process has activities, put it at the very tipsy-top.
2541            addIndex = mLruProcesses.size();
2542            nextIndex = mLruProcessServiceStart;
2543            inActivity = true;
2544        } else if (hasService) {
2545            // Process has services, put it at the top of the service list.
2546            addIndex = mLruProcessActivityStart;
2547            nextIndex = mLruProcessServiceStart;
2548            inActivity = true;
2549            inService = true;
2550        } else  {
2551            // Process not otherwise of interest, it goes to the top of the non-service area.
2552            addIndex = mLruProcessServiceStart;
2553            if (client != null) {
2554                int clientIndex = mLruProcesses.lastIndexOf(client);
2555                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2556                        + app);
2557                if (clientIndex >= 0 && addIndex > clientIndex) {
2558                    addIndex = clientIndex;
2559                }
2560            }
2561            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2562        }
2563
2564        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2565                + mLruProcessActivityStart + "): " + app);
2566        */
2567
2568        if (lrui >= 0) {
2569            if (lrui < mLruProcessActivityStart) {
2570                mLruProcessActivityStart--;
2571            }
2572            if (lrui < mLruProcessServiceStart) {
2573                mLruProcessServiceStart--;
2574            }
2575            /*
2576            if (addIndex > lrui) {
2577                addIndex--;
2578            }
2579            if (nextIndex > lrui) {
2580                nextIndex--;
2581            }
2582            */
2583            mLruProcesses.remove(lrui);
2584        }
2585
2586        /*
2587        mLruProcesses.add(addIndex, app);
2588        if (inActivity) {
2589            mLruProcessActivityStart++;
2590        }
2591        if (inService) {
2592            mLruProcessActivityStart++;
2593        }
2594        */
2595
2596        int nextIndex;
2597        if (hasActivity) {
2598            final int N = mLruProcesses.size();
2599            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2600                // Process doesn't have activities, but has clients with
2601                // activities...  move it up, but one below the top (the top
2602                // should always have a real activity).
2603                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2604                mLruProcesses.add(N-1, app);
2605                // To keep it from spamming the LRU list (by making a bunch of clients),
2606                // we will push down any other entries owned by the app.
2607                final int uid = app.info.uid;
2608                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2609                    ProcessRecord subProc = mLruProcesses.get(i);
2610                    if (subProc.info.uid == uid) {
2611                        // We want to push this one down the list.  If the process after
2612                        // it is for the same uid, however, don't do so, because we don't
2613                        // want them internally to be re-ordered.
2614                        if (mLruProcesses.get(i-1).info.uid != uid) {
2615                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2616                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2617                            ProcessRecord tmp = mLruProcesses.get(i);
2618                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2619                            mLruProcesses.set(i-1, tmp);
2620                            i--;
2621                        }
2622                    } else {
2623                        // A gap, we can stop here.
2624                        break;
2625                    }
2626                }
2627            } else {
2628                // Process has activities, put it at the very tipsy-top.
2629                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2630                mLruProcesses.add(app);
2631            }
2632            nextIndex = mLruProcessServiceStart;
2633        } else if (hasService) {
2634            // Process has services, put it at the top of the service list.
2635            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2636            mLruProcesses.add(mLruProcessActivityStart, app);
2637            nextIndex = mLruProcessServiceStart;
2638            mLruProcessActivityStart++;
2639        } else  {
2640            // Process not otherwise of interest, it goes to the top of the non-service area.
2641            int index = mLruProcessServiceStart;
2642            if (client != null) {
2643                // If there is a client, don't allow the process to be moved up higher
2644                // in the list than that client.
2645                int clientIndex = mLruProcesses.lastIndexOf(client);
2646                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2647                        + " when updating " + app);
2648                if (clientIndex <= lrui) {
2649                    // Don't allow the client index restriction to push it down farther in the
2650                    // list than it already is.
2651                    clientIndex = lrui;
2652                }
2653                if (clientIndex >= 0 && index > clientIndex) {
2654                    index = clientIndex;
2655                }
2656            }
2657            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2658            mLruProcesses.add(index, app);
2659            nextIndex = index-1;
2660            mLruProcessActivityStart++;
2661            mLruProcessServiceStart++;
2662        }
2663
2664        // If the app is currently using a content provider or service,
2665        // bump those processes as well.
2666        for (int j=app.connections.size()-1; j>=0; j--) {
2667            ConnectionRecord cr = app.connections.valueAt(j);
2668            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2669                    && cr.binding.service.app != null
2670                    && cr.binding.service.app.lruSeq != mLruSeq
2671                    && !cr.binding.service.app.persistent) {
2672                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2673                        "service connection", cr, app);
2674            }
2675        }
2676        for (int j=app.conProviders.size()-1; j>=0; j--) {
2677            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2678            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2679                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2680                        "provider reference", cpr, app);
2681            }
2682        }
2683    }
2684
2685    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2686        if (uid == Process.SYSTEM_UID) {
2687            // The system gets to run in any process.  If there are multiple
2688            // processes with the same uid, just pick the first (this
2689            // should never happen).
2690            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2691            if (procs == null) return null;
2692            final int N = procs.size();
2693            for (int i = 0; i < N; i++) {
2694                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2695            }
2696        }
2697        ProcessRecord proc = mProcessNames.get(processName, uid);
2698        if (false && proc != null && !keepIfLarge
2699                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2700                && proc.lastCachedPss >= 4000) {
2701            // Turn this condition on to cause killing to happen regularly, for testing.
2702            if (proc.baseProcessTracker != null) {
2703                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2704            }
2705            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2706                    + "k from cached");
2707        } else if (proc != null && !keepIfLarge
2708                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2709                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2710            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2711            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2712                if (proc.baseProcessTracker != null) {
2713                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2714                }
2715                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2716                        + "k from cached");
2717            }
2718        }
2719        return proc;
2720    }
2721
2722    void ensurePackageDexOpt(String packageName) {
2723        IPackageManager pm = AppGlobals.getPackageManager();
2724        try {
2725            if (pm.performDexOpt(packageName)) {
2726                mDidDexOpt = true;
2727            }
2728        } catch (RemoteException e) {
2729        }
2730    }
2731
2732    boolean isNextTransitionForward() {
2733        int transit = mWindowManager.getPendingAppTransition();
2734        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2735                || transit == AppTransition.TRANSIT_TASK_OPEN
2736                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2737    }
2738
2739    final ProcessRecord startProcessLocked(String processName,
2740            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2741            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2742            boolean isolated, boolean keepIfLarge) {
2743        ProcessRecord app;
2744        if (!isolated) {
2745            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2746        } else {
2747            // If this is an isolated process, it can't re-use an existing process.
2748            app = null;
2749        }
2750        // We don't have to do anything more if:
2751        // (1) There is an existing application record; and
2752        // (2) The caller doesn't think it is dead, OR there is no thread
2753        //     object attached to it so we know it couldn't have crashed; and
2754        // (3) There is a pid assigned to it, so it is either starting or
2755        //     already running.
2756        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2757                + " app=" + app + " knownToBeDead=" + knownToBeDead
2758                + " thread=" + (app != null ? app.thread : null)
2759                + " pid=" + (app != null ? app.pid : -1));
2760        if (app != null && app.pid > 0) {
2761            if (!knownToBeDead || app.thread == null) {
2762                // We already have the app running, or are waiting for it to
2763                // come up (we have a pid but not yet its thread), so keep it.
2764                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2765                // If this is a new package in the process, add the package to the list
2766                app.addPackage(info.packageName, mProcessStats);
2767                return app;
2768            }
2769
2770            // An application record is attached to a previous process,
2771            // clean it up now.
2772            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2773            handleAppDiedLocked(app, true, true);
2774        }
2775
2776        String hostingNameStr = hostingName != null
2777                ? hostingName.flattenToShortString() : null;
2778
2779        if (!isolated) {
2780            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2781                // If we are in the background, then check to see if this process
2782                // is bad.  If so, we will just silently fail.
2783                if (mBadProcesses.get(info.processName, info.uid) != null) {
2784                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2785                            + "/" + info.processName);
2786                    return null;
2787                }
2788            } else {
2789                // When the user is explicitly starting a process, then clear its
2790                // crash count so that we won't make it bad until they see at
2791                // least one crash dialog again, and make the process good again
2792                // if it had been bad.
2793                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2794                        + "/" + info.processName);
2795                mProcessCrashTimes.remove(info.processName, info.uid);
2796                if (mBadProcesses.get(info.processName, info.uid) != null) {
2797                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2798                            UserHandle.getUserId(info.uid), info.uid,
2799                            info.processName);
2800                    mBadProcesses.remove(info.processName, info.uid);
2801                    if (app != null) {
2802                        app.bad = false;
2803                    }
2804                }
2805            }
2806        }
2807
2808        if (app == null) {
2809            app = newProcessRecordLocked(info, processName, isolated);
2810            if (app == null) {
2811                Slog.w(TAG, "Failed making new process record for "
2812                        + processName + "/" + info.uid + " isolated=" + isolated);
2813                return null;
2814            }
2815            mProcessNames.put(processName, app.uid, app);
2816            if (isolated) {
2817                mIsolatedProcesses.put(app.uid, app);
2818            }
2819        } else {
2820            // If this is a new package in the process, add the package to the list
2821            app.addPackage(info.packageName, mProcessStats);
2822        }
2823
2824        // If the system is not ready yet, then hold off on starting this
2825        // process until it is.
2826        if (!mProcessesReady
2827                && !isAllowedWhileBooting(info)
2828                && !allowWhileBooting) {
2829            if (!mProcessesOnHold.contains(app)) {
2830                mProcessesOnHold.add(app);
2831            }
2832            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2833            return app;
2834        }
2835
2836        startProcessLocked(app, hostingType, hostingNameStr);
2837        return (app.pid != 0) ? app : null;
2838    }
2839
2840    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2841        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2842    }
2843
2844    private final void startProcessLocked(ProcessRecord app,
2845            String hostingType, String hostingNameStr) {
2846        if (app.pid > 0 && app.pid != MY_PID) {
2847            synchronized (mPidsSelfLocked) {
2848                mPidsSelfLocked.remove(app.pid);
2849                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2850            }
2851            app.setPid(0);
2852        }
2853
2854        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2855                "startProcessLocked removing on hold: " + app);
2856        mProcessesOnHold.remove(app);
2857
2858        updateCpuStats();
2859
2860        try {
2861            int uid = app.uid;
2862
2863            int[] gids = null;
2864            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2865            if (!app.isolated) {
2866                int[] permGids = null;
2867                try {
2868                    final PackageManager pm = mContext.getPackageManager();
2869                    permGids = pm.getPackageGids(app.info.packageName);
2870
2871                    if (Environment.isExternalStorageEmulated()) {
2872                        if (pm.checkPermission(
2873                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2874                                app.info.packageName) == PERMISSION_GRANTED) {
2875                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2876                        } else {
2877                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2878                        }
2879                    }
2880                } catch (PackageManager.NameNotFoundException e) {
2881                    Slog.w(TAG, "Unable to retrieve gids", e);
2882                }
2883
2884                /*
2885                 * Add shared application GID so applications can share some
2886                 * resources like shared libraries
2887                 */
2888                if (permGids == null) {
2889                    gids = new int[1];
2890                } else {
2891                    gids = new int[permGids.length + 1];
2892                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2893                }
2894                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2895            }
2896            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2897                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2898                        && mTopComponent != null
2899                        && app.processName.equals(mTopComponent.getPackageName())) {
2900                    uid = 0;
2901                }
2902                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2903                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2904                    uid = 0;
2905                }
2906            }
2907            int debugFlags = 0;
2908            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2909                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2910                // Also turn on CheckJNI for debuggable apps. It's quite
2911                // awkward to turn on otherwise.
2912                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2913            }
2914            // Run the app in safe mode if its manifest requests so or the
2915            // system is booted in safe mode.
2916            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2917                mSafeMode == true) {
2918                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2919            }
2920            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2921                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2922            }
2923            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2924                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2925            }
2926            if ("1".equals(SystemProperties.get("debug.assert"))) {
2927                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2928            }
2929
2930            String requiredAbi = app.info.cpuAbi;
2931            if (requiredAbi == null) {
2932                requiredAbi = Build.SUPPORTED_ABIS[0];
2933            }
2934
2935            // Start the process.  It will either succeed and return a result containing
2936            // the PID of the new process, or else throw a RuntimeException.
2937            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2938                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2939                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2940
2941            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2942            synchronized (bs) {
2943                if (bs.isOnBattery()) {
2944                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2945                }
2946            }
2947
2948            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2949                    UserHandle.getUserId(uid), startResult.pid, uid,
2950                    app.processName, hostingType,
2951                    hostingNameStr != null ? hostingNameStr : "");
2952
2953            if (app.persistent) {
2954                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2955            }
2956
2957            StringBuilder buf = mStringBuilder;
2958            buf.setLength(0);
2959            buf.append("Start proc ");
2960            buf.append(app.processName);
2961            buf.append(" for ");
2962            buf.append(hostingType);
2963            if (hostingNameStr != null) {
2964                buf.append(" ");
2965                buf.append(hostingNameStr);
2966            }
2967            buf.append(": pid=");
2968            buf.append(startResult.pid);
2969            buf.append(" uid=");
2970            buf.append(uid);
2971            buf.append(" gids={");
2972            if (gids != null) {
2973                for (int gi=0; gi<gids.length; gi++) {
2974                    if (gi != 0) buf.append(", ");
2975                    buf.append(gids[gi]);
2976
2977                }
2978            }
2979            buf.append("}");
2980            Slog.i(TAG, buf.toString());
2981            app.setPid(startResult.pid);
2982            app.usingWrapper = startResult.usingWrapper;
2983            app.removed = false;
2984            synchronized (mPidsSelfLocked) {
2985                this.mPidsSelfLocked.put(startResult.pid, app);
2986                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2987                msg.obj = app;
2988                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2989                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2990            }
2991            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2992                    app.processName, app.info.uid);
2993            if (app.isolated) {
2994                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2995            }
2996        } catch (RuntimeException e) {
2997            // XXX do better error recovery.
2998            app.setPid(0);
2999            Slog.e(TAG, "Failure starting process " + app.processName, e);
3000        }
3001    }
3002
3003    void updateUsageStats(ActivityRecord component, boolean resumed) {
3004        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3005        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3006        if (resumed) {
3007            mUsageStatsService.noteResumeComponent(component.realActivity);
3008            synchronized (stats) {
3009                stats.noteActivityResumedLocked(component.app.uid);
3010            }
3011        } else {
3012            mUsageStatsService.notePauseComponent(component.realActivity);
3013            synchronized (stats) {
3014                stats.noteActivityPausedLocked(component.app.uid);
3015            }
3016        }
3017    }
3018
3019    Intent getHomeIntent() {
3020        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3021        intent.setComponent(mTopComponent);
3022        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3023            intent.addCategory(Intent.CATEGORY_HOME);
3024        }
3025        return intent;
3026    }
3027
3028    boolean startHomeActivityLocked(int userId) {
3029        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3030                && mTopAction == null) {
3031            // We are running in factory test mode, but unable to find
3032            // the factory test app, so just sit around displaying the
3033            // error message and don't try to start anything.
3034            return false;
3035        }
3036        Intent intent = getHomeIntent();
3037        ActivityInfo aInfo =
3038            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3039        if (aInfo != null) {
3040            intent.setComponent(new ComponentName(
3041                    aInfo.applicationInfo.packageName, aInfo.name));
3042            // Don't do this if the home app is currently being
3043            // instrumented.
3044            aInfo = new ActivityInfo(aInfo);
3045            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3046            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3047                    aInfo.applicationInfo.uid, true);
3048            if (app == null || app.instrumentationClass == null) {
3049                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3050                mStackSupervisor.startHomeActivity(intent, aInfo);
3051            }
3052        }
3053
3054        return true;
3055    }
3056
3057    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3058        ActivityInfo ai = null;
3059        ComponentName comp = intent.getComponent();
3060        try {
3061            if (comp != null) {
3062                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3063            } else {
3064                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3065                        intent,
3066                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3067                            flags, userId);
3068
3069                if (info != null) {
3070                    ai = info.activityInfo;
3071                }
3072            }
3073        } catch (RemoteException e) {
3074            // ignore
3075        }
3076
3077        return ai;
3078    }
3079
3080    /**
3081     * Starts the "new version setup screen" if appropriate.
3082     */
3083    void startSetupActivityLocked() {
3084        // Only do this once per boot.
3085        if (mCheckedForSetup) {
3086            return;
3087        }
3088
3089        // We will show this screen if the current one is a different
3090        // version than the last one shown, and we are not running in
3091        // low-level factory test mode.
3092        final ContentResolver resolver = mContext.getContentResolver();
3093        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3094                Settings.Global.getInt(resolver,
3095                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3096            mCheckedForSetup = true;
3097
3098            // See if we should be showing the platform update setup UI.
3099            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3100            List<ResolveInfo> ris = mContext.getPackageManager()
3101                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3102
3103            // We don't allow third party apps to replace this.
3104            ResolveInfo ri = null;
3105            for (int i=0; ris != null && i<ris.size(); i++) {
3106                if ((ris.get(i).activityInfo.applicationInfo.flags
3107                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3108                    ri = ris.get(i);
3109                    break;
3110                }
3111            }
3112
3113            if (ri != null) {
3114                String vers = ri.activityInfo.metaData != null
3115                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3116                        : null;
3117                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3118                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3119                            Intent.METADATA_SETUP_VERSION);
3120                }
3121                String lastVers = Settings.Secure.getString(
3122                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3123                if (vers != null && !vers.equals(lastVers)) {
3124                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3125                    intent.setComponent(new ComponentName(
3126                            ri.activityInfo.packageName, ri.activityInfo.name));
3127                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3128                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3129                }
3130            }
3131        }
3132    }
3133
3134    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3135        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3136    }
3137
3138    void enforceNotIsolatedCaller(String caller) {
3139        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3140            throw new SecurityException("Isolated process not allowed to call " + caller);
3141        }
3142    }
3143
3144    @Override
3145    public int getFrontActivityScreenCompatMode() {
3146        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3147        synchronized (this) {
3148            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3149        }
3150    }
3151
3152    @Override
3153    public void setFrontActivityScreenCompatMode(int mode) {
3154        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3155                "setFrontActivityScreenCompatMode");
3156        synchronized (this) {
3157            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3158        }
3159    }
3160
3161    @Override
3162    public int getPackageScreenCompatMode(String packageName) {
3163        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3164        synchronized (this) {
3165            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3166        }
3167    }
3168
3169    @Override
3170    public void setPackageScreenCompatMode(String packageName, int mode) {
3171        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3172                "setPackageScreenCompatMode");
3173        synchronized (this) {
3174            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3175        }
3176    }
3177
3178    @Override
3179    public boolean getPackageAskScreenCompat(String packageName) {
3180        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3181        synchronized (this) {
3182            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3183        }
3184    }
3185
3186    @Override
3187    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3188        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3189                "setPackageAskScreenCompat");
3190        synchronized (this) {
3191            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3192        }
3193    }
3194
3195    private void dispatchProcessesChanged() {
3196        int N;
3197        synchronized (this) {
3198            N = mPendingProcessChanges.size();
3199            if (mActiveProcessChanges.length < N) {
3200                mActiveProcessChanges = new ProcessChangeItem[N];
3201            }
3202            mPendingProcessChanges.toArray(mActiveProcessChanges);
3203            mAvailProcessChanges.addAll(mPendingProcessChanges);
3204            mPendingProcessChanges.clear();
3205            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3206        }
3207
3208        int i = mProcessObservers.beginBroadcast();
3209        while (i > 0) {
3210            i--;
3211            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3212            if (observer != null) {
3213                try {
3214                    for (int j=0; j<N; j++) {
3215                        ProcessChangeItem item = mActiveProcessChanges[j];
3216                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3217                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3218                                    + item.pid + " uid=" + item.uid + ": "
3219                                    + item.foregroundActivities);
3220                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3221                                    item.foregroundActivities);
3222                        }
3223                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3224                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3225                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3226                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3227                        }
3228                    }
3229                } catch (RemoteException e) {
3230                }
3231            }
3232        }
3233        mProcessObservers.finishBroadcast();
3234    }
3235
3236    private void dispatchProcessDied(int pid, int uid) {
3237        int i = mProcessObservers.beginBroadcast();
3238        while (i > 0) {
3239            i--;
3240            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3241            if (observer != null) {
3242                try {
3243                    observer.onProcessDied(pid, uid);
3244                } catch (RemoteException e) {
3245                }
3246            }
3247        }
3248        mProcessObservers.finishBroadcast();
3249    }
3250
3251    final void doPendingActivityLaunchesLocked(boolean doResume) {
3252        final int N = mPendingActivityLaunches.size();
3253        if (N <= 0) {
3254            return;
3255        }
3256        for (int i=0; i<N; i++) {
3257            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3258            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3259                    doResume && i == (N-1), null);
3260        }
3261        mPendingActivityLaunches.clear();
3262    }
3263
3264    @Override
3265    public final int startActivity(IApplicationThread caller, String callingPackage,
3266            Intent intent, String resolvedType, IBinder resultTo,
3267            String resultWho, int requestCode, int startFlags,
3268            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3269        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3270                resultWho, requestCode,
3271                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3272    }
3273
3274    @Override
3275    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3276            Intent intent, String resolvedType, IBinder resultTo,
3277            String resultWho, int requestCode, int startFlags,
3278            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3279        enforceNotIsolatedCaller("startActivity");
3280        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3281                false, true, "startActivity", null);
3282        // TODO: Switch to user app stacks here.
3283        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3284                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3285                null, null, options, userId, null);
3286    }
3287
3288    @Override
3289    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3290            Intent intent, String resolvedType, IBinder resultTo,
3291            String resultWho, int requestCode, int startFlags, String profileFile,
3292            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3293        enforceNotIsolatedCaller("startActivityAndWait");
3294        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3295                false, true, "startActivityAndWait", null);
3296        WaitResult res = new WaitResult();
3297        // TODO: Switch to user app stacks here.
3298        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3299                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3300                res, null, options, UserHandle.getCallingUserId(), null);
3301        return res;
3302    }
3303
3304    @Override
3305    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3306            Intent intent, String resolvedType, IBinder resultTo,
3307            String resultWho, int requestCode, int startFlags, Configuration config,
3308            Bundle options, int userId) {
3309        enforceNotIsolatedCaller("startActivityWithConfig");
3310        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3311                false, true, "startActivityWithConfig", null);
3312        // TODO: Switch to user app stacks here.
3313        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3314                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3315                null, null, null, config, options, userId, null);
3316        return ret;
3317    }
3318
3319    @Override
3320    public int startActivityIntentSender(IApplicationThread caller,
3321            IntentSender intent, Intent fillInIntent, String resolvedType,
3322            IBinder resultTo, String resultWho, int requestCode,
3323            int flagsMask, int flagsValues, Bundle options) {
3324        enforceNotIsolatedCaller("startActivityIntentSender");
3325        // Refuse possible leaked file descriptors
3326        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3327            throw new IllegalArgumentException("File descriptors passed in Intent");
3328        }
3329
3330        IIntentSender sender = intent.getTarget();
3331        if (!(sender instanceof PendingIntentRecord)) {
3332            throw new IllegalArgumentException("Bad PendingIntent object");
3333        }
3334
3335        PendingIntentRecord pir = (PendingIntentRecord)sender;
3336
3337        synchronized (this) {
3338            // If this is coming from the currently resumed activity, it is
3339            // effectively saying that app switches are allowed at this point.
3340            final ActivityStack stack = getFocusedStack();
3341            if (stack.mResumedActivity != null &&
3342                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3343                mAppSwitchesAllowedTime = 0;
3344            }
3345        }
3346        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3347                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3348        return ret;
3349    }
3350
3351    @Override
3352    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3353            Intent intent, String resolvedType, IVoiceInteractionSession session,
3354            IVoiceInteractor interactor, int startFlags, String profileFile,
3355            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3356        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3357                != PackageManager.PERMISSION_GRANTED) {
3358            String msg = "Permission Denial: startVoiceActivity() from pid="
3359                    + Binder.getCallingPid()
3360                    + ", uid=" + Binder.getCallingUid()
3361                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3362            Slog.w(TAG, msg);
3363            throw new SecurityException(msg);
3364        }
3365        if (session == null || interactor == null) {
3366            throw new NullPointerException("null session or interactor");
3367        }
3368        userId = handleIncomingUser(callingPid, callingUid, userId,
3369                false, true, "startVoiceActivity", null);
3370        // TODO: Switch to user app stacks here.
3371        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3372                resolvedType, session, interactor, null, null, 0, startFlags,
3373                profileFile, profileFd, null, null, options, userId, null);
3374    }
3375
3376    @Override
3377    public boolean startNextMatchingActivity(IBinder callingActivity,
3378            Intent intent, Bundle options) {
3379        // Refuse possible leaked file descriptors
3380        if (intent != null && intent.hasFileDescriptors() == true) {
3381            throw new IllegalArgumentException("File descriptors passed in Intent");
3382        }
3383
3384        synchronized (this) {
3385            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3386            if (r == null) {
3387                ActivityOptions.abort(options);
3388                return false;
3389            }
3390            if (r.app == null || r.app.thread == null) {
3391                // The caller is not running...  d'oh!
3392                ActivityOptions.abort(options);
3393                return false;
3394            }
3395            intent = new Intent(intent);
3396            // The caller is not allowed to change the data.
3397            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3398            // And we are resetting to find the next component...
3399            intent.setComponent(null);
3400
3401            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3402
3403            ActivityInfo aInfo = null;
3404            try {
3405                List<ResolveInfo> resolves =
3406                    AppGlobals.getPackageManager().queryIntentActivities(
3407                            intent, r.resolvedType,
3408                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3409                            UserHandle.getCallingUserId());
3410
3411                // Look for the original activity in the list...
3412                final int N = resolves != null ? resolves.size() : 0;
3413                for (int i=0; i<N; i++) {
3414                    ResolveInfo rInfo = resolves.get(i);
3415                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3416                            && rInfo.activityInfo.name.equals(r.info.name)) {
3417                        // We found the current one...  the next matching is
3418                        // after it.
3419                        i++;
3420                        if (i<N) {
3421                            aInfo = resolves.get(i).activityInfo;
3422                        }
3423                        if (debug) {
3424                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3425                                    + "/" + r.info.name);
3426                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3427                                    + "/" + aInfo.name);
3428                        }
3429                        break;
3430                    }
3431                }
3432            } catch (RemoteException e) {
3433            }
3434
3435            if (aInfo == null) {
3436                // Nobody who is next!
3437                ActivityOptions.abort(options);
3438                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3439                return false;
3440            }
3441
3442            intent.setComponent(new ComponentName(
3443                    aInfo.applicationInfo.packageName, aInfo.name));
3444            intent.setFlags(intent.getFlags()&~(
3445                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3446                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3447                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3448                    Intent.FLAG_ACTIVITY_NEW_TASK));
3449
3450            // Okay now we need to start the new activity, replacing the
3451            // currently running activity.  This is a little tricky because
3452            // we want to start the new one as if the current one is finished,
3453            // but not finish the current one first so that there is no flicker.
3454            // And thus...
3455            final boolean wasFinishing = r.finishing;
3456            r.finishing = true;
3457
3458            // Propagate reply information over to the new activity.
3459            final ActivityRecord resultTo = r.resultTo;
3460            final String resultWho = r.resultWho;
3461            final int requestCode = r.requestCode;
3462            r.resultTo = null;
3463            if (resultTo != null) {
3464                resultTo.removeResultsLocked(r, resultWho, requestCode);
3465            }
3466
3467            final long origId = Binder.clearCallingIdentity();
3468            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3469                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3470                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3471                    options, false, null, null);
3472            Binder.restoreCallingIdentity(origId);
3473
3474            r.finishing = wasFinishing;
3475            if (res != ActivityManager.START_SUCCESS) {
3476                return false;
3477            }
3478            return true;
3479        }
3480    }
3481
3482    final int startActivityInPackage(int uid, String callingPackage,
3483            Intent intent, String resolvedType, IBinder resultTo,
3484            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3485                    IActivityContainer container) {
3486
3487        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3488                false, true, "startActivityInPackage", null);
3489
3490        // TODO: Switch to user app stacks here.
3491        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3492                null, null, resultTo, resultWho, requestCode, startFlags,
3493                null, null, null, null, options, userId, container);
3494        return ret;
3495    }
3496
3497    @Override
3498    public final int startActivities(IApplicationThread caller, String callingPackage,
3499            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3500            int userId) {
3501        enforceNotIsolatedCaller("startActivities");
3502        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3503                false, true, "startActivity", null);
3504        // TODO: Switch to user app stacks here.
3505        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3506                resolvedTypes, resultTo, options, userId);
3507        return ret;
3508    }
3509
3510    final int startActivitiesInPackage(int uid, String callingPackage,
3511            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3512            Bundle options, int userId) {
3513
3514        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3515                false, true, "startActivityInPackage", null);
3516        // TODO: Switch to user app stacks here.
3517        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3518                resultTo, options, userId);
3519        return ret;
3520    }
3521
3522    final void addRecentTaskLocked(TaskRecord task) {
3523        int N = mRecentTasks.size();
3524        // Quick case: check if the top-most recent task is the same.
3525        if (N > 0 && mRecentTasks.get(0) == task) {
3526            return;
3527        }
3528        // Another quick case: never add voice sessions.
3529        if (task.voiceSession != null) {
3530            return;
3531        }
3532        // Remove any existing entries that are the same kind of task.
3533        final Intent intent = task.intent;
3534        final boolean document = intent != null && intent.isDocument();
3535        for (int i=0; i<N; i++) {
3536            TaskRecord tr = mRecentTasks.get(i);
3537            if (task != tr) {
3538                if (task.userId != tr.userId) {
3539                    continue;
3540                }
3541                final Intent trIntent = tr.intent;
3542                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3543                    (intent == null || !intent.filterEquals(trIntent))) {
3544                    continue;
3545                }
3546                if (document || trIntent != null && trIntent.isDocument()) {
3547                    // Document tasks do not match other tasks.
3548                    continue;
3549                }
3550            }
3551
3552            // Either task and tr are the same or, their affinities match or their intents match
3553            // and neither of them is a document.
3554            tr.disposeThumbnail();
3555            mRecentTasks.remove(i);
3556            i--;
3557            N--;
3558            if (task.intent == null) {
3559                // If the new recent task we are adding is not fully
3560                // specified, then replace it with the existing recent task.
3561                task = tr;
3562            }
3563        }
3564        if (N >= MAX_RECENT_TASKS) {
3565            mRecentTasks.remove(N-1).disposeThumbnail();
3566        }
3567        mRecentTasks.add(0, task);
3568    }
3569
3570    @Override
3571    public void reportActivityFullyDrawn(IBinder token) {
3572        synchronized (this) {
3573            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3574            if (r == null) {
3575                return;
3576            }
3577            r.reportFullyDrawnLocked();
3578        }
3579    }
3580
3581    @Override
3582    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3583        synchronized (this) {
3584            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3585            if (r == null) {
3586                return;
3587            }
3588            final long origId = Binder.clearCallingIdentity();
3589            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3590            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3591                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3592            if (config != null) {
3593                r.frozenBeforeDestroy = true;
3594                if (!updateConfigurationLocked(config, r, false, false)) {
3595                    mStackSupervisor.resumeTopActivitiesLocked();
3596                }
3597            }
3598            Binder.restoreCallingIdentity(origId);
3599        }
3600    }
3601
3602    @Override
3603    public int getRequestedOrientation(IBinder token) {
3604        synchronized (this) {
3605            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3606            if (r == null) {
3607                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3608            }
3609            return mWindowManager.getAppOrientation(r.appToken);
3610        }
3611    }
3612
3613    /**
3614     * This is the internal entry point for handling Activity.finish().
3615     *
3616     * @param token The Binder token referencing the Activity we want to finish.
3617     * @param resultCode Result code, if any, from this Activity.
3618     * @param resultData Result data (Intent), if any, from this Activity.
3619     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3620     *            the root Activity in the task.
3621     *
3622     * @return Returns true if the activity successfully finished, or false if it is still running.
3623     */
3624    @Override
3625    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3626            boolean finishTask) {
3627        // Refuse possible leaked file descriptors
3628        if (resultData != null && resultData.hasFileDescriptors() == true) {
3629            throw new IllegalArgumentException("File descriptors passed in Intent");
3630        }
3631
3632        synchronized(this) {
3633            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3634            if (r == null) {
3635                return true;
3636            }
3637            // Keep track of the root activity of the task before we finish it
3638            TaskRecord tr = r.task;
3639            ActivityRecord rootR = tr.getRootActivity();
3640            if (mController != null) {
3641                // Find the first activity that is not finishing.
3642                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3643                if (next != null) {
3644                    // ask watcher if this is allowed
3645                    boolean resumeOK = true;
3646                    try {
3647                        resumeOK = mController.activityResuming(next.packageName);
3648                    } catch (RemoteException e) {
3649                        mController = null;
3650                        Watchdog.getInstance().setActivityController(null);
3651                    }
3652
3653                    if (!resumeOK) {
3654                        return false;
3655                    }
3656                }
3657            }
3658            final long origId = Binder.clearCallingIdentity();
3659            try {
3660                boolean res;
3661                if (finishTask && r == rootR) {
3662                    // If requested, remove the task that is associated to this activity only if it
3663                    // was the root activity in the task.  The result code and data is ignored because
3664                    // we don't support returning them across task boundaries.
3665                    res = removeTaskByIdLocked(tr.taskId, 0);
3666                } else {
3667                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3668                            resultData, "app-request", true);
3669                }
3670                return res;
3671            } finally {
3672                Binder.restoreCallingIdentity(origId);
3673            }
3674        }
3675    }
3676
3677    @Override
3678    public final void finishHeavyWeightApp() {
3679        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3680                != PackageManager.PERMISSION_GRANTED) {
3681            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3682                    + Binder.getCallingPid()
3683                    + ", uid=" + Binder.getCallingUid()
3684                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3685            Slog.w(TAG, msg);
3686            throw new SecurityException(msg);
3687        }
3688
3689        synchronized(this) {
3690            if (mHeavyWeightProcess == null) {
3691                return;
3692            }
3693
3694            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3695                    mHeavyWeightProcess.activities);
3696            for (int i=0; i<activities.size(); i++) {
3697                ActivityRecord r = activities.get(i);
3698                if (!r.finishing) {
3699                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3700                            null, "finish-heavy", true);
3701                }
3702            }
3703
3704            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3705                    mHeavyWeightProcess.userId, 0));
3706            mHeavyWeightProcess = null;
3707        }
3708    }
3709
3710    @Override
3711    public void crashApplication(int uid, int initialPid, String packageName,
3712            String message) {
3713        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3714                != PackageManager.PERMISSION_GRANTED) {
3715            String msg = "Permission Denial: crashApplication() from pid="
3716                    + Binder.getCallingPid()
3717                    + ", uid=" + Binder.getCallingUid()
3718                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3719            Slog.w(TAG, msg);
3720            throw new SecurityException(msg);
3721        }
3722
3723        synchronized(this) {
3724            ProcessRecord proc = null;
3725
3726            // Figure out which process to kill.  We don't trust that initialPid
3727            // still has any relation to current pids, so must scan through the
3728            // list.
3729            synchronized (mPidsSelfLocked) {
3730                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3731                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3732                    if (p.uid != uid) {
3733                        continue;
3734                    }
3735                    if (p.pid == initialPid) {
3736                        proc = p;
3737                        break;
3738                    }
3739                    if (p.pkgList.containsKey(packageName)) {
3740                        proc = p;
3741                    }
3742                }
3743            }
3744
3745            if (proc == null) {
3746                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3747                        + " initialPid=" + initialPid
3748                        + " packageName=" + packageName);
3749                return;
3750            }
3751
3752            if (proc.thread != null) {
3753                if (proc.pid == Process.myPid()) {
3754                    Log.w(TAG, "crashApplication: trying to crash self!");
3755                    return;
3756                }
3757                long ident = Binder.clearCallingIdentity();
3758                try {
3759                    proc.thread.scheduleCrash(message);
3760                } catch (RemoteException e) {
3761                }
3762                Binder.restoreCallingIdentity(ident);
3763            }
3764        }
3765    }
3766
3767    @Override
3768    public final void finishSubActivity(IBinder token, String resultWho,
3769            int requestCode) {
3770        synchronized(this) {
3771            final long origId = Binder.clearCallingIdentity();
3772            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3773            if (r != null) {
3774                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3775            }
3776            Binder.restoreCallingIdentity(origId);
3777        }
3778    }
3779
3780    @Override
3781    public boolean finishActivityAffinity(IBinder token) {
3782        synchronized(this) {
3783            final long origId = Binder.clearCallingIdentity();
3784            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3785            boolean res = false;
3786            if (r != null) {
3787                res = r.task.stack.finishActivityAffinityLocked(r);
3788            }
3789            Binder.restoreCallingIdentity(origId);
3790            return res;
3791        }
3792    }
3793
3794    @Override
3795    public boolean willActivityBeVisible(IBinder token) {
3796        synchronized(this) {
3797            ActivityStack stack = ActivityRecord.getStackLocked(token);
3798            if (stack != null) {
3799                return stack.willActivityBeVisibleLocked(token);
3800            }
3801            return false;
3802        }
3803    }
3804
3805    @Override
3806    public void overridePendingTransition(IBinder token, String packageName,
3807            int enterAnim, int exitAnim) {
3808        synchronized(this) {
3809            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3810            if (self == null) {
3811                return;
3812            }
3813
3814            final long origId = Binder.clearCallingIdentity();
3815
3816            if (self.state == ActivityState.RESUMED
3817                    || self.state == ActivityState.PAUSING) {
3818                mWindowManager.overridePendingAppTransition(packageName,
3819                        enterAnim, exitAnim, null);
3820            }
3821
3822            Binder.restoreCallingIdentity(origId);
3823        }
3824    }
3825
3826    /**
3827     * Main function for removing an existing process from the activity manager
3828     * as a result of that process going away.  Clears out all connections
3829     * to the process.
3830     */
3831    private final void handleAppDiedLocked(ProcessRecord app,
3832            boolean restarting, boolean allowRestart) {
3833        int pid = app.pid;
3834        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3835        if (!restarting) {
3836            removeLruProcessLocked(app);
3837            if (pid > 0) {
3838                ProcessList.remove(pid);
3839            }
3840        }
3841
3842        if (mProfileProc == app) {
3843            clearProfilerLocked();
3844        }
3845
3846        // Remove this application's activities from active lists.
3847        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3848
3849        app.activities.clear();
3850
3851        if (app.instrumentationClass != null) {
3852            Slog.w(TAG, "Crash of app " + app.processName
3853                  + " running instrumentation " + app.instrumentationClass);
3854            Bundle info = new Bundle();
3855            info.putString("shortMsg", "Process crashed.");
3856            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3857        }
3858
3859        if (!restarting) {
3860            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3861                // If there was nothing to resume, and we are not already
3862                // restarting this process, but there is a visible activity that
3863                // is hosted by the process...  then make sure all visible
3864                // activities are running, taking care of restarting this
3865                // process.
3866                if (hasVisibleActivities) {
3867                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3868                }
3869            }
3870        }
3871    }
3872
3873    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3874        IBinder threadBinder = thread.asBinder();
3875        // Find the application record.
3876        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3877            ProcessRecord rec = mLruProcesses.get(i);
3878            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3879                return i;
3880            }
3881        }
3882        return -1;
3883    }
3884
3885    final ProcessRecord getRecordForAppLocked(
3886            IApplicationThread thread) {
3887        if (thread == null) {
3888            return null;
3889        }
3890
3891        int appIndex = getLRURecordIndexForAppLocked(thread);
3892        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3893    }
3894
3895    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3896        // If there are no longer any background processes running,
3897        // and the app that died was not running instrumentation,
3898        // then tell everyone we are now low on memory.
3899        boolean haveBg = false;
3900        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3901            ProcessRecord rec = mLruProcesses.get(i);
3902            if (rec.thread != null
3903                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3904                haveBg = true;
3905                break;
3906            }
3907        }
3908
3909        if (!haveBg) {
3910            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3911            if (doReport) {
3912                long now = SystemClock.uptimeMillis();
3913                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3914                    doReport = false;
3915                } else {
3916                    mLastMemUsageReportTime = now;
3917                }
3918            }
3919            final ArrayList<ProcessMemInfo> memInfos
3920                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3921            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3922            long now = SystemClock.uptimeMillis();
3923            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3924                ProcessRecord rec = mLruProcesses.get(i);
3925                if (rec == dyingProc || rec.thread == null) {
3926                    continue;
3927                }
3928                if (doReport) {
3929                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3930                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3931                }
3932                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3933                    // The low memory report is overriding any current
3934                    // state for a GC request.  Make sure to do
3935                    // heavy/important/visible/foreground processes first.
3936                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3937                        rec.lastRequestedGc = 0;
3938                    } else {
3939                        rec.lastRequestedGc = rec.lastLowMemory;
3940                    }
3941                    rec.reportLowMemory = true;
3942                    rec.lastLowMemory = now;
3943                    mProcessesToGc.remove(rec);
3944                    addProcessToGcListLocked(rec);
3945                }
3946            }
3947            if (doReport) {
3948                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3949                mHandler.sendMessage(msg);
3950            }
3951            scheduleAppGcsLocked();
3952        }
3953    }
3954
3955    final void appDiedLocked(ProcessRecord app, int pid,
3956            IApplicationThread thread) {
3957
3958        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3959        synchronized (stats) {
3960            stats.noteProcessDiedLocked(app.info.uid, pid);
3961        }
3962
3963        // Clean up already done if the process has been re-started.
3964        if (app.pid == pid && app.thread != null &&
3965                app.thread.asBinder() == thread.asBinder()) {
3966            boolean doLowMem = app.instrumentationClass == null;
3967            boolean doOomAdj = doLowMem;
3968            if (!app.killedByAm) {
3969                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3970                        + ") has died.");
3971                mAllowLowerMemLevel = true;
3972            } else {
3973                // Note that we always want to do oom adj to update our state with the
3974                // new number of procs.
3975                mAllowLowerMemLevel = false;
3976                doLowMem = false;
3977            }
3978            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3979            if (DEBUG_CLEANUP) Slog.v(
3980                TAG, "Dying app: " + app + ", pid: " + pid
3981                + ", thread: " + thread.asBinder());
3982            handleAppDiedLocked(app, false, true);
3983
3984            if (doOomAdj) {
3985                updateOomAdjLocked();
3986            }
3987            if (doLowMem) {
3988                doLowMemReportIfNeededLocked(app);
3989            }
3990        } else if (app.pid != pid) {
3991            // A new process has already been started.
3992            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3993                    + ") has died and restarted (pid " + app.pid + ").");
3994            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3995        } else if (DEBUG_PROCESSES) {
3996            Slog.d(TAG, "Received spurious death notification for thread "
3997                    + thread.asBinder());
3998        }
3999    }
4000
4001    /**
4002     * If a stack trace dump file is configured, dump process stack traces.
4003     * @param clearTraces causes the dump file to be erased prior to the new
4004     *    traces being written, if true; when false, the new traces will be
4005     *    appended to any existing file content.
4006     * @param firstPids of dalvik VM processes to dump stack traces for first
4007     * @param lastPids of dalvik VM processes to dump stack traces for last
4008     * @param nativeProcs optional list of native process names to dump stack crawls
4009     * @return file containing stack traces, or null if no dump file is configured
4010     */
4011    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4012            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4013        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4014        if (tracesPath == null || tracesPath.length() == 0) {
4015            return null;
4016        }
4017
4018        File tracesFile = new File(tracesPath);
4019        try {
4020            File tracesDir = tracesFile.getParentFile();
4021            if (!tracesDir.exists()) {
4022                tracesFile.mkdirs();
4023                if (!SELinux.restorecon(tracesDir)) {
4024                    return null;
4025                }
4026            }
4027            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4028
4029            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4030            tracesFile.createNewFile();
4031            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4032        } catch (IOException e) {
4033            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4034            return null;
4035        }
4036
4037        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4038        return tracesFile;
4039    }
4040
4041    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4042            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4043        // Use a FileObserver to detect when traces finish writing.
4044        // The order of traces is considered important to maintain for legibility.
4045        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4046            @Override
4047            public synchronized void onEvent(int event, String path) { notify(); }
4048        };
4049
4050        try {
4051            observer.startWatching();
4052
4053            // First collect all of the stacks of the most important pids.
4054            if (firstPids != null) {
4055                try {
4056                    int num = firstPids.size();
4057                    for (int i = 0; i < num; i++) {
4058                        synchronized (observer) {
4059                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4060                            observer.wait(200);  // Wait for write-close, give up after 200msec
4061                        }
4062                    }
4063                } catch (InterruptedException e) {
4064                    Log.wtf(TAG, e);
4065                }
4066            }
4067
4068            // Next collect the stacks of the native pids
4069            if (nativeProcs != null) {
4070                int[] pids = Process.getPidsForCommands(nativeProcs);
4071                if (pids != null) {
4072                    for (int pid : pids) {
4073                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4074                    }
4075                }
4076            }
4077
4078            // Lastly, measure CPU usage.
4079            if (processCpuTracker != null) {
4080                processCpuTracker.init();
4081                System.gc();
4082                processCpuTracker.update();
4083                try {
4084                    synchronized (processCpuTracker) {
4085                        processCpuTracker.wait(500); // measure over 1/2 second.
4086                    }
4087                } catch (InterruptedException e) {
4088                }
4089                processCpuTracker.update();
4090
4091                // We'll take the stack crawls of just the top apps using CPU.
4092                final int N = processCpuTracker.countWorkingStats();
4093                int numProcs = 0;
4094                for (int i=0; i<N && numProcs<5; i++) {
4095                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4096                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4097                        numProcs++;
4098                        try {
4099                            synchronized (observer) {
4100                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4101                                observer.wait(200);  // Wait for write-close, give up after 200msec
4102                            }
4103                        } catch (InterruptedException e) {
4104                            Log.wtf(TAG, e);
4105                        }
4106
4107                    }
4108                }
4109            }
4110        } finally {
4111            observer.stopWatching();
4112        }
4113    }
4114
4115    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4116        if (true || IS_USER_BUILD) {
4117            return;
4118        }
4119        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4120        if (tracesPath == null || tracesPath.length() == 0) {
4121            return;
4122        }
4123
4124        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4125        StrictMode.allowThreadDiskWrites();
4126        try {
4127            final File tracesFile = new File(tracesPath);
4128            final File tracesDir = tracesFile.getParentFile();
4129            final File tracesTmp = new File(tracesDir, "__tmp__");
4130            try {
4131                if (!tracesDir.exists()) {
4132                    tracesFile.mkdirs();
4133                    if (!SELinux.restorecon(tracesDir.getPath())) {
4134                        return;
4135                    }
4136                }
4137                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4138
4139                if (tracesFile.exists()) {
4140                    tracesTmp.delete();
4141                    tracesFile.renameTo(tracesTmp);
4142                }
4143                StringBuilder sb = new StringBuilder();
4144                Time tobj = new Time();
4145                tobj.set(System.currentTimeMillis());
4146                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4147                sb.append(": ");
4148                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4149                sb.append(" since ");
4150                sb.append(msg);
4151                FileOutputStream fos = new FileOutputStream(tracesFile);
4152                fos.write(sb.toString().getBytes());
4153                if (app == null) {
4154                    fos.write("\n*** No application process!".getBytes());
4155                }
4156                fos.close();
4157                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4158            } catch (IOException e) {
4159                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4160                return;
4161            }
4162
4163            if (app != null) {
4164                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4165                firstPids.add(app.pid);
4166                dumpStackTraces(tracesPath, firstPids, null, null, null);
4167            }
4168
4169            File lastTracesFile = null;
4170            File curTracesFile = null;
4171            for (int i=9; i>=0; i--) {
4172                String name = String.format(Locale.US, "slow%02d.txt", i);
4173                curTracesFile = new File(tracesDir, name);
4174                if (curTracesFile.exists()) {
4175                    if (lastTracesFile != null) {
4176                        curTracesFile.renameTo(lastTracesFile);
4177                    } else {
4178                        curTracesFile.delete();
4179                    }
4180                }
4181                lastTracesFile = curTracesFile;
4182            }
4183            tracesFile.renameTo(curTracesFile);
4184            if (tracesTmp.exists()) {
4185                tracesTmp.renameTo(tracesFile);
4186            }
4187        } finally {
4188            StrictMode.setThreadPolicy(oldPolicy);
4189        }
4190    }
4191
4192    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4193            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4194        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4195        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4196
4197        if (mController != null) {
4198            try {
4199                // 0 == continue, -1 = kill process immediately
4200                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4201                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4202            } catch (RemoteException e) {
4203                mController = null;
4204                Watchdog.getInstance().setActivityController(null);
4205            }
4206        }
4207
4208        long anrTime = SystemClock.uptimeMillis();
4209        if (MONITOR_CPU_USAGE) {
4210            updateCpuStatsNow();
4211        }
4212
4213        synchronized (this) {
4214            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4215            if (mShuttingDown) {
4216                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4217                return;
4218            } else if (app.notResponding) {
4219                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4220                return;
4221            } else if (app.crashing) {
4222                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4223                return;
4224            }
4225
4226            // In case we come through here for the same app before completing
4227            // this one, mark as anring now so we will bail out.
4228            app.notResponding = true;
4229
4230            // Log the ANR to the event log.
4231            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4232                    app.processName, app.info.flags, annotation);
4233
4234            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4235            firstPids.add(app.pid);
4236
4237            int parentPid = app.pid;
4238            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4239            if (parentPid != app.pid) firstPids.add(parentPid);
4240
4241            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4242
4243            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4244                ProcessRecord r = mLruProcesses.get(i);
4245                if (r != null && r.thread != null) {
4246                    int pid = r.pid;
4247                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4248                        if (r.persistent) {
4249                            firstPids.add(pid);
4250                        } else {
4251                            lastPids.put(pid, Boolean.TRUE);
4252                        }
4253                    }
4254                }
4255            }
4256        }
4257
4258        // Log the ANR to the main log.
4259        StringBuilder info = new StringBuilder();
4260        info.setLength(0);
4261        info.append("ANR in ").append(app.processName);
4262        if (activity != null && activity.shortComponentName != null) {
4263            info.append(" (").append(activity.shortComponentName).append(")");
4264        }
4265        info.append("\n");
4266        info.append("PID: ").append(app.pid).append("\n");
4267        if (annotation != null) {
4268            info.append("Reason: ").append(annotation).append("\n");
4269        }
4270        if (parent != null && parent != activity) {
4271            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4272        }
4273
4274        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4275
4276        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4277                NATIVE_STACKS_OF_INTEREST);
4278
4279        String cpuInfo = null;
4280        if (MONITOR_CPU_USAGE) {
4281            updateCpuStatsNow();
4282            synchronized (mProcessCpuThread) {
4283                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4284            }
4285            info.append(processCpuTracker.printCurrentLoad());
4286            info.append(cpuInfo);
4287        }
4288
4289        info.append(processCpuTracker.printCurrentState(anrTime));
4290
4291        Slog.e(TAG, info.toString());
4292        if (tracesFile == null) {
4293            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4294            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4295        }
4296
4297        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4298                cpuInfo, tracesFile, null);
4299
4300        if (mController != null) {
4301            try {
4302                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4303                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4304                if (res != 0) {
4305                    if (res < 0 && app.pid != MY_PID) {
4306                        Process.killProcess(app.pid);
4307                    } else {
4308                        synchronized (this) {
4309                            mServices.scheduleServiceTimeoutLocked(app);
4310                        }
4311                    }
4312                    return;
4313                }
4314            } catch (RemoteException e) {
4315                mController = null;
4316                Watchdog.getInstance().setActivityController(null);
4317            }
4318        }
4319
4320        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4321        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4322                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4323
4324        synchronized (this) {
4325            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4326                killUnneededProcessLocked(app, "background ANR");
4327                return;
4328            }
4329
4330            // Set the app's notResponding state, and look up the errorReportReceiver
4331            makeAppNotRespondingLocked(app,
4332                    activity != null ? activity.shortComponentName : null,
4333                    annotation != null ? "ANR " + annotation : "ANR",
4334                    info.toString());
4335
4336            // Bring up the infamous App Not Responding dialog
4337            Message msg = Message.obtain();
4338            HashMap<String, Object> map = new HashMap<String, Object>();
4339            msg.what = SHOW_NOT_RESPONDING_MSG;
4340            msg.obj = map;
4341            msg.arg1 = aboveSystem ? 1 : 0;
4342            map.put("app", app);
4343            if (activity != null) {
4344                map.put("activity", activity);
4345            }
4346
4347            mHandler.sendMessage(msg);
4348        }
4349    }
4350
4351    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4352        if (!mLaunchWarningShown) {
4353            mLaunchWarningShown = true;
4354            mHandler.post(new Runnable() {
4355                @Override
4356                public void run() {
4357                    synchronized (ActivityManagerService.this) {
4358                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4359                        d.show();
4360                        mHandler.postDelayed(new Runnable() {
4361                            @Override
4362                            public void run() {
4363                                synchronized (ActivityManagerService.this) {
4364                                    d.dismiss();
4365                                    mLaunchWarningShown = false;
4366                                }
4367                            }
4368                        }, 4000);
4369                    }
4370                }
4371            });
4372        }
4373    }
4374
4375    @Override
4376    public boolean clearApplicationUserData(final String packageName,
4377            final IPackageDataObserver observer, int userId) {
4378        enforceNotIsolatedCaller("clearApplicationUserData");
4379        int uid = Binder.getCallingUid();
4380        int pid = Binder.getCallingPid();
4381        userId = handleIncomingUser(pid, uid,
4382                userId, false, true, "clearApplicationUserData", null);
4383        long callingId = Binder.clearCallingIdentity();
4384        try {
4385            IPackageManager pm = AppGlobals.getPackageManager();
4386            int pkgUid = -1;
4387            synchronized(this) {
4388                try {
4389                    pkgUid = pm.getPackageUid(packageName, userId);
4390                } catch (RemoteException e) {
4391                }
4392                if (pkgUid == -1) {
4393                    Slog.w(TAG, "Invalid packageName: " + packageName);
4394                    if (observer != null) {
4395                        try {
4396                            observer.onRemoveCompleted(packageName, false);
4397                        } catch (RemoteException e) {
4398                            Slog.i(TAG, "Observer no longer exists.");
4399                        }
4400                    }
4401                    return false;
4402                }
4403                if (uid == pkgUid || checkComponentPermission(
4404                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4405                        pid, uid, -1, true)
4406                        == PackageManager.PERMISSION_GRANTED) {
4407                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4408                } else {
4409                    throw new SecurityException("PID " + pid + " does not have permission "
4410                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4411                                    + " of package " + packageName);
4412                }
4413            }
4414
4415            try {
4416                // Clear application user data
4417                pm.clearApplicationUserData(packageName, observer, userId);
4418
4419                // Remove all permissions granted from/to this package
4420                removeUriPermissionsForPackageLocked(packageName, userId, true);
4421
4422                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4423                        Uri.fromParts("package", packageName, null));
4424                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4425                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4426                        null, null, 0, null, null, null, false, false, userId);
4427            } catch (RemoteException e) {
4428            }
4429        } finally {
4430            Binder.restoreCallingIdentity(callingId);
4431        }
4432        return true;
4433    }
4434
4435    @Override
4436    public void killBackgroundProcesses(final String packageName, int userId) {
4437        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4438                != PackageManager.PERMISSION_GRANTED &&
4439                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4440                        != PackageManager.PERMISSION_GRANTED) {
4441            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4442                    + Binder.getCallingPid()
4443                    + ", uid=" + Binder.getCallingUid()
4444                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4445            Slog.w(TAG, msg);
4446            throw new SecurityException(msg);
4447        }
4448
4449        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4450                userId, true, true, "killBackgroundProcesses", null);
4451        long callingId = Binder.clearCallingIdentity();
4452        try {
4453            IPackageManager pm = AppGlobals.getPackageManager();
4454            synchronized(this) {
4455                int appId = -1;
4456                try {
4457                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4458                } catch (RemoteException e) {
4459                }
4460                if (appId == -1) {
4461                    Slog.w(TAG, "Invalid packageName: " + packageName);
4462                    return;
4463                }
4464                killPackageProcessesLocked(packageName, appId, userId,
4465                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4466            }
4467        } finally {
4468            Binder.restoreCallingIdentity(callingId);
4469        }
4470    }
4471
4472    @Override
4473    public void killAllBackgroundProcesses() {
4474        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4475                != PackageManager.PERMISSION_GRANTED) {
4476            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4477                    + Binder.getCallingPid()
4478                    + ", uid=" + Binder.getCallingUid()
4479                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4480            Slog.w(TAG, msg);
4481            throw new SecurityException(msg);
4482        }
4483
4484        long callingId = Binder.clearCallingIdentity();
4485        try {
4486            synchronized(this) {
4487                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4488                final int NP = mProcessNames.getMap().size();
4489                for (int ip=0; ip<NP; ip++) {
4490                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4491                    final int NA = apps.size();
4492                    for (int ia=0; ia<NA; ia++) {
4493                        ProcessRecord app = apps.valueAt(ia);
4494                        if (app.persistent) {
4495                            // we don't kill persistent processes
4496                            continue;
4497                        }
4498                        if (app.removed) {
4499                            procs.add(app);
4500                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4501                            app.removed = true;
4502                            procs.add(app);
4503                        }
4504                    }
4505                }
4506
4507                int N = procs.size();
4508                for (int i=0; i<N; i++) {
4509                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4510                }
4511                mAllowLowerMemLevel = true;
4512                updateOomAdjLocked();
4513                doLowMemReportIfNeededLocked(null);
4514            }
4515        } finally {
4516            Binder.restoreCallingIdentity(callingId);
4517        }
4518    }
4519
4520    @Override
4521    public void forceStopPackage(final String packageName, int userId) {
4522        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4523                != PackageManager.PERMISSION_GRANTED) {
4524            String msg = "Permission Denial: forceStopPackage() from pid="
4525                    + Binder.getCallingPid()
4526                    + ", uid=" + Binder.getCallingUid()
4527                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4528            Slog.w(TAG, msg);
4529            throw new SecurityException(msg);
4530        }
4531        final int callingPid = Binder.getCallingPid();
4532        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4533                userId, true, true, "forceStopPackage", null);
4534        long callingId = Binder.clearCallingIdentity();
4535        try {
4536            IPackageManager pm = AppGlobals.getPackageManager();
4537            synchronized(this) {
4538                int[] users = userId == UserHandle.USER_ALL
4539                        ? getUsersLocked() : new int[] { userId };
4540                for (int user : users) {
4541                    int pkgUid = -1;
4542                    try {
4543                        pkgUid = pm.getPackageUid(packageName, user);
4544                    } catch (RemoteException e) {
4545                    }
4546                    if (pkgUid == -1) {
4547                        Slog.w(TAG, "Invalid packageName: " + packageName);
4548                        continue;
4549                    }
4550                    try {
4551                        pm.setPackageStoppedState(packageName, true, user);
4552                    } catch (RemoteException e) {
4553                    } catch (IllegalArgumentException e) {
4554                        Slog.w(TAG, "Failed trying to unstop package "
4555                                + packageName + ": " + e);
4556                    }
4557                    if (isUserRunningLocked(user, false)) {
4558                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4559                    }
4560                }
4561            }
4562        } finally {
4563            Binder.restoreCallingIdentity(callingId);
4564        }
4565    }
4566
4567    /*
4568     * The pkg name and app id have to be specified.
4569     */
4570    @Override
4571    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4572        if (pkg == null) {
4573            return;
4574        }
4575        // Make sure the uid is valid.
4576        if (appid < 0) {
4577            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4578            return;
4579        }
4580        int callerUid = Binder.getCallingUid();
4581        // Only the system server can kill an application
4582        if (callerUid == Process.SYSTEM_UID) {
4583            // Post an aysnc message to kill the application
4584            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4585            msg.arg1 = appid;
4586            msg.arg2 = 0;
4587            Bundle bundle = new Bundle();
4588            bundle.putString("pkg", pkg);
4589            bundle.putString("reason", reason);
4590            msg.obj = bundle;
4591            mHandler.sendMessage(msg);
4592        } else {
4593            throw new SecurityException(callerUid + " cannot kill pkg: " +
4594                    pkg);
4595        }
4596    }
4597
4598    @Override
4599    public void closeSystemDialogs(String reason) {
4600        enforceNotIsolatedCaller("closeSystemDialogs");
4601
4602        final int pid = Binder.getCallingPid();
4603        final int uid = Binder.getCallingUid();
4604        final long origId = Binder.clearCallingIdentity();
4605        try {
4606            synchronized (this) {
4607                // Only allow this from foreground processes, so that background
4608                // applications can't abuse it to prevent system UI from being shown.
4609                if (uid >= Process.FIRST_APPLICATION_UID) {
4610                    ProcessRecord proc;
4611                    synchronized (mPidsSelfLocked) {
4612                        proc = mPidsSelfLocked.get(pid);
4613                    }
4614                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4615                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4616                                + " from background process " + proc);
4617                        return;
4618                    }
4619                }
4620                closeSystemDialogsLocked(reason);
4621            }
4622        } finally {
4623            Binder.restoreCallingIdentity(origId);
4624        }
4625    }
4626
4627    void closeSystemDialogsLocked(String reason) {
4628        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4629        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4630                | Intent.FLAG_RECEIVER_FOREGROUND);
4631        if (reason != null) {
4632            intent.putExtra("reason", reason);
4633        }
4634        mWindowManager.closeSystemDialogs(reason);
4635
4636        mStackSupervisor.closeSystemDialogsLocked();
4637
4638        broadcastIntentLocked(null, null, intent, null,
4639                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4640                Process.SYSTEM_UID, UserHandle.USER_ALL);
4641    }
4642
4643    @Override
4644    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4645        enforceNotIsolatedCaller("getProcessMemoryInfo");
4646        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4647        for (int i=pids.length-1; i>=0; i--) {
4648            ProcessRecord proc;
4649            int oomAdj;
4650            synchronized (this) {
4651                synchronized (mPidsSelfLocked) {
4652                    proc = mPidsSelfLocked.get(pids[i]);
4653                    oomAdj = proc != null ? proc.setAdj : 0;
4654                }
4655            }
4656            infos[i] = new Debug.MemoryInfo();
4657            Debug.getMemoryInfo(pids[i], infos[i]);
4658            if (proc != null) {
4659                synchronized (this) {
4660                    if (proc.thread != null && proc.setAdj == oomAdj) {
4661                        // Record this for posterity if the process has been stable.
4662                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4663                                infos[i].getTotalUss(), false, proc.pkgList);
4664                    }
4665                }
4666            }
4667        }
4668        return infos;
4669    }
4670
4671    @Override
4672    public long[] getProcessPss(int[] pids) {
4673        enforceNotIsolatedCaller("getProcessPss");
4674        long[] pss = new long[pids.length];
4675        for (int i=pids.length-1; i>=0; i--) {
4676            ProcessRecord proc;
4677            int oomAdj;
4678            synchronized (this) {
4679                synchronized (mPidsSelfLocked) {
4680                    proc = mPidsSelfLocked.get(pids[i]);
4681                    oomAdj = proc != null ? proc.setAdj : 0;
4682                }
4683            }
4684            long[] tmpUss = new long[1];
4685            pss[i] = Debug.getPss(pids[i], tmpUss);
4686            if (proc != null) {
4687                synchronized (this) {
4688                    if (proc.thread != null && proc.setAdj == oomAdj) {
4689                        // Record this for posterity if the process has been stable.
4690                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4691                    }
4692                }
4693            }
4694        }
4695        return pss;
4696    }
4697
4698    @Override
4699    public void killApplicationProcess(String processName, int uid) {
4700        if (processName == null) {
4701            return;
4702        }
4703
4704        int callerUid = Binder.getCallingUid();
4705        // Only the system server can kill an application
4706        if (callerUid == Process.SYSTEM_UID) {
4707            synchronized (this) {
4708                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4709                if (app != null && app.thread != null) {
4710                    try {
4711                        app.thread.scheduleSuicide();
4712                    } catch (RemoteException e) {
4713                        // If the other end already died, then our work here is done.
4714                    }
4715                } else {
4716                    Slog.w(TAG, "Process/uid not found attempting kill of "
4717                            + processName + " / " + uid);
4718                }
4719            }
4720        } else {
4721            throw new SecurityException(callerUid + " cannot kill app process: " +
4722                    processName);
4723        }
4724    }
4725
4726    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4727        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4728                false, true, false, false, UserHandle.getUserId(uid), reason);
4729        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4730                Uri.fromParts("package", packageName, null));
4731        if (!mProcessesReady) {
4732            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4733                    | Intent.FLAG_RECEIVER_FOREGROUND);
4734        }
4735        intent.putExtra(Intent.EXTRA_UID, uid);
4736        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4737        broadcastIntentLocked(null, null, intent,
4738                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4739                false, false,
4740                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4741    }
4742
4743    private void forceStopUserLocked(int userId, String reason) {
4744        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4745        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4746        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4747                | Intent.FLAG_RECEIVER_FOREGROUND);
4748        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4749        broadcastIntentLocked(null, null, intent,
4750                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4751                false, false,
4752                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4753    }
4754
4755    private final boolean killPackageProcessesLocked(String packageName, int appId,
4756            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4757            boolean doit, boolean evenPersistent, String reason) {
4758        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4759
4760        // Remove all processes this package may have touched: all with the
4761        // same UID (except for the system or root user), and all whose name
4762        // matches the package name.
4763        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4764        final int NP = mProcessNames.getMap().size();
4765        for (int ip=0; ip<NP; ip++) {
4766            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4767            final int NA = apps.size();
4768            for (int ia=0; ia<NA; ia++) {
4769                ProcessRecord app = apps.valueAt(ia);
4770                if (app.persistent && !evenPersistent) {
4771                    // we don't kill persistent processes
4772                    continue;
4773                }
4774                if (app.removed) {
4775                    if (doit) {
4776                        procs.add(app);
4777                    }
4778                    continue;
4779                }
4780
4781                // Skip process if it doesn't meet our oom adj requirement.
4782                if (app.setAdj < minOomAdj) {
4783                    continue;
4784                }
4785
4786                // If no package is specified, we call all processes under the
4787                // give user id.
4788                if (packageName == null) {
4789                    if (app.userId != userId) {
4790                        continue;
4791                    }
4792                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4793                        continue;
4794                    }
4795                // Package has been specified, we want to hit all processes
4796                // that match it.  We need to qualify this by the processes
4797                // that are running under the specified app and user ID.
4798                } else {
4799                    if (UserHandle.getAppId(app.uid) != appId) {
4800                        continue;
4801                    }
4802                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4803                        continue;
4804                    }
4805                    if (!app.pkgList.containsKey(packageName)) {
4806                        continue;
4807                    }
4808                }
4809
4810                // Process has passed all conditions, kill it!
4811                if (!doit) {
4812                    return true;
4813                }
4814                app.removed = true;
4815                procs.add(app);
4816            }
4817        }
4818
4819        int N = procs.size();
4820        for (int i=0; i<N; i++) {
4821            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4822        }
4823        updateOomAdjLocked();
4824        return N > 0;
4825    }
4826
4827    private final boolean forceStopPackageLocked(String name, int appId,
4828            boolean callerWillRestart, boolean purgeCache, boolean doit,
4829            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4830        int i;
4831        int N;
4832
4833        if (userId == UserHandle.USER_ALL && name == null) {
4834            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4835        }
4836
4837        if (appId < 0 && name != null) {
4838            try {
4839                appId = UserHandle.getAppId(
4840                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4841            } catch (RemoteException e) {
4842            }
4843        }
4844
4845        if (doit) {
4846            if (name != null) {
4847                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4848                        + " user=" + userId + ": " + reason);
4849            } else {
4850                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4851            }
4852
4853            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4854            for (int ip=pmap.size()-1; ip>=0; ip--) {
4855                SparseArray<Long> ba = pmap.valueAt(ip);
4856                for (i=ba.size()-1; i>=0; i--) {
4857                    boolean remove = false;
4858                    final int entUid = ba.keyAt(i);
4859                    if (name != null) {
4860                        if (userId == UserHandle.USER_ALL) {
4861                            if (UserHandle.getAppId(entUid) == appId) {
4862                                remove = true;
4863                            }
4864                        } else {
4865                            if (entUid == UserHandle.getUid(userId, appId)) {
4866                                remove = true;
4867                            }
4868                        }
4869                    } else if (UserHandle.getUserId(entUid) == userId) {
4870                        remove = true;
4871                    }
4872                    if (remove) {
4873                        ba.removeAt(i);
4874                    }
4875                }
4876                if (ba.size() == 0) {
4877                    pmap.removeAt(ip);
4878                }
4879            }
4880        }
4881
4882        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4883                -100, callerWillRestart, true, doit, evenPersistent,
4884                name == null ? ("stop user " + userId) : ("stop " + name));
4885
4886        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4887            if (!doit) {
4888                return true;
4889            }
4890            didSomething = true;
4891        }
4892
4893        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4894            if (!doit) {
4895                return true;
4896            }
4897            didSomething = true;
4898        }
4899
4900        if (name == null) {
4901            // Remove all sticky broadcasts from this user.
4902            mStickyBroadcasts.remove(userId);
4903        }
4904
4905        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4906        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4907                userId, providers)) {
4908            if (!doit) {
4909                return true;
4910            }
4911            didSomething = true;
4912        }
4913        N = providers.size();
4914        for (i=0; i<N; i++) {
4915            removeDyingProviderLocked(null, providers.get(i), true);
4916        }
4917
4918        // Remove transient permissions granted from/to this package/user
4919        removeUriPermissionsForPackageLocked(name, userId, false);
4920
4921        if (name == null || uninstalling) {
4922            // Remove pending intents.  For now we only do this when force
4923            // stopping users, because we have some problems when doing this
4924            // for packages -- app widgets are not currently cleaned up for
4925            // such packages, so they can be left with bad pending intents.
4926            if (mIntentSenderRecords.size() > 0) {
4927                Iterator<WeakReference<PendingIntentRecord>> it
4928                        = mIntentSenderRecords.values().iterator();
4929                while (it.hasNext()) {
4930                    WeakReference<PendingIntentRecord> wpir = it.next();
4931                    if (wpir == null) {
4932                        it.remove();
4933                        continue;
4934                    }
4935                    PendingIntentRecord pir = wpir.get();
4936                    if (pir == null) {
4937                        it.remove();
4938                        continue;
4939                    }
4940                    if (name == null) {
4941                        // Stopping user, remove all objects for the user.
4942                        if (pir.key.userId != userId) {
4943                            // Not the same user, skip it.
4944                            continue;
4945                        }
4946                    } else {
4947                        if (UserHandle.getAppId(pir.uid) != appId) {
4948                            // Different app id, skip it.
4949                            continue;
4950                        }
4951                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4952                            // Different user, skip it.
4953                            continue;
4954                        }
4955                        if (!pir.key.packageName.equals(name)) {
4956                            // Different package, skip it.
4957                            continue;
4958                        }
4959                    }
4960                    if (!doit) {
4961                        return true;
4962                    }
4963                    didSomething = true;
4964                    it.remove();
4965                    pir.canceled = true;
4966                    if (pir.key.activity != null) {
4967                        pir.key.activity.pendingResults.remove(pir.ref);
4968                    }
4969                }
4970            }
4971        }
4972
4973        if (doit) {
4974            if (purgeCache && name != null) {
4975                AttributeCache ac = AttributeCache.instance();
4976                if (ac != null) {
4977                    ac.removePackage(name);
4978                }
4979            }
4980            if (mBooted) {
4981                mStackSupervisor.resumeTopActivitiesLocked();
4982                mStackSupervisor.scheduleIdleLocked();
4983            }
4984        }
4985
4986        return didSomething;
4987    }
4988
4989    private final boolean removeProcessLocked(ProcessRecord app,
4990            boolean callerWillRestart, boolean allowRestart, String reason) {
4991        final String name = app.processName;
4992        final int uid = app.uid;
4993        if (DEBUG_PROCESSES) Slog.d(
4994            TAG, "Force removing proc " + app.toShortString() + " (" + name
4995            + "/" + uid + ")");
4996
4997        mProcessNames.remove(name, uid);
4998        mIsolatedProcesses.remove(app.uid);
4999        if (mHeavyWeightProcess == app) {
5000            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5001                    mHeavyWeightProcess.userId, 0));
5002            mHeavyWeightProcess = null;
5003        }
5004        boolean needRestart = false;
5005        if (app.pid > 0 && app.pid != MY_PID) {
5006            int pid = app.pid;
5007            synchronized (mPidsSelfLocked) {
5008                mPidsSelfLocked.remove(pid);
5009                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5010            }
5011            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5012                    app.processName, app.info.uid);
5013            if (app.isolated) {
5014                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5015            }
5016            killUnneededProcessLocked(app, reason);
5017            handleAppDiedLocked(app, true, allowRestart);
5018            removeLruProcessLocked(app);
5019
5020            if (app.persistent && !app.isolated) {
5021                if (!callerWillRestart) {
5022                    addAppLocked(app.info, false);
5023                } else {
5024                    needRestart = true;
5025                }
5026            }
5027        } else {
5028            mRemovedProcesses.add(app);
5029        }
5030
5031        return needRestart;
5032    }
5033
5034    private final void processStartTimedOutLocked(ProcessRecord app) {
5035        final int pid = app.pid;
5036        boolean gone = false;
5037        synchronized (mPidsSelfLocked) {
5038            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5039            if (knownApp != null && knownApp.thread == null) {
5040                mPidsSelfLocked.remove(pid);
5041                gone = true;
5042            }
5043        }
5044
5045        if (gone) {
5046            Slog.w(TAG, "Process " + app + " failed to attach");
5047            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5048                    pid, app.uid, app.processName);
5049            mProcessNames.remove(app.processName, app.uid);
5050            mIsolatedProcesses.remove(app.uid);
5051            if (mHeavyWeightProcess == app) {
5052                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5053                        mHeavyWeightProcess.userId, 0));
5054                mHeavyWeightProcess = null;
5055            }
5056            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5057                    app.processName, app.info.uid);
5058            if (app.isolated) {
5059                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5060            }
5061            // Take care of any launching providers waiting for this process.
5062            checkAppInLaunchingProvidersLocked(app, true);
5063            // Take care of any services that are waiting for the process.
5064            mServices.processStartTimedOutLocked(app);
5065            killUnneededProcessLocked(app, "start timeout");
5066            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5067                Slog.w(TAG, "Unattached app died before backup, skipping");
5068                try {
5069                    IBackupManager bm = IBackupManager.Stub.asInterface(
5070                            ServiceManager.getService(Context.BACKUP_SERVICE));
5071                    bm.agentDisconnected(app.info.packageName);
5072                } catch (RemoteException e) {
5073                    // Can't happen; the backup manager is local
5074                }
5075            }
5076            if (isPendingBroadcastProcessLocked(pid)) {
5077                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5078                skipPendingBroadcastLocked(pid);
5079            }
5080        } else {
5081            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5082        }
5083    }
5084
5085    private final boolean attachApplicationLocked(IApplicationThread thread,
5086            int pid) {
5087
5088        // Find the application record that is being attached...  either via
5089        // the pid if we are running in multiple processes, or just pull the
5090        // next app record if we are emulating process with anonymous threads.
5091        ProcessRecord app;
5092        if (pid != MY_PID && pid >= 0) {
5093            synchronized (mPidsSelfLocked) {
5094                app = mPidsSelfLocked.get(pid);
5095            }
5096        } else {
5097            app = null;
5098        }
5099
5100        if (app == null) {
5101            Slog.w(TAG, "No pending application record for pid " + pid
5102                    + " (IApplicationThread " + thread + "); dropping process");
5103            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5104            if (pid > 0 && pid != MY_PID) {
5105                Process.killProcessQuiet(pid);
5106            } else {
5107                try {
5108                    thread.scheduleExit();
5109                } catch (Exception e) {
5110                    // Ignore exceptions.
5111                }
5112            }
5113            return false;
5114        }
5115
5116        // If this application record is still attached to a previous
5117        // process, clean it up now.
5118        if (app.thread != null) {
5119            handleAppDiedLocked(app, true, true);
5120        }
5121
5122        // Tell the process all about itself.
5123
5124        if (localLOGV) Slog.v(
5125                TAG, "Binding process pid " + pid + " to record " + app);
5126
5127        final String processName = app.processName;
5128        try {
5129            AppDeathRecipient adr = new AppDeathRecipient(
5130                    app, pid, thread);
5131            thread.asBinder().linkToDeath(adr, 0);
5132            app.deathRecipient = adr;
5133        } catch (RemoteException e) {
5134            app.resetPackageList(mProcessStats);
5135            startProcessLocked(app, "link fail", processName);
5136            return false;
5137        }
5138
5139        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5140
5141        app.makeActive(thread, mProcessStats);
5142        app.curAdj = app.setAdj = -100;
5143        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5144        app.forcingToForeground = null;
5145        updateProcessForegroundLocked(app, false, false);
5146        app.hasShownUi = false;
5147        app.debugging = false;
5148        app.cached = false;
5149
5150        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5151
5152        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5153        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5154
5155        if (!normalMode) {
5156            Slog.i(TAG, "Launching preboot mode app: " + app);
5157        }
5158
5159        if (localLOGV) Slog.v(
5160            TAG, "New app record " + app
5161            + " thread=" + thread.asBinder() + " pid=" + pid);
5162        try {
5163            int testMode = IApplicationThread.DEBUG_OFF;
5164            if (mDebugApp != null && mDebugApp.equals(processName)) {
5165                testMode = mWaitForDebugger
5166                    ? IApplicationThread.DEBUG_WAIT
5167                    : IApplicationThread.DEBUG_ON;
5168                app.debugging = true;
5169                if (mDebugTransient) {
5170                    mDebugApp = mOrigDebugApp;
5171                    mWaitForDebugger = mOrigWaitForDebugger;
5172                }
5173            }
5174            String profileFile = app.instrumentationProfileFile;
5175            ParcelFileDescriptor profileFd = null;
5176            boolean profileAutoStop = false;
5177            if (mProfileApp != null && mProfileApp.equals(processName)) {
5178                mProfileProc = app;
5179                profileFile = mProfileFile;
5180                profileFd = mProfileFd;
5181                profileAutoStop = mAutoStopProfiler;
5182            }
5183            boolean enableOpenGlTrace = false;
5184            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5185                enableOpenGlTrace = true;
5186                mOpenGlTraceApp = null;
5187            }
5188
5189            // If the app is being launched for restore or full backup, set it up specially
5190            boolean isRestrictedBackupMode = false;
5191            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5192                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5193                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5194                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5195            }
5196
5197            ensurePackageDexOpt(app.instrumentationInfo != null
5198                    ? app.instrumentationInfo.packageName
5199                    : app.info.packageName);
5200            if (app.instrumentationClass != null) {
5201                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5202            }
5203            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5204                    + processName + " with config " + mConfiguration);
5205            ApplicationInfo appInfo = app.instrumentationInfo != null
5206                    ? app.instrumentationInfo : app.info;
5207            app.compat = compatibilityInfoForPackageLocked(appInfo);
5208            if (profileFd != null) {
5209                profileFd = profileFd.dup();
5210            }
5211            thread.bindApplication(processName, appInfo, providers,
5212                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5213                    app.instrumentationArguments, app.instrumentationWatcher,
5214                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5215                    isRestrictedBackupMode || !normalMode, app.persistent,
5216                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5217                    mCoreSettingsObserver.getCoreSettingsLocked());
5218            updateLruProcessLocked(app, false, null);
5219            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5220        } catch (Exception e) {
5221            // todo: Yikes!  What should we do?  For now we will try to
5222            // start another process, but that could easily get us in
5223            // an infinite loop of restarting processes...
5224            Slog.w(TAG, "Exception thrown during bind!", e);
5225
5226            app.resetPackageList(mProcessStats);
5227            app.unlinkDeathRecipient();
5228            startProcessLocked(app, "bind fail", processName);
5229            return false;
5230        }
5231
5232        // Remove this record from the list of starting applications.
5233        mPersistentStartingProcesses.remove(app);
5234        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5235                "Attach application locked removing on hold: " + app);
5236        mProcessesOnHold.remove(app);
5237
5238        boolean badApp = false;
5239        boolean didSomething = false;
5240
5241        // See if the top visible activity is waiting to run in this process...
5242        if (normalMode) {
5243            try {
5244                if (mStackSupervisor.attachApplicationLocked(app)) {
5245                    didSomething = true;
5246                }
5247            } catch (Exception e) {
5248                badApp = true;
5249            }
5250        }
5251
5252        // Find any services that should be running in this process...
5253        if (!badApp) {
5254            try {
5255                didSomething |= mServices.attachApplicationLocked(app, processName);
5256            } catch (Exception e) {
5257                badApp = true;
5258            }
5259        }
5260
5261        // Check if a next-broadcast receiver is in this process...
5262        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5263            try {
5264                didSomething |= sendPendingBroadcastsLocked(app);
5265            } catch (Exception e) {
5266                // If the app died trying to launch the receiver we declare it 'bad'
5267                badApp = true;
5268            }
5269        }
5270
5271        // Check whether the next backup agent is in this process...
5272        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5273            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5274            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5275            try {
5276                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5277                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5278                        mBackupTarget.backupMode);
5279            } catch (Exception e) {
5280                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5281                e.printStackTrace();
5282            }
5283        }
5284
5285        if (badApp) {
5286            // todo: Also need to kill application to deal with all
5287            // kinds of exceptions.
5288            handleAppDiedLocked(app, false, true);
5289            return false;
5290        }
5291
5292        if (!didSomething) {
5293            updateOomAdjLocked();
5294        }
5295
5296        return true;
5297    }
5298
5299    @Override
5300    public final void attachApplication(IApplicationThread thread) {
5301        synchronized (this) {
5302            int callingPid = Binder.getCallingPid();
5303            final long origId = Binder.clearCallingIdentity();
5304            attachApplicationLocked(thread, callingPid);
5305            Binder.restoreCallingIdentity(origId);
5306        }
5307    }
5308
5309    @Override
5310    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5311        final long origId = Binder.clearCallingIdentity();
5312        synchronized (this) {
5313            ActivityStack stack = ActivityRecord.getStackLocked(token);
5314            if (stack != null) {
5315                ActivityRecord r =
5316                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5317                if (stopProfiling) {
5318                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5319                        try {
5320                            mProfileFd.close();
5321                        } catch (IOException e) {
5322                        }
5323                        clearProfilerLocked();
5324                    }
5325                }
5326            }
5327        }
5328        Binder.restoreCallingIdentity(origId);
5329    }
5330
5331    void enableScreenAfterBoot() {
5332        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5333                SystemClock.uptimeMillis());
5334        mWindowManager.enableScreenAfterBoot();
5335
5336        synchronized (this) {
5337            updateEventDispatchingLocked();
5338        }
5339    }
5340
5341    @Override
5342    public void showBootMessage(final CharSequence msg, final boolean always) {
5343        enforceNotIsolatedCaller("showBootMessage");
5344        mWindowManager.showBootMessage(msg, always);
5345    }
5346
5347    @Override
5348    public void dismissKeyguardOnNextActivity() {
5349        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5350        final long token = Binder.clearCallingIdentity();
5351        try {
5352            synchronized (this) {
5353                if (DEBUG_LOCKSCREEN) logLockScreen("");
5354                if (mLockScreenShown) {
5355                    mLockScreenShown = false;
5356                    comeOutOfSleepIfNeededLocked();
5357                }
5358                mStackSupervisor.setDismissKeyguard(true);
5359            }
5360        } finally {
5361            Binder.restoreCallingIdentity(token);
5362        }
5363    }
5364
5365    final void finishBooting() {
5366        // Register receivers to handle package update events
5367        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5368
5369        synchronized (this) {
5370            // Ensure that any processes we had put on hold are now started
5371            // up.
5372            final int NP = mProcessesOnHold.size();
5373            if (NP > 0) {
5374                ArrayList<ProcessRecord> procs =
5375                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5376                for (int ip=0; ip<NP; ip++) {
5377                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5378                            + procs.get(ip));
5379                    startProcessLocked(procs.get(ip), "on-hold", null);
5380                }
5381            }
5382
5383            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5384                // Start looking for apps that are abusing wake locks.
5385                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5386                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5387                // Tell anyone interested that we are done booting!
5388                SystemProperties.set("sys.boot_completed", "1");
5389                SystemProperties.set("dev.bootcomplete", "1");
5390                for (int i=0; i<mStartedUsers.size(); i++) {
5391                    UserStartedState uss = mStartedUsers.valueAt(i);
5392                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5393                        uss.mState = UserStartedState.STATE_RUNNING;
5394                        final int userId = mStartedUsers.keyAt(i);
5395                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5396                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5397                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5398                        broadcastIntentLocked(null, null, intent, null,
5399                                new IIntentReceiver.Stub() {
5400                                    @Override
5401                                    public void performReceive(Intent intent, int resultCode,
5402                                            String data, Bundle extras, boolean ordered,
5403                                            boolean sticky, int sendingUser) {
5404                                        synchronized (ActivityManagerService.this) {
5405                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5406                                                    true, false);
5407                                        }
5408                                    }
5409                                },
5410                                0, null, null,
5411                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5412                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5413                                userId);
5414                    }
5415                }
5416                scheduleStartProfilesLocked();
5417            }
5418        }
5419    }
5420
5421    final void ensureBootCompleted() {
5422        boolean booting;
5423        boolean enableScreen;
5424        synchronized (this) {
5425            booting = mBooting;
5426            mBooting = false;
5427            enableScreen = !mBooted;
5428            mBooted = true;
5429        }
5430
5431        if (booting) {
5432            finishBooting();
5433        }
5434
5435        if (enableScreen) {
5436            enableScreenAfterBoot();
5437        }
5438    }
5439
5440    @Override
5441    public final void activityResumed(IBinder token) {
5442        final long origId = Binder.clearCallingIdentity();
5443        synchronized(this) {
5444            ActivityStack stack = ActivityRecord.getStackLocked(token);
5445            if (stack != null) {
5446                ActivityRecord.activityResumedLocked(token);
5447            }
5448        }
5449        Binder.restoreCallingIdentity(origId);
5450    }
5451
5452    @Override
5453    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5454        final long origId = Binder.clearCallingIdentity();
5455        synchronized(this) {
5456            ActivityStack stack = ActivityRecord.getStackLocked(token);
5457            if (stack != null) {
5458                stack.activityPausedLocked(token, false, persistentState);
5459            }
5460        }
5461        Binder.restoreCallingIdentity(origId);
5462    }
5463
5464    @Override
5465    public final void activityStopped(IBinder token, Bundle icicle,
5466            PersistableBundle persistentState, CharSequence description) {
5467        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5468
5469        // Refuse possible leaked file descriptors
5470        if (icicle != null && icicle.hasFileDescriptors()) {
5471            throw new IllegalArgumentException("File descriptors passed in Bundle");
5472        }
5473
5474        final long origId = Binder.clearCallingIdentity();
5475
5476        synchronized (this) {
5477            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5478            if (r != null) {
5479                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5480            }
5481        }
5482
5483        trimApplications();
5484
5485        Binder.restoreCallingIdentity(origId);
5486    }
5487
5488    @Override
5489    public final void activityDestroyed(IBinder token) {
5490        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5491        synchronized (this) {
5492            ActivityStack stack = ActivityRecord.getStackLocked(token);
5493            if (stack != null) {
5494                stack.activityDestroyedLocked(token);
5495            }
5496        }
5497    }
5498
5499    @Override
5500    public String getCallingPackage(IBinder token) {
5501        synchronized (this) {
5502            ActivityRecord r = getCallingRecordLocked(token);
5503            return r != null ? r.info.packageName : null;
5504        }
5505    }
5506
5507    @Override
5508    public ComponentName getCallingActivity(IBinder token) {
5509        synchronized (this) {
5510            ActivityRecord r = getCallingRecordLocked(token);
5511            return r != null ? r.intent.getComponent() : null;
5512        }
5513    }
5514
5515    private ActivityRecord getCallingRecordLocked(IBinder token) {
5516        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5517        if (r == null) {
5518            return null;
5519        }
5520        return r.resultTo;
5521    }
5522
5523    @Override
5524    public ComponentName getActivityClassForToken(IBinder token) {
5525        synchronized(this) {
5526            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5527            if (r == null) {
5528                return null;
5529            }
5530            return r.intent.getComponent();
5531        }
5532    }
5533
5534    @Override
5535    public String getPackageForToken(IBinder token) {
5536        synchronized(this) {
5537            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5538            if (r == null) {
5539                return null;
5540            }
5541            return r.packageName;
5542        }
5543    }
5544
5545    @Override
5546    public IIntentSender getIntentSender(int type,
5547            String packageName, IBinder token, String resultWho,
5548            int requestCode, Intent[] intents, String[] resolvedTypes,
5549            int flags, Bundle options, int userId) {
5550        enforceNotIsolatedCaller("getIntentSender");
5551        // Refuse possible leaked file descriptors
5552        if (intents != null) {
5553            if (intents.length < 1) {
5554                throw new IllegalArgumentException("Intents array length must be >= 1");
5555            }
5556            for (int i=0; i<intents.length; i++) {
5557                Intent intent = intents[i];
5558                if (intent != null) {
5559                    if (intent.hasFileDescriptors()) {
5560                        throw new IllegalArgumentException("File descriptors passed in Intent");
5561                    }
5562                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5563                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5564                        throw new IllegalArgumentException(
5565                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5566                    }
5567                    intents[i] = new Intent(intent);
5568                }
5569            }
5570            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5571                throw new IllegalArgumentException(
5572                        "Intent array length does not match resolvedTypes length");
5573            }
5574        }
5575        if (options != null) {
5576            if (options.hasFileDescriptors()) {
5577                throw new IllegalArgumentException("File descriptors passed in options");
5578            }
5579        }
5580
5581        synchronized(this) {
5582            int callingUid = Binder.getCallingUid();
5583            int origUserId = userId;
5584            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5585                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5586                    "getIntentSender", null);
5587            if (origUserId == UserHandle.USER_CURRENT) {
5588                // We don't want to evaluate this until the pending intent is
5589                // actually executed.  However, we do want to always do the
5590                // security checking for it above.
5591                userId = UserHandle.USER_CURRENT;
5592            }
5593            try {
5594                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5595                    int uid = AppGlobals.getPackageManager()
5596                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5597                    if (!UserHandle.isSameApp(callingUid, uid)) {
5598                        String msg = "Permission Denial: getIntentSender() from pid="
5599                            + Binder.getCallingPid()
5600                            + ", uid=" + Binder.getCallingUid()
5601                            + ", (need uid=" + uid + ")"
5602                            + " is not allowed to send as package " + packageName;
5603                        Slog.w(TAG, msg);
5604                        throw new SecurityException(msg);
5605                    }
5606                }
5607
5608                return getIntentSenderLocked(type, packageName, callingUid, userId,
5609                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5610
5611            } catch (RemoteException e) {
5612                throw new SecurityException(e);
5613            }
5614        }
5615    }
5616
5617    IIntentSender getIntentSenderLocked(int type, String packageName,
5618            int callingUid, int userId, IBinder token, String resultWho,
5619            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5620            Bundle options) {
5621        if (DEBUG_MU)
5622            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5623        ActivityRecord activity = null;
5624        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5625            activity = ActivityRecord.isInStackLocked(token);
5626            if (activity == null) {
5627                return null;
5628            }
5629            if (activity.finishing) {
5630                return null;
5631            }
5632        }
5633
5634        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5635        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5636        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5637        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5638                |PendingIntent.FLAG_UPDATE_CURRENT);
5639
5640        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5641                type, packageName, activity, resultWho,
5642                requestCode, intents, resolvedTypes, flags, options, userId);
5643        WeakReference<PendingIntentRecord> ref;
5644        ref = mIntentSenderRecords.get(key);
5645        PendingIntentRecord rec = ref != null ? ref.get() : null;
5646        if (rec != null) {
5647            if (!cancelCurrent) {
5648                if (updateCurrent) {
5649                    if (rec.key.requestIntent != null) {
5650                        rec.key.requestIntent.replaceExtras(intents != null ?
5651                                intents[intents.length - 1] : null);
5652                    }
5653                    if (intents != null) {
5654                        intents[intents.length-1] = rec.key.requestIntent;
5655                        rec.key.allIntents = intents;
5656                        rec.key.allResolvedTypes = resolvedTypes;
5657                    } else {
5658                        rec.key.allIntents = null;
5659                        rec.key.allResolvedTypes = null;
5660                    }
5661                }
5662                return rec;
5663            }
5664            rec.canceled = true;
5665            mIntentSenderRecords.remove(key);
5666        }
5667        if (noCreate) {
5668            return rec;
5669        }
5670        rec = new PendingIntentRecord(this, key, callingUid);
5671        mIntentSenderRecords.put(key, rec.ref);
5672        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5673            if (activity.pendingResults == null) {
5674                activity.pendingResults
5675                        = new HashSet<WeakReference<PendingIntentRecord>>();
5676            }
5677            activity.pendingResults.add(rec.ref);
5678        }
5679        return rec;
5680    }
5681
5682    @Override
5683    public void cancelIntentSender(IIntentSender sender) {
5684        if (!(sender instanceof PendingIntentRecord)) {
5685            return;
5686        }
5687        synchronized(this) {
5688            PendingIntentRecord rec = (PendingIntentRecord)sender;
5689            try {
5690                int uid = AppGlobals.getPackageManager()
5691                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5692                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5693                    String msg = "Permission Denial: cancelIntentSender() from pid="
5694                        + Binder.getCallingPid()
5695                        + ", uid=" + Binder.getCallingUid()
5696                        + " is not allowed to cancel packges "
5697                        + rec.key.packageName;
5698                    Slog.w(TAG, msg);
5699                    throw new SecurityException(msg);
5700                }
5701            } catch (RemoteException e) {
5702                throw new SecurityException(e);
5703            }
5704            cancelIntentSenderLocked(rec, true);
5705        }
5706    }
5707
5708    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5709        rec.canceled = true;
5710        mIntentSenderRecords.remove(rec.key);
5711        if (cleanActivity && rec.key.activity != null) {
5712            rec.key.activity.pendingResults.remove(rec.ref);
5713        }
5714    }
5715
5716    @Override
5717    public String getPackageForIntentSender(IIntentSender pendingResult) {
5718        if (!(pendingResult instanceof PendingIntentRecord)) {
5719            return null;
5720        }
5721        try {
5722            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5723            return res.key.packageName;
5724        } catch (ClassCastException e) {
5725        }
5726        return null;
5727    }
5728
5729    @Override
5730    public int getUidForIntentSender(IIntentSender sender) {
5731        if (sender instanceof PendingIntentRecord) {
5732            try {
5733                PendingIntentRecord res = (PendingIntentRecord)sender;
5734                return res.uid;
5735            } catch (ClassCastException e) {
5736            }
5737        }
5738        return -1;
5739    }
5740
5741    @Override
5742    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5743        if (!(pendingResult instanceof PendingIntentRecord)) {
5744            return false;
5745        }
5746        try {
5747            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5748            if (res.key.allIntents == null) {
5749                return false;
5750            }
5751            for (int i=0; i<res.key.allIntents.length; i++) {
5752                Intent intent = res.key.allIntents[i];
5753                if (intent.getPackage() != null && intent.getComponent() != null) {
5754                    return false;
5755                }
5756            }
5757            return true;
5758        } catch (ClassCastException e) {
5759        }
5760        return false;
5761    }
5762
5763    @Override
5764    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5765        if (!(pendingResult instanceof PendingIntentRecord)) {
5766            return false;
5767        }
5768        try {
5769            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5770            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5771                return true;
5772            }
5773            return false;
5774        } catch (ClassCastException e) {
5775        }
5776        return false;
5777    }
5778
5779    @Override
5780    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5781        if (!(pendingResult instanceof PendingIntentRecord)) {
5782            return null;
5783        }
5784        try {
5785            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5786            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5787        } catch (ClassCastException e) {
5788        }
5789        return null;
5790    }
5791
5792    @Override
5793    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5794        if (!(pendingResult instanceof PendingIntentRecord)) {
5795            return null;
5796        }
5797        try {
5798            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5799            Intent intent = res.key.requestIntent;
5800            if (intent != null) {
5801                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5802                        || res.lastTagPrefix.equals(prefix))) {
5803                    return res.lastTag;
5804                }
5805                res.lastTagPrefix = prefix;
5806                StringBuilder sb = new StringBuilder(128);
5807                if (prefix != null) {
5808                    sb.append(prefix);
5809                }
5810                if (intent.getAction() != null) {
5811                    sb.append(intent.getAction());
5812                } else if (intent.getComponent() != null) {
5813                    intent.getComponent().appendShortString(sb);
5814                } else {
5815                    sb.append("?");
5816                }
5817                return res.lastTag = sb.toString();
5818            }
5819        } catch (ClassCastException e) {
5820        }
5821        return null;
5822    }
5823
5824    @Override
5825    public void setProcessLimit(int max) {
5826        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5827                "setProcessLimit()");
5828        synchronized (this) {
5829            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5830            mProcessLimitOverride = max;
5831        }
5832        trimApplications();
5833    }
5834
5835    @Override
5836    public int getProcessLimit() {
5837        synchronized (this) {
5838            return mProcessLimitOverride;
5839        }
5840    }
5841
5842    void foregroundTokenDied(ForegroundToken token) {
5843        synchronized (ActivityManagerService.this) {
5844            synchronized (mPidsSelfLocked) {
5845                ForegroundToken cur
5846                    = mForegroundProcesses.get(token.pid);
5847                if (cur != token) {
5848                    return;
5849                }
5850                mForegroundProcesses.remove(token.pid);
5851                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5852                if (pr == null) {
5853                    return;
5854                }
5855                pr.forcingToForeground = null;
5856                updateProcessForegroundLocked(pr, false, false);
5857            }
5858            updateOomAdjLocked();
5859        }
5860    }
5861
5862    @Override
5863    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5864        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5865                "setProcessForeground()");
5866        synchronized(this) {
5867            boolean changed = false;
5868
5869            synchronized (mPidsSelfLocked) {
5870                ProcessRecord pr = mPidsSelfLocked.get(pid);
5871                if (pr == null && isForeground) {
5872                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5873                    return;
5874                }
5875                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5876                if (oldToken != null) {
5877                    oldToken.token.unlinkToDeath(oldToken, 0);
5878                    mForegroundProcesses.remove(pid);
5879                    if (pr != null) {
5880                        pr.forcingToForeground = null;
5881                    }
5882                    changed = true;
5883                }
5884                if (isForeground && token != null) {
5885                    ForegroundToken newToken = new ForegroundToken() {
5886                        @Override
5887                        public void binderDied() {
5888                            foregroundTokenDied(this);
5889                        }
5890                    };
5891                    newToken.pid = pid;
5892                    newToken.token = token;
5893                    try {
5894                        token.linkToDeath(newToken, 0);
5895                        mForegroundProcesses.put(pid, newToken);
5896                        pr.forcingToForeground = token;
5897                        changed = true;
5898                    } catch (RemoteException e) {
5899                        // If the process died while doing this, we will later
5900                        // do the cleanup with the process death link.
5901                    }
5902                }
5903            }
5904
5905            if (changed) {
5906                updateOomAdjLocked();
5907            }
5908        }
5909    }
5910
5911    // =========================================================
5912    // PERMISSIONS
5913    // =========================================================
5914
5915    static class PermissionController extends IPermissionController.Stub {
5916        ActivityManagerService mActivityManagerService;
5917        PermissionController(ActivityManagerService activityManagerService) {
5918            mActivityManagerService = activityManagerService;
5919        }
5920
5921        @Override
5922        public boolean checkPermission(String permission, int pid, int uid) {
5923            return mActivityManagerService.checkPermission(permission, pid,
5924                    uid) == PackageManager.PERMISSION_GRANTED;
5925        }
5926    }
5927
5928    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5929        @Override
5930        public int checkComponentPermission(String permission, int pid, int uid,
5931                int owningUid, boolean exported) {
5932            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5933                    owningUid, exported);
5934        }
5935
5936        @Override
5937        public Object getAMSLock() {
5938            return ActivityManagerService.this;
5939        }
5940    }
5941
5942    /**
5943     * This can be called with or without the global lock held.
5944     */
5945    int checkComponentPermission(String permission, int pid, int uid,
5946            int owningUid, boolean exported) {
5947        // We might be performing an operation on behalf of an indirect binder
5948        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5949        // client identity accordingly before proceeding.
5950        Identity tlsIdentity = sCallerIdentity.get();
5951        if (tlsIdentity != null) {
5952            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5953                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5954            uid = tlsIdentity.uid;
5955            pid = tlsIdentity.pid;
5956        }
5957
5958        if (pid == MY_PID) {
5959            return PackageManager.PERMISSION_GRANTED;
5960        }
5961
5962        return ActivityManager.checkComponentPermission(permission, uid,
5963                owningUid, exported);
5964    }
5965
5966    /**
5967     * As the only public entry point for permissions checking, this method
5968     * can enforce the semantic that requesting a check on a null global
5969     * permission is automatically denied.  (Internally a null permission
5970     * string is used when calling {@link #checkComponentPermission} in cases
5971     * when only uid-based security is needed.)
5972     *
5973     * This can be called with or without the global lock held.
5974     */
5975    @Override
5976    public int checkPermission(String permission, int pid, int uid) {
5977        if (permission == null) {
5978            return PackageManager.PERMISSION_DENIED;
5979        }
5980        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5981    }
5982
5983    /**
5984     * Binder IPC calls go through the public entry point.
5985     * This can be called with or without the global lock held.
5986     */
5987    int checkCallingPermission(String permission) {
5988        return checkPermission(permission,
5989                Binder.getCallingPid(),
5990                UserHandle.getAppId(Binder.getCallingUid()));
5991    }
5992
5993    /**
5994     * This can be called with or without the global lock held.
5995     */
5996    void enforceCallingPermission(String permission, String func) {
5997        if (checkCallingPermission(permission)
5998                == PackageManager.PERMISSION_GRANTED) {
5999            return;
6000        }
6001
6002        String msg = "Permission Denial: " + func + " from pid="
6003                + Binder.getCallingPid()
6004                + ", uid=" + Binder.getCallingUid()
6005                + " requires " + permission;
6006        Slog.w(TAG, msg);
6007        throw new SecurityException(msg);
6008    }
6009
6010    /**
6011     * Determine if UID is holding permissions required to access {@link Uri} in
6012     * the given {@link ProviderInfo}. Final permission checking is always done
6013     * in {@link ContentProvider}.
6014     */
6015    private final boolean checkHoldingPermissionsLocked(
6016            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6017        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6018                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6019        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6020            return false;
6021        }
6022
6023        if (pi.applicationInfo.uid == uid) {
6024            return true;
6025        } else if (!pi.exported) {
6026            return false;
6027        }
6028
6029        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6030        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6031        try {
6032            // check if target holds top-level <provider> permissions
6033            if (!readMet && pi.readPermission != null
6034                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6035                readMet = true;
6036            }
6037            if (!writeMet && pi.writePermission != null
6038                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6039                writeMet = true;
6040            }
6041
6042            // track if unprotected read/write is allowed; any denied
6043            // <path-permission> below removes this ability
6044            boolean allowDefaultRead = pi.readPermission == null;
6045            boolean allowDefaultWrite = pi.writePermission == null;
6046
6047            // check if target holds any <path-permission> that match uri
6048            final PathPermission[] pps = pi.pathPermissions;
6049            if (pps != null) {
6050                final String path = grantUri.uri.getPath();
6051                int i = pps.length;
6052                while (i > 0 && (!readMet || !writeMet)) {
6053                    i--;
6054                    PathPermission pp = pps[i];
6055                    if (pp.match(path)) {
6056                        if (!readMet) {
6057                            final String pprperm = pp.getReadPermission();
6058                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6059                                    + pprperm + " for " + pp.getPath()
6060                                    + ": match=" + pp.match(path)
6061                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6062                            if (pprperm != null) {
6063                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6064                                    readMet = true;
6065                                } else {
6066                                    allowDefaultRead = false;
6067                                }
6068                            }
6069                        }
6070                        if (!writeMet) {
6071                            final String ppwperm = pp.getWritePermission();
6072                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6073                                    + ppwperm + " for " + pp.getPath()
6074                                    + ": match=" + pp.match(path)
6075                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6076                            if (ppwperm != null) {
6077                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6078                                    writeMet = true;
6079                                } else {
6080                                    allowDefaultWrite = false;
6081                                }
6082                            }
6083                        }
6084                    }
6085                }
6086            }
6087
6088            // grant unprotected <provider> read/write, if not blocked by
6089            // <path-permission> above
6090            if (allowDefaultRead) readMet = true;
6091            if (allowDefaultWrite) writeMet = true;
6092
6093        } catch (RemoteException e) {
6094            return false;
6095        }
6096
6097        return readMet && writeMet;
6098    }
6099
6100    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6101        ProviderInfo pi = null;
6102        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6103        if (cpr != null) {
6104            pi = cpr.info;
6105        } else {
6106            try {
6107                pi = AppGlobals.getPackageManager().resolveContentProvider(
6108                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6109            } catch (RemoteException ex) {
6110            }
6111        }
6112        return pi;
6113    }
6114
6115    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6116        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6117        if (targetUris != null) {
6118            return targetUris.get(grantUri);
6119        }
6120        return null;
6121    }
6122
6123    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6124            String targetPkg, int targetUid, GrantUri grantUri) {
6125        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6126        if (targetUris == null) {
6127            targetUris = Maps.newArrayMap();
6128            mGrantedUriPermissions.put(targetUid, targetUris);
6129        }
6130
6131        UriPermission perm = targetUris.get(grantUri);
6132        if (perm == null) {
6133            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6134            targetUris.put(grantUri, perm);
6135        }
6136
6137        return perm;
6138    }
6139
6140    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6141            final int modeFlags) {
6142        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6143        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6144                : UriPermission.STRENGTH_OWNED;
6145
6146        // Root gets to do everything.
6147        if (uid == 0) {
6148            return true;
6149        }
6150
6151        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6152        if (perms == null) return false;
6153
6154        // First look for exact match
6155        final UriPermission exactPerm = perms.get(grantUri);
6156        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6157            return true;
6158        }
6159
6160        // No exact match, look for prefixes
6161        final int N = perms.size();
6162        for (int i = 0; i < N; i++) {
6163            final UriPermission perm = perms.valueAt(i);
6164            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6165                    && perm.getStrength(modeFlags) >= minStrength) {
6166                return true;
6167            }
6168        }
6169
6170        return false;
6171    }
6172
6173    @Override
6174    public int checkUriPermission(Uri uri, int pid, int uid,
6175            final int modeFlags, int userId) {
6176        enforceNotIsolatedCaller("checkUriPermission");
6177
6178        // Another redirected-binder-call permissions check as in
6179        // {@link checkComponentPermission}.
6180        Identity tlsIdentity = sCallerIdentity.get();
6181        if (tlsIdentity != null) {
6182            uid = tlsIdentity.uid;
6183            pid = tlsIdentity.pid;
6184        }
6185
6186        // Our own process gets to do everything.
6187        if (pid == MY_PID) {
6188            return PackageManager.PERMISSION_GRANTED;
6189        }
6190        synchronized (this) {
6191            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6192                    ? PackageManager.PERMISSION_GRANTED
6193                    : PackageManager.PERMISSION_DENIED;
6194        }
6195    }
6196
6197    /**
6198     * Check if the targetPkg can be granted permission to access uri by
6199     * the callingUid using the given modeFlags.  Throws a security exception
6200     * if callingUid is not allowed to do this.  Returns the uid of the target
6201     * if the URI permission grant should be performed; returns -1 if it is not
6202     * needed (for example targetPkg already has permission to access the URI).
6203     * If you already know the uid of the target, you can supply it in
6204     * lastTargetUid else set that to -1.
6205     */
6206    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6207            final int modeFlags, int lastTargetUid) {
6208        if (!Intent.isAccessUriMode(modeFlags)) {
6209            return -1;
6210        }
6211
6212        if (targetPkg != null) {
6213            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6214                    "Checking grant " + targetPkg + " permission to " + grantUri);
6215        }
6216
6217        final IPackageManager pm = AppGlobals.getPackageManager();
6218
6219        // If this is not a content: uri, we can't do anything with it.
6220        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6221            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6222                    "Can't grant URI permission for non-content URI: " + grantUri);
6223            return -1;
6224        }
6225
6226        final String authority = grantUri.uri.getAuthority();
6227        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6228        if (pi == null) {
6229            Slog.w(TAG, "No content provider found for permission check: " +
6230                    grantUri.uri.toSafeString());
6231            return -1;
6232        }
6233
6234        int targetUid = lastTargetUid;
6235        if (targetUid < 0 && targetPkg != null) {
6236            try {
6237                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6238                if (targetUid < 0) {
6239                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6240                            "Can't grant URI permission no uid for: " + targetPkg);
6241                    return -1;
6242                }
6243            } catch (RemoteException ex) {
6244                return -1;
6245            }
6246        }
6247
6248        if (targetUid >= 0) {
6249            // First...  does the target actually need this permission?
6250            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6251                // No need to grant the target this permission.
6252                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6253                        "Target " + targetPkg + " already has full permission to " + grantUri);
6254                return -1;
6255            }
6256        } else {
6257            // First...  there is no target package, so can anyone access it?
6258            boolean allowed = pi.exported;
6259            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6260                if (pi.readPermission != null) {
6261                    allowed = false;
6262                }
6263            }
6264            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6265                if (pi.writePermission != null) {
6266                    allowed = false;
6267                }
6268            }
6269            if (allowed) {
6270                return -1;
6271            }
6272        }
6273
6274        // Second...  is the provider allowing granting of URI permissions?
6275        if (!pi.grantUriPermissions) {
6276            throw new SecurityException("Provider " + pi.packageName
6277                    + "/" + pi.name
6278                    + " does not allow granting of Uri permissions (uri "
6279                    + grantUri + ")");
6280        }
6281        if (pi.uriPermissionPatterns != null) {
6282            final int N = pi.uriPermissionPatterns.length;
6283            boolean allowed = false;
6284            for (int i=0; i<N; i++) {
6285                if (pi.uriPermissionPatterns[i] != null
6286                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6287                    allowed = true;
6288                    break;
6289                }
6290            }
6291            if (!allowed) {
6292                throw new SecurityException("Provider " + pi.packageName
6293                        + "/" + pi.name
6294                        + " does not allow granting of permission to path of Uri "
6295                        + grantUri);
6296            }
6297        }
6298
6299        // Third...  does the caller itself have permission to access
6300        // this uri?
6301        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6302            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6303                // Require they hold a strong enough Uri permission
6304                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6305                    throw new SecurityException("Uid " + callingUid
6306                            + " does not have permission to uri " + grantUri);
6307                }
6308            }
6309        }
6310        return targetUid;
6311    }
6312
6313    @Override
6314    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6315            final int modeFlags, int userId) {
6316        enforceNotIsolatedCaller("checkGrantUriPermission");
6317        synchronized(this) {
6318            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6319                    new GrantUri(userId, uri, false), modeFlags, -1);
6320        }
6321    }
6322
6323    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6324            final int modeFlags, UriPermissionOwner owner) {
6325        if (!Intent.isAccessUriMode(modeFlags)) {
6326            return;
6327        }
6328
6329        // So here we are: the caller has the assumed permission
6330        // to the uri, and the target doesn't.  Let's now give this to
6331        // the target.
6332
6333        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6334                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6335
6336        final String authority = grantUri.uri.getAuthority();
6337        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6338        if (pi == null) {
6339            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6340            return;
6341        }
6342
6343        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6344            grantUri.prefix = true;
6345        }
6346        final UriPermission perm = findOrCreateUriPermissionLocked(
6347                pi.packageName, targetPkg, targetUid, grantUri);
6348        perm.grantModes(modeFlags, owner);
6349    }
6350
6351    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6352            final int modeFlags, UriPermissionOwner owner) {
6353        if (targetPkg == null) {
6354            throw new NullPointerException("targetPkg");
6355        }
6356
6357        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6358                -1);
6359        if (targetUid < 0) {
6360            return;
6361        }
6362
6363        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6364                owner);
6365    }
6366
6367    static class NeededUriGrants extends ArrayList<GrantUri> {
6368        final String targetPkg;
6369        final int targetUid;
6370        final int flags;
6371
6372        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6373            this.targetPkg = targetPkg;
6374            this.targetUid = targetUid;
6375            this.flags = flags;
6376        }
6377    }
6378
6379    /**
6380     * Like checkGrantUriPermissionLocked, but takes an Intent.
6381     */
6382    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6383            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6384        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6385                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6386                + " clip=" + (intent != null ? intent.getClipData() : null)
6387                + " from " + intent + "; flags=0x"
6388                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6389
6390        if (targetPkg == null) {
6391            throw new NullPointerException("targetPkg");
6392        }
6393
6394        if (intent == null) {
6395            return null;
6396        }
6397        Uri data = intent.getData();
6398        ClipData clip = intent.getClipData();
6399        if (data == null && clip == null) {
6400            return null;
6401        }
6402        final IPackageManager pm = AppGlobals.getPackageManager();
6403        int targetUid;
6404        if (needed != null) {
6405            targetUid = needed.targetUid;
6406        } else {
6407            try {
6408                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6409            } catch (RemoteException ex) {
6410                return null;
6411            }
6412            if (targetUid < 0) {
6413                if (DEBUG_URI_PERMISSION) {
6414                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6415                            + " on user " + targetUserId);
6416                }
6417                return null;
6418            }
6419        }
6420        if (data != null) {
6421            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6422            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6423                    targetUid);
6424            if (targetUid > 0) {
6425                if (needed == null) {
6426                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6427                }
6428                needed.add(grantUri);
6429            }
6430        }
6431        if (clip != null) {
6432            for (int i=0; i<clip.getItemCount(); i++) {
6433                Uri uri = clip.getItemAt(i).getUri();
6434                if (uri != null) {
6435                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6436                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6437                            targetUid);
6438                    if (targetUid > 0) {
6439                        if (needed == null) {
6440                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6441                        }
6442                        needed.add(grantUri);
6443                    }
6444                } else {
6445                    Intent clipIntent = clip.getItemAt(i).getIntent();
6446                    if (clipIntent != null) {
6447                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6448                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6449                        if (newNeeded != null) {
6450                            needed = newNeeded;
6451                        }
6452                    }
6453                }
6454            }
6455        }
6456
6457        return needed;
6458    }
6459
6460    /**
6461     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6462     */
6463    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6464            UriPermissionOwner owner) {
6465        if (needed != null) {
6466            for (int i=0; i<needed.size(); i++) {
6467                GrantUri grantUri = needed.get(i);
6468                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6469                        grantUri, needed.flags, owner);
6470            }
6471        }
6472    }
6473
6474    void grantUriPermissionFromIntentLocked(int callingUid,
6475            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6476        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6477                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6478        if (needed == null) {
6479            return;
6480        }
6481
6482        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6483    }
6484
6485    @Override
6486    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6487            final int modeFlags, int userId) {
6488        enforceNotIsolatedCaller("grantUriPermission");
6489        GrantUri grantUri = new GrantUri(userId, uri, false);
6490        synchronized(this) {
6491            final ProcessRecord r = getRecordForAppLocked(caller);
6492            if (r == null) {
6493                throw new SecurityException("Unable to find app for caller "
6494                        + caller
6495                        + " when granting permission to uri " + grantUri);
6496            }
6497            if (targetPkg == null) {
6498                throw new IllegalArgumentException("null target");
6499            }
6500            if (grantUri == null) {
6501                throw new IllegalArgumentException("null uri");
6502            }
6503
6504            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6505                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6506                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6507                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6508
6509            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6510        }
6511    }
6512
6513    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6514        if (perm.modeFlags == 0) {
6515            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6516                    perm.targetUid);
6517            if (perms != null) {
6518                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6519                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6520
6521                perms.remove(perm.uri);
6522                if (perms.isEmpty()) {
6523                    mGrantedUriPermissions.remove(perm.targetUid);
6524                }
6525            }
6526        }
6527    }
6528
6529    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6530        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6531
6532        final IPackageManager pm = AppGlobals.getPackageManager();
6533        final String authority = grantUri.uri.getAuthority();
6534        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6535        if (pi == null) {
6536            Slog.w(TAG, "No content provider found for permission revoke: "
6537                    + grantUri.toSafeString());
6538            return;
6539        }
6540
6541        // Does the caller have this permission on the URI?
6542        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6543            // Right now, if you are not the original owner of the permission,
6544            // you are not allowed to revoke it.
6545            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6546                throw new SecurityException("Uid " + callingUid
6547                        + " does not have permission to uri " + grantUri);
6548            //}
6549        }
6550
6551        boolean persistChanged = false;
6552
6553        // Go through all of the permissions and remove any that match.
6554        int N = mGrantedUriPermissions.size();
6555        for (int i = 0; i < N; i++) {
6556            final int targetUid = mGrantedUriPermissions.keyAt(i);
6557            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6558
6559            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6560                final UriPermission perm = it.next();
6561                if (perm.uri.sourceUserId == grantUri.sourceUserId
6562                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6563                    if (DEBUG_URI_PERMISSION)
6564                        Slog.v(TAG,
6565                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6566                    persistChanged |= perm.revokeModes(
6567                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6568                    if (perm.modeFlags == 0) {
6569                        it.remove();
6570                    }
6571                }
6572            }
6573
6574            if (perms.isEmpty()) {
6575                mGrantedUriPermissions.remove(targetUid);
6576                N--;
6577                i--;
6578            }
6579        }
6580
6581        if (persistChanged) {
6582            schedulePersistUriGrants();
6583        }
6584    }
6585
6586    @Override
6587    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6588            int userId) {
6589        enforceNotIsolatedCaller("revokeUriPermission");
6590        synchronized(this) {
6591            final ProcessRecord r = getRecordForAppLocked(caller);
6592            if (r == null) {
6593                throw new SecurityException("Unable to find app for caller "
6594                        + caller
6595                        + " when revoking permission to uri " + uri);
6596            }
6597            if (uri == null) {
6598                Slog.w(TAG, "revokeUriPermission: null uri");
6599                return;
6600            }
6601
6602            if (!Intent.isAccessUriMode(modeFlags)) {
6603                return;
6604            }
6605
6606            final IPackageManager pm = AppGlobals.getPackageManager();
6607            final String authority = uri.getAuthority();
6608            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6609            if (pi == null) {
6610                Slog.w(TAG, "No content provider found for permission revoke: "
6611                        + uri.toSafeString());
6612                return;
6613            }
6614
6615            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6616        }
6617    }
6618
6619    /**
6620     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6621     * given package.
6622     *
6623     * @param packageName Package name to match, or {@code null} to apply to all
6624     *            packages.
6625     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6626     *            to all users.
6627     * @param persistable If persistable grants should be removed.
6628     */
6629    private void removeUriPermissionsForPackageLocked(
6630            String packageName, int userHandle, boolean persistable) {
6631        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6632            throw new IllegalArgumentException("Must narrow by either package or user");
6633        }
6634
6635        boolean persistChanged = false;
6636
6637        int N = mGrantedUriPermissions.size();
6638        for (int i = 0; i < N; i++) {
6639            final int targetUid = mGrantedUriPermissions.keyAt(i);
6640            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6641
6642            // Only inspect grants matching user
6643            if (userHandle == UserHandle.USER_ALL
6644                    || userHandle == UserHandle.getUserId(targetUid)) {
6645                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6646                    final UriPermission perm = it.next();
6647
6648                    // Only inspect grants matching package
6649                    if (packageName == null || perm.sourcePkg.equals(packageName)
6650                            || perm.targetPkg.equals(packageName)) {
6651                        persistChanged |= perm.revokeModes(
6652                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6653
6654                        // Only remove when no modes remain; any persisted grants
6655                        // will keep this alive.
6656                        if (perm.modeFlags == 0) {
6657                            it.remove();
6658                        }
6659                    }
6660                }
6661
6662                if (perms.isEmpty()) {
6663                    mGrantedUriPermissions.remove(targetUid);
6664                    N--;
6665                    i--;
6666                }
6667            }
6668        }
6669
6670        if (persistChanged) {
6671            schedulePersistUriGrants();
6672        }
6673    }
6674
6675    @Override
6676    public IBinder newUriPermissionOwner(String name) {
6677        enforceNotIsolatedCaller("newUriPermissionOwner");
6678        synchronized(this) {
6679            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6680            return owner.getExternalTokenLocked();
6681        }
6682    }
6683
6684    @Override
6685    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6686            final int modeFlags, int userId) {
6687        synchronized(this) {
6688            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6689            if (owner == null) {
6690                throw new IllegalArgumentException("Unknown owner: " + token);
6691            }
6692            if (fromUid != Binder.getCallingUid()) {
6693                if (Binder.getCallingUid() != Process.myUid()) {
6694                    // Only system code can grant URI permissions on behalf
6695                    // of other users.
6696                    throw new SecurityException("nice try");
6697                }
6698            }
6699            if (targetPkg == null) {
6700                throw new IllegalArgumentException("null target");
6701            }
6702            if (uri == null) {
6703                throw new IllegalArgumentException("null uri");
6704            }
6705
6706            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6707                    modeFlags, owner);
6708        }
6709    }
6710
6711    @Override
6712    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6713        synchronized(this) {
6714            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6715            if (owner == null) {
6716                throw new IllegalArgumentException("Unknown owner: " + token);
6717            }
6718
6719            if (uri == null) {
6720                owner.removeUriPermissionsLocked(mode);
6721            } else {
6722                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6723            }
6724        }
6725    }
6726
6727    private void schedulePersistUriGrants() {
6728        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6729            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6730                    10 * DateUtils.SECOND_IN_MILLIS);
6731        }
6732    }
6733
6734    private void writeGrantedUriPermissions() {
6735        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6736
6737        // Snapshot permissions so we can persist without lock
6738        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6739        synchronized (this) {
6740            final int size = mGrantedUriPermissions.size();
6741            for (int i = 0; i < size; i++) {
6742                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6743                for (UriPermission perm : perms.values()) {
6744                    if (perm.persistedModeFlags != 0) {
6745                        persist.add(perm.snapshot());
6746                    }
6747                }
6748            }
6749        }
6750
6751        FileOutputStream fos = null;
6752        try {
6753            fos = mGrantFile.startWrite();
6754
6755            XmlSerializer out = new FastXmlSerializer();
6756            out.setOutput(fos, "utf-8");
6757            out.startDocument(null, true);
6758            out.startTag(null, TAG_URI_GRANTS);
6759            for (UriPermission.Snapshot perm : persist) {
6760                out.startTag(null, TAG_URI_GRANT);
6761                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6762                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6763                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6764                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6765                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6766                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6767                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6768                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6769                out.endTag(null, TAG_URI_GRANT);
6770            }
6771            out.endTag(null, TAG_URI_GRANTS);
6772            out.endDocument();
6773
6774            mGrantFile.finishWrite(fos);
6775        } catch (IOException e) {
6776            if (fos != null) {
6777                mGrantFile.failWrite(fos);
6778            }
6779        }
6780    }
6781
6782    private void readGrantedUriPermissionsLocked() {
6783        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6784
6785        final long now = System.currentTimeMillis();
6786
6787        FileInputStream fis = null;
6788        try {
6789            fis = mGrantFile.openRead();
6790            final XmlPullParser in = Xml.newPullParser();
6791            in.setInput(fis, null);
6792
6793            int type;
6794            while ((type = in.next()) != END_DOCUMENT) {
6795                final String tag = in.getName();
6796                if (type == START_TAG) {
6797                    if (TAG_URI_GRANT.equals(tag)) {
6798                        final int sourceUserId;
6799                        final int targetUserId;
6800                        final int userHandle = readIntAttribute(in,
6801                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6802                        if (userHandle != UserHandle.USER_NULL) {
6803                            // For backwards compatibility.
6804                            sourceUserId = userHandle;
6805                            targetUserId = userHandle;
6806                        } else {
6807                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6808                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6809                        }
6810                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6811                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6812                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6813                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6814                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6815                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6816
6817                        // Sanity check that provider still belongs to source package
6818                        final ProviderInfo pi = getProviderInfoLocked(
6819                                uri.getAuthority(), sourceUserId);
6820                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6821                            int targetUid = -1;
6822                            try {
6823                                targetUid = AppGlobals.getPackageManager()
6824                                        .getPackageUid(targetPkg, targetUserId);
6825                            } catch (RemoteException e) {
6826                            }
6827                            if (targetUid != -1) {
6828                                final UriPermission perm = findOrCreateUriPermissionLocked(
6829                                        sourcePkg, targetPkg, targetUid,
6830                                        new GrantUri(sourceUserId, uri, prefix));
6831                                perm.initPersistedModes(modeFlags, createdTime);
6832                            }
6833                        } else {
6834                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6835                                    + " but instead found " + pi);
6836                        }
6837                    }
6838                }
6839            }
6840        } catch (FileNotFoundException e) {
6841            // Missing grants is okay
6842        } catch (IOException e) {
6843            Log.wtf(TAG, "Failed reading Uri grants", e);
6844        } catch (XmlPullParserException e) {
6845            Log.wtf(TAG, "Failed reading Uri grants", e);
6846        } finally {
6847            IoUtils.closeQuietly(fis);
6848        }
6849    }
6850
6851    @Override
6852    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6853        enforceNotIsolatedCaller("takePersistableUriPermission");
6854
6855        Preconditions.checkFlagsArgument(modeFlags,
6856                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6857
6858        synchronized (this) {
6859            final int callingUid = Binder.getCallingUid();
6860            boolean persistChanged = false;
6861            GrantUri grantUri = new GrantUri(userId, uri, false);
6862
6863            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6864                    new GrantUri(userId, uri, false));
6865            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6866                    new GrantUri(userId, uri, true));
6867
6868            final boolean exactValid = (exactPerm != null)
6869                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6870            final boolean prefixValid = (prefixPerm != null)
6871                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6872
6873            if (!(exactValid || prefixValid)) {
6874                throw new SecurityException("No persistable permission grants found for UID "
6875                        + callingUid + " and Uri " + grantUri.toSafeString());
6876            }
6877
6878            if (exactValid) {
6879                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6880            }
6881            if (prefixValid) {
6882                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6883            }
6884
6885            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6886
6887            if (persistChanged) {
6888                schedulePersistUriGrants();
6889            }
6890        }
6891    }
6892
6893    @Override
6894    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6895        enforceNotIsolatedCaller("releasePersistableUriPermission");
6896
6897        Preconditions.checkFlagsArgument(modeFlags,
6898                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6899
6900        synchronized (this) {
6901            final int callingUid = Binder.getCallingUid();
6902            boolean persistChanged = false;
6903
6904            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6905                    new GrantUri(userId, uri, false));
6906            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6907                    new GrantUri(userId, uri, true));
6908            if (exactPerm == null && prefixPerm == null) {
6909                throw new SecurityException("No permission grants found for UID " + callingUid
6910                        + " and Uri " + uri.toSafeString());
6911            }
6912
6913            if (exactPerm != null) {
6914                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6915                removeUriPermissionIfNeededLocked(exactPerm);
6916            }
6917            if (prefixPerm != null) {
6918                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6919                removeUriPermissionIfNeededLocked(prefixPerm);
6920            }
6921
6922            if (persistChanged) {
6923                schedulePersistUriGrants();
6924            }
6925        }
6926    }
6927
6928    /**
6929     * Prune any older {@link UriPermission} for the given UID until outstanding
6930     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6931     *
6932     * @return if any mutations occured that require persisting.
6933     */
6934    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6935        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6936        if (perms == null) return false;
6937        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6938
6939        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6940        for (UriPermission perm : perms.values()) {
6941            if (perm.persistedModeFlags != 0) {
6942                persisted.add(perm);
6943            }
6944        }
6945
6946        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6947        if (trimCount <= 0) return false;
6948
6949        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6950        for (int i = 0; i < trimCount; i++) {
6951            final UriPermission perm = persisted.get(i);
6952
6953            if (DEBUG_URI_PERMISSION) {
6954                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6955            }
6956
6957            perm.releasePersistableModes(~0);
6958            removeUriPermissionIfNeededLocked(perm);
6959        }
6960
6961        return true;
6962    }
6963
6964    @Override
6965    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6966            String packageName, boolean incoming) {
6967        enforceNotIsolatedCaller("getPersistedUriPermissions");
6968        Preconditions.checkNotNull(packageName, "packageName");
6969
6970        final int callingUid = Binder.getCallingUid();
6971        final IPackageManager pm = AppGlobals.getPackageManager();
6972        try {
6973            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6974            if (packageUid != callingUid) {
6975                throw new SecurityException(
6976                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6977            }
6978        } catch (RemoteException e) {
6979            throw new SecurityException("Failed to verify package name ownership");
6980        }
6981
6982        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6983        synchronized (this) {
6984            if (incoming) {
6985                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6986                        callingUid);
6987                if (perms == null) {
6988                    Slog.w(TAG, "No permission grants found for " + packageName);
6989                } else {
6990                    for (UriPermission perm : perms.values()) {
6991                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6992                            result.add(perm.buildPersistedPublicApiObject());
6993                        }
6994                    }
6995                }
6996            } else {
6997                final int size = mGrantedUriPermissions.size();
6998                for (int i = 0; i < size; i++) {
6999                    final ArrayMap<GrantUri, UriPermission> perms =
7000                            mGrantedUriPermissions.valueAt(i);
7001                    for (UriPermission perm : perms.values()) {
7002                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7003                            result.add(perm.buildPersistedPublicApiObject());
7004                        }
7005                    }
7006                }
7007            }
7008        }
7009        return new ParceledListSlice<android.content.UriPermission>(result);
7010    }
7011
7012    @Override
7013    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7014        synchronized (this) {
7015            ProcessRecord app =
7016                who != null ? getRecordForAppLocked(who) : null;
7017            if (app == null) return;
7018
7019            Message msg = Message.obtain();
7020            msg.what = WAIT_FOR_DEBUGGER_MSG;
7021            msg.obj = app;
7022            msg.arg1 = waiting ? 1 : 0;
7023            mHandler.sendMessage(msg);
7024        }
7025    }
7026
7027    @Override
7028    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7029        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7030        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7031        outInfo.availMem = Process.getFreeMemory();
7032        outInfo.totalMem = Process.getTotalMemory();
7033        outInfo.threshold = homeAppMem;
7034        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7035        outInfo.hiddenAppThreshold = cachedAppMem;
7036        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7037                ProcessList.SERVICE_ADJ);
7038        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7039                ProcessList.VISIBLE_APP_ADJ);
7040        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7041                ProcessList.FOREGROUND_APP_ADJ);
7042    }
7043
7044    // =========================================================
7045    // TASK MANAGEMENT
7046    // =========================================================
7047
7048    @Override
7049    public List<IAppTask> getAppTasks() {
7050        int callingUid = Binder.getCallingUid();
7051        long ident = Binder.clearCallingIdentity();
7052        synchronized(this) {
7053            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7054            try {
7055                if (localLOGV) Slog.v(TAG, "getAppTasks");
7056
7057                final int N = mRecentTasks.size();
7058                for (int i = 0; i < N; i++) {
7059                    TaskRecord tr = mRecentTasks.get(i);
7060                    // Skip tasks that are not created by the caller
7061                    if (tr.creatorUid == callingUid) {
7062                        ActivityManager.RecentTaskInfo taskInfo =
7063                                createRecentTaskInfoFromTaskRecord(tr);
7064                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7065                        list.add(taskImpl);
7066                    }
7067                }
7068            } finally {
7069                Binder.restoreCallingIdentity(ident);
7070            }
7071            return list;
7072        }
7073    }
7074
7075    @Override
7076    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7077        final int callingUid = Binder.getCallingUid();
7078        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7079
7080        synchronized(this) {
7081            if (localLOGV) Slog.v(
7082                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7083
7084            final boolean allowed = checkCallingPermission(
7085                    android.Manifest.permission.GET_TASKS)
7086                    == PackageManager.PERMISSION_GRANTED;
7087            if (!allowed) {
7088                Slog.w(TAG, "getTasks: caller " + callingUid
7089                        + " does not hold GET_TASKS; limiting output");
7090            }
7091
7092            // TODO: Improve with MRU list from all ActivityStacks.
7093            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7094        }
7095
7096        return list;
7097    }
7098
7099    TaskRecord getMostRecentTask() {
7100        return mRecentTasks.get(0);
7101    }
7102
7103    /**
7104     * Creates a new RecentTaskInfo from a TaskRecord.
7105     */
7106    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7107        // Update the task description to reflect any changes in the task stack
7108        tr.updateTaskDescription();
7109
7110        // Compose the recent task info
7111        ActivityManager.RecentTaskInfo rti
7112                = new ActivityManager.RecentTaskInfo();
7113        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7114        rti.persistentId = tr.taskId;
7115        rti.baseIntent = new Intent(tr.getBaseIntent());
7116        rti.origActivity = tr.origActivity;
7117        rti.description = tr.lastDescription;
7118        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7119        rti.userId = tr.userId;
7120        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7121        return rti;
7122    }
7123
7124    @Override
7125    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7126            int flags, int userId) {
7127        final int callingUid = Binder.getCallingUid();
7128        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7129                false, true, "getRecentTasks", null);
7130
7131        synchronized (this) {
7132            final boolean allowed = checkCallingPermission(
7133                    android.Manifest.permission.GET_TASKS)
7134                    == PackageManager.PERMISSION_GRANTED;
7135            if (!allowed) {
7136                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7137                        + " does not hold GET_TASKS; limiting output");
7138            }
7139            final boolean detailed = checkCallingPermission(
7140                    android.Manifest.permission.GET_DETAILED_TASKS)
7141                    == PackageManager.PERMISSION_GRANTED;
7142
7143            IPackageManager pm = AppGlobals.getPackageManager();
7144
7145            final int N = mRecentTasks.size();
7146            ArrayList<ActivityManager.RecentTaskInfo> res
7147                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7148                            maxNum < N ? maxNum : N);
7149
7150            final Set<Integer> includedUsers;
7151            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7152                includedUsers = getProfileIdsLocked(userId);
7153            } else {
7154                includedUsers = new HashSet<Integer>();
7155            }
7156            includedUsers.add(Integer.valueOf(userId));
7157            for (int i=0; i<N && maxNum > 0; i++) {
7158                TaskRecord tr = mRecentTasks.get(i);
7159                // Only add calling user or related users recent tasks
7160                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7161
7162                // Return the entry if desired by the caller.  We always return
7163                // the first entry, because callers always expect this to be the
7164                // foreground app.  We may filter others if the caller has
7165                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7166                // we should exclude the entry.
7167
7168                if (i == 0
7169                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7170                        || (tr.intent == null)
7171                        || ((tr.intent.getFlags()
7172                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7173                    if (!allowed) {
7174                        // If the caller doesn't have the GET_TASKS permission, then only
7175                        // allow them to see a small subset of tasks -- their own and home.
7176                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7177                            continue;
7178                        }
7179                    }
7180
7181                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7182                    if (!detailed) {
7183                        rti.baseIntent.replaceExtras((Bundle)null);
7184                    }
7185
7186                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7187                        // Check whether this activity is currently available.
7188                        try {
7189                            if (rti.origActivity != null) {
7190                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7191                                        == null) {
7192                                    continue;
7193                                }
7194                            } else if (rti.baseIntent != null) {
7195                                if (pm.queryIntentActivities(rti.baseIntent,
7196                                        null, 0, userId) == null) {
7197                                    continue;
7198                                }
7199                            }
7200                        } catch (RemoteException e) {
7201                            // Will never happen.
7202                        }
7203                    }
7204
7205                    res.add(rti);
7206                    maxNum--;
7207                }
7208            }
7209            return res;
7210        }
7211    }
7212
7213    private TaskRecord recentTaskForIdLocked(int id) {
7214        final int N = mRecentTasks.size();
7215            for (int i=0; i<N; i++) {
7216                TaskRecord tr = mRecentTasks.get(i);
7217                if (tr.taskId == id) {
7218                    return tr;
7219                }
7220            }
7221            return null;
7222    }
7223
7224    @Override
7225    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7226        synchronized (this) {
7227            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7228                    "getTaskThumbnails()");
7229            TaskRecord tr = recentTaskForIdLocked(id);
7230            if (tr != null) {
7231                return tr.getTaskThumbnailsLocked();
7232            }
7233        }
7234        return null;
7235    }
7236
7237    @Override
7238    public Bitmap getTaskTopThumbnail(int id) {
7239        synchronized (this) {
7240            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7241                    "getTaskTopThumbnail()");
7242            TaskRecord tr = recentTaskForIdLocked(id);
7243            if (tr != null) {
7244                return tr.getTaskTopThumbnailLocked();
7245            }
7246        }
7247        return null;
7248    }
7249
7250    @Override
7251    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7252        synchronized (this) {
7253            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7254            if (r != null) {
7255                r.taskDescription = td;
7256                r.task.updateTaskDescription();
7257            }
7258        }
7259    }
7260
7261    @Override
7262    public boolean removeSubTask(int taskId, int subTaskIndex) {
7263        synchronized (this) {
7264            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7265                    "removeSubTask()");
7266            long ident = Binder.clearCallingIdentity();
7267            try {
7268                TaskRecord tr = recentTaskForIdLocked(taskId);
7269                if (tr != null) {
7270                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7271                }
7272                return false;
7273            } finally {
7274                Binder.restoreCallingIdentity(ident);
7275            }
7276        }
7277    }
7278
7279    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7280        if (!pr.killedByAm) {
7281            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7282            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7283                    pr.processName, pr.setAdj, reason);
7284            pr.killedByAm = true;
7285            Process.killProcessQuiet(pr.pid);
7286        }
7287    }
7288
7289    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7290        tr.disposeThumbnail();
7291        mRecentTasks.remove(tr);
7292        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7293        Intent baseIntent = new Intent(
7294                tr.intent != null ? tr.intent : tr.affinityIntent);
7295        ComponentName component = baseIntent.getComponent();
7296        if (component == null) {
7297            Slog.w(TAG, "Now component for base intent of task: " + tr);
7298            return;
7299        }
7300
7301        // Find any running services associated with this app.
7302        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7303
7304        if (killProcesses) {
7305            // Find any running processes associated with this app.
7306            final String pkg = component.getPackageName();
7307            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7308            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7309            for (int i=0; i<pmap.size(); i++) {
7310                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7311                for (int j=0; j<uids.size(); j++) {
7312                    ProcessRecord proc = uids.valueAt(j);
7313                    if (proc.userId != tr.userId) {
7314                        continue;
7315                    }
7316                    if (!proc.pkgList.containsKey(pkg)) {
7317                        continue;
7318                    }
7319                    procs.add(proc);
7320                }
7321            }
7322
7323            // Kill the running processes.
7324            for (int i=0; i<procs.size(); i++) {
7325                ProcessRecord pr = procs.get(i);
7326                if (pr == mHomeProcess) {
7327                    // Don't kill the home process along with tasks from the same package.
7328                    continue;
7329                }
7330                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7331                    killUnneededProcessLocked(pr, "remove task");
7332                } else {
7333                    pr.waitingToKill = "remove task";
7334                }
7335            }
7336        }
7337    }
7338
7339    /**
7340     * Removes the task with the specified task id.
7341     *
7342     * @param taskId Identifier of the task to be removed.
7343     * @param flags Additional operational flags.  May be 0 or
7344     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7345     * @return Returns true if the given task was found and removed.
7346     */
7347    private boolean removeTaskByIdLocked(int taskId, int flags) {
7348        TaskRecord tr = recentTaskForIdLocked(taskId);
7349        if (tr != null) {
7350            tr.removeTaskActivitiesLocked(-1, false);
7351            cleanUpRemovedTaskLocked(tr, flags);
7352            if (tr.isPersistable) {
7353                notifyTaskPersisterLocked(tr, true);
7354            }
7355            return true;
7356        }
7357        return false;
7358    }
7359
7360    @Override
7361    public boolean removeTask(int taskId, int flags) {
7362        synchronized (this) {
7363            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7364                    "removeTask()");
7365            long ident = Binder.clearCallingIdentity();
7366            try {
7367                return removeTaskByIdLocked(taskId, flags);
7368            } finally {
7369                Binder.restoreCallingIdentity(ident);
7370            }
7371        }
7372    }
7373
7374    /**
7375     * TODO: Add mController hook
7376     */
7377    @Override
7378    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7379        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7380                "moveTaskToFront()");
7381
7382        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7383        synchronized(this) {
7384            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7385                    Binder.getCallingUid(), "Task to front")) {
7386                ActivityOptions.abort(options);
7387                return;
7388            }
7389            final long origId = Binder.clearCallingIdentity();
7390            try {
7391                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7392                if (task == null) {
7393                    return;
7394                }
7395                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7396                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7397                    return;
7398                }
7399                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7400            } finally {
7401                Binder.restoreCallingIdentity(origId);
7402            }
7403            ActivityOptions.abort(options);
7404        }
7405    }
7406
7407    @Override
7408    public void moveTaskToBack(int taskId) {
7409        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7410                "moveTaskToBack()");
7411
7412        synchronized(this) {
7413            TaskRecord tr = recentTaskForIdLocked(taskId);
7414            if (tr != null) {
7415                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7416                ActivityStack stack = tr.stack;
7417                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7418                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7419                            Binder.getCallingUid(), "Task to back")) {
7420                        return;
7421                    }
7422                }
7423                final long origId = Binder.clearCallingIdentity();
7424                try {
7425                    stack.moveTaskToBackLocked(taskId, null);
7426                } finally {
7427                    Binder.restoreCallingIdentity(origId);
7428                }
7429            }
7430        }
7431    }
7432
7433    /**
7434     * Moves an activity, and all of the other activities within the same task, to the bottom
7435     * of the history stack.  The activity's order within the task is unchanged.
7436     *
7437     * @param token A reference to the activity we wish to move
7438     * @param nonRoot If false then this only works if the activity is the root
7439     *                of a task; if true it will work for any activity in a task.
7440     * @return Returns true if the move completed, false if not.
7441     */
7442    @Override
7443    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7444        enforceNotIsolatedCaller("moveActivityTaskToBack");
7445        synchronized(this) {
7446            final long origId = Binder.clearCallingIdentity();
7447            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7448            if (taskId >= 0) {
7449                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7450            }
7451            Binder.restoreCallingIdentity(origId);
7452        }
7453        return false;
7454    }
7455
7456    @Override
7457    public void moveTaskBackwards(int task) {
7458        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7459                "moveTaskBackwards()");
7460
7461        synchronized(this) {
7462            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7463                    Binder.getCallingUid(), "Task backwards")) {
7464                return;
7465            }
7466            final long origId = Binder.clearCallingIdentity();
7467            moveTaskBackwardsLocked(task);
7468            Binder.restoreCallingIdentity(origId);
7469        }
7470    }
7471
7472    private final void moveTaskBackwardsLocked(int task) {
7473        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7474    }
7475
7476    @Override
7477    public IBinder getHomeActivityToken() throws RemoteException {
7478        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7479                "getHomeActivityToken()");
7480        synchronized (this) {
7481            return mStackSupervisor.getHomeActivityToken();
7482        }
7483    }
7484
7485    @Override
7486    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7487            IActivityContainerCallback callback) throws RemoteException {
7488        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7489                "createActivityContainer()");
7490        synchronized (this) {
7491            if (parentActivityToken == null) {
7492                throw new IllegalArgumentException("parent token must not be null");
7493            }
7494            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7495            if (r == null) {
7496                return null;
7497            }
7498            if (callback == null) {
7499                throw new IllegalArgumentException("callback must not be null");
7500            }
7501            return mStackSupervisor.createActivityContainer(r, callback);
7502        }
7503    }
7504
7505    @Override
7506    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7507        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7508                "deleteActivityContainer()");
7509        synchronized (this) {
7510            mStackSupervisor.deleteActivityContainer(container);
7511        }
7512    }
7513
7514    @Override
7515    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7516            throws RemoteException {
7517        synchronized (this) {
7518            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7519            if (stack != null) {
7520                return stack.mActivityContainer;
7521            }
7522            return null;
7523        }
7524    }
7525
7526    @Override
7527    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7528        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7529                "moveTaskToStack()");
7530        if (stackId == HOME_STACK_ID) {
7531            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7532                    new RuntimeException("here").fillInStackTrace());
7533        }
7534        synchronized (this) {
7535            long ident = Binder.clearCallingIdentity();
7536            try {
7537                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7538                        + stackId + " toTop=" + toTop);
7539                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7540            } finally {
7541                Binder.restoreCallingIdentity(ident);
7542            }
7543        }
7544    }
7545
7546    @Override
7547    public void resizeStack(int stackBoxId, Rect bounds) {
7548        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7549                "resizeStackBox()");
7550        long ident = Binder.clearCallingIdentity();
7551        try {
7552            mWindowManager.resizeStack(stackBoxId, bounds);
7553        } finally {
7554            Binder.restoreCallingIdentity(ident);
7555        }
7556    }
7557
7558    @Override
7559    public List<StackInfo> getAllStackInfos() {
7560        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7561                "getAllStackInfos()");
7562        long ident = Binder.clearCallingIdentity();
7563        try {
7564            synchronized (this) {
7565                return mStackSupervisor.getAllStackInfosLocked();
7566            }
7567        } finally {
7568            Binder.restoreCallingIdentity(ident);
7569        }
7570    }
7571
7572    @Override
7573    public StackInfo getStackInfo(int stackId) {
7574        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7575                "getStackInfo()");
7576        long ident = Binder.clearCallingIdentity();
7577        try {
7578            synchronized (this) {
7579                return mStackSupervisor.getStackInfoLocked(stackId);
7580            }
7581        } finally {
7582            Binder.restoreCallingIdentity(ident);
7583        }
7584    }
7585
7586    @Override
7587    public boolean isInHomeStack(int taskId) {
7588        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7589                "getStackInfo()");
7590        long ident = Binder.clearCallingIdentity();
7591        try {
7592            synchronized (this) {
7593                TaskRecord tr = recentTaskForIdLocked(taskId);
7594                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7595            }
7596        } finally {
7597            Binder.restoreCallingIdentity(ident);
7598        }
7599    }
7600
7601    @Override
7602    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7603        synchronized(this) {
7604            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7605        }
7606    }
7607
7608    private boolean isLockTaskAuthorized(ComponentName name) {
7609        final DevicePolicyManager dpm = (DevicePolicyManager)
7610                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7611        return dpm != null && dpm.isLockTaskPermitted(name);
7612    }
7613
7614    private void startLockTaskMode(TaskRecord task) {
7615        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7616            return;
7617        }
7618        long ident = Binder.clearCallingIdentity();
7619        try {
7620            synchronized (this) {
7621                // Since we lost lock on task, make sure it is still there.
7622                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7623                if (task != null) {
7624                    mStackSupervisor.setLockTaskModeLocked(task);
7625                }
7626            }
7627        } finally {
7628            Binder.restoreCallingIdentity(ident);
7629        }
7630    }
7631
7632    @Override
7633    public void startLockTaskMode(int taskId) {
7634        long ident = Binder.clearCallingIdentity();
7635        try {
7636            final TaskRecord task;
7637            synchronized (this) {
7638                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7639            }
7640            if (task != null) {
7641                startLockTaskMode(task);
7642            }
7643        } finally {
7644            Binder.restoreCallingIdentity(ident);
7645        }
7646    }
7647
7648    @Override
7649    public void startLockTaskMode(IBinder token) {
7650        long ident = Binder.clearCallingIdentity();
7651        try {
7652            final TaskRecord task;
7653            synchronized (this) {
7654                final ActivityRecord r = ActivityRecord.forToken(token);
7655                if (r == null) {
7656                    return;
7657                }
7658                task = r.task;
7659            }
7660            if (task != null) {
7661                startLockTaskMode(task);
7662            }
7663        } finally {
7664            Binder.restoreCallingIdentity(ident);
7665        }
7666    }
7667
7668    @Override
7669    public void stopLockTaskMode() {
7670        // Check if the calling task is eligible to use lock task
7671        final int uid = Binder.getCallingUid();
7672        try {
7673            final String name = AppGlobals.getPackageManager().getNameForUid(uid);
7674            if (!isLockTaskAuthorized(new ComponentName(name, name))) {
7675                return;
7676            }
7677        } catch (RemoteException e) {
7678            Log.d(TAG, "stopLockTaskMode " + e);
7679            return;
7680        }
7681        // Stop lock task
7682        synchronized (this) {
7683            mStackSupervisor.setLockTaskModeLocked(null);
7684        }
7685    }
7686
7687    @Override
7688    public boolean isInLockTaskMode() {
7689        synchronized (this) {
7690            return mStackSupervisor.isInLockTaskMode();
7691        }
7692    }
7693
7694    // =========================================================
7695    // CONTENT PROVIDERS
7696    // =========================================================
7697
7698    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7699        List<ProviderInfo> providers = null;
7700        try {
7701            providers = AppGlobals.getPackageManager().
7702                queryContentProviders(app.processName, app.uid,
7703                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7704        } catch (RemoteException ex) {
7705        }
7706        if (DEBUG_MU)
7707            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7708        int userId = app.userId;
7709        if (providers != null) {
7710            int N = providers.size();
7711            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7712            for (int i=0; i<N; i++) {
7713                ProviderInfo cpi =
7714                    (ProviderInfo)providers.get(i);
7715                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7716                        cpi.name, cpi.flags);
7717                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7718                    // This is a singleton provider, but a user besides the
7719                    // default user is asking to initialize a process it runs
7720                    // in...  well, no, it doesn't actually run in this process,
7721                    // it runs in the process of the default user.  Get rid of it.
7722                    providers.remove(i);
7723                    N--;
7724                    i--;
7725                    continue;
7726                }
7727
7728                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7729                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7730                if (cpr == null) {
7731                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7732                    mProviderMap.putProviderByClass(comp, cpr);
7733                }
7734                if (DEBUG_MU)
7735                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7736                app.pubProviders.put(cpi.name, cpr);
7737                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7738                    // Don't add this if it is a platform component that is marked
7739                    // to run in multiple processes, because this is actually
7740                    // part of the framework so doesn't make sense to track as a
7741                    // separate apk in the process.
7742                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7743                }
7744                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7745            }
7746        }
7747        return providers;
7748    }
7749
7750    /**
7751     * Check if {@link ProcessRecord} has a possible chance at accessing the
7752     * given {@link ProviderInfo}. Final permission checking is always done
7753     * in {@link ContentProvider}.
7754     */
7755    private final String checkContentProviderPermissionLocked(
7756            ProviderInfo cpi, ProcessRecord r, int userId) {
7757        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7758        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7759        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7760        // Looking for cross-user grants before to enforce the typical cross-users permissions
7761        if (userId != UserHandle.getUserId(callingUid)) {
7762            if (perms != null) {
7763                for (GrantUri grantUri : perms.keySet()) {
7764                    if (grantUri.sourceUserId == userId) {
7765                        String authority = grantUri.uri.getAuthority();
7766                        if (authority.equals(cpi.authority)) {
7767                            return null;
7768                        }
7769                    }
7770                }
7771            }
7772        }
7773        userId = handleIncomingUser(callingPid, callingUid, userId,
7774                false, true, "checkContentProviderPermissionLocked", null);
7775        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7776                cpi.applicationInfo.uid, cpi.exported)
7777                == PackageManager.PERMISSION_GRANTED) {
7778            return null;
7779        }
7780        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7781                cpi.applicationInfo.uid, cpi.exported)
7782                == PackageManager.PERMISSION_GRANTED) {
7783            return null;
7784        }
7785
7786        PathPermission[] pps = cpi.pathPermissions;
7787        if (pps != null) {
7788            int i = pps.length;
7789            while (i > 0) {
7790                i--;
7791                PathPermission pp = pps[i];
7792                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7793                        cpi.applicationInfo.uid, cpi.exported)
7794                        == PackageManager.PERMISSION_GRANTED) {
7795                    return null;
7796                }
7797                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7798                        cpi.applicationInfo.uid, cpi.exported)
7799                        == PackageManager.PERMISSION_GRANTED) {
7800                    return null;
7801                }
7802            }
7803        }
7804
7805        if (perms != null) {
7806            for (GrantUri grantUri : perms.keySet()) {
7807                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7808                    return null;
7809                }
7810            }
7811        }
7812
7813        String msg;
7814        if (!cpi.exported) {
7815            msg = "Permission Denial: opening provider " + cpi.name
7816                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7817                    + ", uid=" + callingUid + ") that is not exported from uid "
7818                    + cpi.applicationInfo.uid;
7819        } else {
7820            msg = "Permission Denial: opening provider " + cpi.name
7821                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7822                    + ", uid=" + callingUid + ") requires "
7823                    + cpi.readPermission + " or " + cpi.writePermission;
7824        }
7825        Slog.w(TAG, msg);
7826        return msg;
7827    }
7828
7829    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7830            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7831        if (r != null) {
7832            for (int i=0; i<r.conProviders.size(); i++) {
7833                ContentProviderConnection conn = r.conProviders.get(i);
7834                if (conn.provider == cpr) {
7835                    if (DEBUG_PROVIDER) Slog.v(TAG,
7836                            "Adding provider requested by "
7837                            + r.processName + " from process "
7838                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7839                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7840                    if (stable) {
7841                        conn.stableCount++;
7842                        conn.numStableIncs++;
7843                    } else {
7844                        conn.unstableCount++;
7845                        conn.numUnstableIncs++;
7846                    }
7847                    return conn;
7848                }
7849            }
7850            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7851            if (stable) {
7852                conn.stableCount = 1;
7853                conn.numStableIncs = 1;
7854            } else {
7855                conn.unstableCount = 1;
7856                conn.numUnstableIncs = 1;
7857            }
7858            cpr.connections.add(conn);
7859            r.conProviders.add(conn);
7860            return conn;
7861        }
7862        cpr.addExternalProcessHandleLocked(externalProcessToken);
7863        return null;
7864    }
7865
7866    boolean decProviderCountLocked(ContentProviderConnection conn,
7867            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7868        if (conn != null) {
7869            cpr = conn.provider;
7870            if (DEBUG_PROVIDER) Slog.v(TAG,
7871                    "Removing provider requested by "
7872                    + conn.client.processName + " from process "
7873                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7874                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7875            if (stable) {
7876                conn.stableCount--;
7877            } else {
7878                conn.unstableCount--;
7879            }
7880            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7881                cpr.connections.remove(conn);
7882                conn.client.conProviders.remove(conn);
7883                return true;
7884            }
7885            return false;
7886        }
7887        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7888        return false;
7889    }
7890
7891    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7892            String name, IBinder token, boolean stable, int userId) {
7893        ContentProviderRecord cpr;
7894        ContentProviderConnection conn = null;
7895        ProviderInfo cpi = null;
7896
7897        synchronized(this) {
7898            ProcessRecord r = null;
7899            if (caller != null) {
7900                r = getRecordForAppLocked(caller);
7901                if (r == null) {
7902                    throw new SecurityException(
7903                            "Unable to find app for caller " + caller
7904                          + " (pid=" + Binder.getCallingPid()
7905                          + ") when getting content provider " + name);
7906                }
7907            }
7908
7909            // First check if this content provider has been published...
7910            cpr = mProviderMap.getProviderByName(name, userId);
7911            boolean providerRunning = cpr != null;
7912            if (providerRunning) {
7913                cpi = cpr.info;
7914                String msg;
7915                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7916                    throw new SecurityException(msg);
7917                }
7918
7919                if (r != null && cpr.canRunHere(r)) {
7920                    // This provider has been published or is in the process
7921                    // of being published...  but it is also allowed to run
7922                    // in the caller's process, so don't make a connection
7923                    // and just let the caller instantiate its own instance.
7924                    ContentProviderHolder holder = cpr.newHolder(null);
7925                    // don't give caller the provider object, it needs
7926                    // to make its own.
7927                    holder.provider = null;
7928                    return holder;
7929                }
7930
7931                final long origId = Binder.clearCallingIdentity();
7932
7933                // In this case the provider instance already exists, so we can
7934                // return it right away.
7935                conn = incProviderCountLocked(r, cpr, token, stable);
7936                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7937                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7938                        // If this is a perceptible app accessing the provider,
7939                        // make sure to count it as being accessed and thus
7940                        // back up on the LRU list.  This is good because
7941                        // content providers are often expensive to start.
7942                        updateLruProcessLocked(cpr.proc, false, null);
7943                    }
7944                }
7945
7946                if (cpr.proc != null) {
7947                    if (false) {
7948                        if (cpr.name.flattenToShortString().equals(
7949                                "com.android.providers.calendar/.CalendarProvider2")) {
7950                            Slog.v(TAG, "****************** KILLING "
7951                                + cpr.name.flattenToShortString());
7952                            Process.killProcess(cpr.proc.pid);
7953                        }
7954                    }
7955                    boolean success = updateOomAdjLocked(cpr.proc);
7956                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7957                    // NOTE: there is still a race here where a signal could be
7958                    // pending on the process even though we managed to update its
7959                    // adj level.  Not sure what to do about this, but at least
7960                    // the race is now smaller.
7961                    if (!success) {
7962                        // Uh oh...  it looks like the provider's process
7963                        // has been killed on us.  We need to wait for a new
7964                        // process to be started, and make sure its death
7965                        // doesn't kill our process.
7966                        Slog.i(TAG,
7967                                "Existing provider " + cpr.name.flattenToShortString()
7968                                + " is crashing; detaching " + r);
7969                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7970                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7971                        if (!lastRef) {
7972                            // This wasn't the last ref our process had on
7973                            // the provider...  we have now been killed, bail.
7974                            return null;
7975                        }
7976                        providerRunning = false;
7977                        conn = null;
7978                    }
7979                }
7980
7981                Binder.restoreCallingIdentity(origId);
7982            }
7983
7984            boolean singleton;
7985            if (!providerRunning) {
7986                try {
7987                    cpi = AppGlobals.getPackageManager().
7988                        resolveContentProvider(name,
7989                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7990                } catch (RemoteException ex) {
7991                }
7992                if (cpi == null) {
7993                    return null;
7994                }
7995                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7996                        cpi.name, cpi.flags);
7997                if (singleton) {
7998                    userId = 0;
7999                }
8000                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8001
8002                String msg;
8003                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
8004                    throw new SecurityException(msg);
8005                }
8006
8007                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8008                        && !cpi.processName.equals("system")) {
8009                    // If this content provider does not run in the system
8010                    // process, and the system is not yet ready to run other
8011                    // processes, then fail fast instead of hanging.
8012                    throw new IllegalArgumentException(
8013                            "Attempt to launch content provider before system ready");
8014                }
8015
8016                // Make sure that the user who owns this provider is started.  If not,
8017                // we don't want to allow it to run.
8018                if (mStartedUsers.get(userId) == null) {
8019                    Slog.w(TAG, "Unable to launch app "
8020                            + cpi.applicationInfo.packageName + "/"
8021                            + cpi.applicationInfo.uid + " for provider "
8022                            + name + ": user " + userId + " is stopped");
8023                    return null;
8024                }
8025
8026                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8027                cpr = mProviderMap.getProviderByClass(comp, userId);
8028                final boolean firstClass = cpr == null;
8029                if (firstClass) {
8030                    try {
8031                        ApplicationInfo ai =
8032                            AppGlobals.getPackageManager().
8033                                getApplicationInfo(
8034                                        cpi.applicationInfo.packageName,
8035                                        STOCK_PM_FLAGS, userId);
8036                        if (ai == null) {
8037                            Slog.w(TAG, "No package info for content provider "
8038                                    + cpi.name);
8039                            return null;
8040                        }
8041                        ai = getAppInfoForUser(ai, userId);
8042                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8043                    } catch (RemoteException ex) {
8044                        // pm is in same process, this will never happen.
8045                    }
8046                }
8047
8048                if (r != null && cpr.canRunHere(r)) {
8049                    // If this is a multiprocess provider, then just return its
8050                    // info and allow the caller to instantiate it.  Only do
8051                    // this if the provider is the same user as the caller's
8052                    // process, or can run as root (so can be in any process).
8053                    return cpr.newHolder(null);
8054                }
8055
8056                if (DEBUG_PROVIDER) {
8057                    RuntimeException e = new RuntimeException("here");
8058                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8059                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8060                }
8061
8062                // This is single process, and our app is now connecting to it.
8063                // See if we are already in the process of launching this
8064                // provider.
8065                final int N = mLaunchingProviders.size();
8066                int i;
8067                for (i=0; i<N; i++) {
8068                    if (mLaunchingProviders.get(i) == cpr) {
8069                        break;
8070                    }
8071                }
8072
8073                // If the provider is not already being launched, then get it
8074                // started.
8075                if (i >= N) {
8076                    final long origId = Binder.clearCallingIdentity();
8077
8078                    try {
8079                        // Content provider is now in use, its package can't be stopped.
8080                        try {
8081                            AppGlobals.getPackageManager().setPackageStoppedState(
8082                                    cpr.appInfo.packageName, false, userId);
8083                        } catch (RemoteException e) {
8084                        } catch (IllegalArgumentException e) {
8085                            Slog.w(TAG, "Failed trying to unstop package "
8086                                    + cpr.appInfo.packageName + ": " + e);
8087                        }
8088
8089                        // Use existing process if already started
8090                        ProcessRecord proc = getProcessRecordLocked(
8091                                cpi.processName, cpr.appInfo.uid, false);
8092                        if (proc != null && proc.thread != null) {
8093                            if (DEBUG_PROVIDER) {
8094                                Slog.d(TAG, "Installing in existing process " + proc);
8095                            }
8096                            proc.pubProviders.put(cpi.name, cpr);
8097                            try {
8098                                proc.thread.scheduleInstallProvider(cpi);
8099                            } catch (RemoteException e) {
8100                            }
8101                        } else {
8102                            proc = startProcessLocked(cpi.processName,
8103                                    cpr.appInfo, false, 0, "content provider",
8104                                    new ComponentName(cpi.applicationInfo.packageName,
8105                                            cpi.name), false, false, false);
8106                            if (proc == null) {
8107                                Slog.w(TAG, "Unable to launch app "
8108                                        + cpi.applicationInfo.packageName + "/"
8109                                        + cpi.applicationInfo.uid + " for provider "
8110                                        + name + ": process is bad");
8111                                return null;
8112                            }
8113                        }
8114                        cpr.launchingApp = proc;
8115                        mLaunchingProviders.add(cpr);
8116                    } finally {
8117                        Binder.restoreCallingIdentity(origId);
8118                    }
8119                }
8120
8121                // Make sure the provider is published (the same provider class
8122                // may be published under multiple names).
8123                if (firstClass) {
8124                    mProviderMap.putProviderByClass(comp, cpr);
8125                }
8126
8127                mProviderMap.putProviderByName(name, cpr);
8128                conn = incProviderCountLocked(r, cpr, token, stable);
8129                if (conn != null) {
8130                    conn.waiting = true;
8131                }
8132            }
8133        }
8134
8135        // Wait for the provider to be published...
8136        synchronized (cpr) {
8137            while (cpr.provider == null) {
8138                if (cpr.launchingApp == null) {
8139                    Slog.w(TAG, "Unable to launch app "
8140                            + cpi.applicationInfo.packageName + "/"
8141                            + cpi.applicationInfo.uid + " for provider "
8142                            + name + ": launching app became null");
8143                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8144                            UserHandle.getUserId(cpi.applicationInfo.uid),
8145                            cpi.applicationInfo.packageName,
8146                            cpi.applicationInfo.uid, name);
8147                    return null;
8148                }
8149                try {
8150                    if (DEBUG_MU) {
8151                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8152                                + cpr.launchingApp);
8153                    }
8154                    if (conn != null) {
8155                        conn.waiting = true;
8156                    }
8157                    cpr.wait();
8158                } catch (InterruptedException ex) {
8159                } finally {
8160                    if (conn != null) {
8161                        conn.waiting = false;
8162                    }
8163                }
8164            }
8165        }
8166        return cpr != null ? cpr.newHolder(conn) : null;
8167    }
8168
8169    @Override
8170    public final ContentProviderHolder getContentProvider(
8171            IApplicationThread caller, String name, int userId, boolean stable) {
8172        enforceNotIsolatedCaller("getContentProvider");
8173        if (caller == null) {
8174            String msg = "null IApplicationThread when getting content provider "
8175                    + name;
8176            Slog.w(TAG, msg);
8177            throw new SecurityException(msg);
8178        }
8179        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8180        // with cross-user grant.
8181        return getContentProviderImpl(caller, name, null, stable, userId);
8182    }
8183
8184    public ContentProviderHolder getContentProviderExternal(
8185            String name, int userId, IBinder token) {
8186        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8187            "Do not have permission in call getContentProviderExternal()");
8188        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8189                false, true, "getContentProvider", null);
8190        return getContentProviderExternalUnchecked(name, token, userId);
8191    }
8192
8193    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8194            IBinder token, int userId) {
8195        return getContentProviderImpl(null, name, token, true, userId);
8196    }
8197
8198    /**
8199     * Drop a content provider from a ProcessRecord's bookkeeping
8200     */
8201    public void removeContentProvider(IBinder connection, boolean stable) {
8202        enforceNotIsolatedCaller("removeContentProvider");
8203        long ident = Binder.clearCallingIdentity();
8204        try {
8205            synchronized (this) {
8206                ContentProviderConnection conn;
8207                try {
8208                    conn = (ContentProviderConnection)connection;
8209                } catch (ClassCastException e) {
8210                    String msg ="removeContentProvider: " + connection
8211                            + " not a ContentProviderConnection";
8212                    Slog.w(TAG, msg);
8213                    throw new IllegalArgumentException(msg);
8214                }
8215                if (conn == null) {
8216                    throw new NullPointerException("connection is null");
8217                }
8218                if (decProviderCountLocked(conn, null, null, stable)) {
8219                    updateOomAdjLocked();
8220                }
8221            }
8222        } finally {
8223            Binder.restoreCallingIdentity(ident);
8224        }
8225    }
8226
8227    public void removeContentProviderExternal(String name, IBinder token) {
8228        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8229            "Do not have permission in call removeContentProviderExternal()");
8230        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8231    }
8232
8233    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8234        synchronized (this) {
8235            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8236            if(cpr == null) {
8237                //remove from mProvidersByClass
8238                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8239                return;
8240            }
8241
8242            //update content provider record entry info
8243            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8244            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8245            if (localCpr.hasExternalProcessHandles()) {
8246                if (localCpr.removeExternalProcessHandleLocked(token)) {
8247                    updateOomAdjLocked();
8248                } else {
8249                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8250                            + " with no external reference for token: "
8251                            + token + ".");
8252                }
8253            } else {
8254                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8255                        + " with no external references.");
8256            }
8257        }
8258    }
8259
8260    public final void publishContentProviders(IApplicationThread caller,
8261            List<ContentProviderHolder> providers) {
8262        if (providers == null) {
8263            return;
8264        }
8265
8266        enforceNotIsolatedCaller("publishContentProviders");
8267        synchronized (this) {
8268            final ProcessRecord r = getRecordForAppLocked(caller);
8269            if (DEBUG_MU)
8270                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8271            if (r == null) {
8272                throw new SecurityException(
8273                        "Unable to find app for caller " + caller
8274                      + " (pid=" + Binder.getCallingPid()
8275                      + ") when publishing content providers");
8276            }
8277
8278            final long origId = Binder.clearCallingIdentity();
8279
8280            final int N = providers.size();
8281            for (int i=0; i<N; i++) {
8282                ContentProviderHolder src = providers.get(i);
8283                if (src == null || src.info == null || src.provider == null) {
8284                    continue;
8285                }
8286                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8287                if (DEBUG_MU)
8288                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8289                if (dst != null) {
8290                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8291                    mProviderMap.putProviderByClass(comp, dst);
8292                    String names[] = dst.info.authority.split(";");
8293                    for (int j = 0; j < names.length; j++) {
8294                        mProviderMap.putProviderByName(names[j], dst);
8295                    }
8296
8297                    int NL = mLaunchingProviders.size();
8298                    int j;
8299                    for (j=0; j<NL; j++) {
8300                        if (mLaunchingProviders.get(j) == dst) {
8301                            mLaunchingProviders.remove(j);
8302                            j--;
8303                            NL--;
8304                        }
8305                    }
8306                    synchronized (dst) {
8307                        dst.provider = src.provider;
8308                        dst.proc = r;
8309                        dst.notifyAll();
8310                    }
8311                    updateOomAdjLocked(r);
8312                }
8313            }
8314
8315            Binder.restoreCallingIdentity(origId);
8316        }
8317    }
8318
8319    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8320        ContentProviderConnection conn;
8321        try {
8322            conn = (ContentProviderConnection)connection;
8323        } catch (ClassCastException e) {
8324            String msg ="refContentProvider: " + connection
8325                    + " not a ContentProviderConnection";
8326            Slog.w(TAG, msg);
8327            throw new IllegalArgumentException(msg);
8328        }
8329        if (conn == null) {
8330            throw new NullPointerException("connection is null");
8331        }
8332
8333        synchronized (this) {
8334            if (stable > 0) {
8335                conn.numStableIncs += stable;
8336            }
8337            stable = conn.stableCount + stable;
8338            if (stable < 0) {
8339                throw new IllegalStateException("stableCount < 0: " + stable);
8340            }
8341
8342            if (unstable > 0) {
8343                conn.numUnstableIncs += unstable;
8344            }
8345            unstable = conn.unstableCount + unstable;
8346            if (unstable < 0) {
8347                throw new IllegalStateException("unstableCount < 0: " + unstable);
8348            }
8349
8350            if ((stable+unstable) <= 0) {
8351                throw new IllegalStateException("ref counts can't go to zero here: stable="
8352                        + stable + " unstable=" + unstable);
8353            }
8354            conn.stableCount = stable;
8355            conn.unstableCount = unstable;
8356            return !conn.dead;
8357        }
8358    }
8359
8360    public void unstableProviderDied(IBinder connection) {
8361        ContentProviderConnection conn;
8362        try {
8363            conn = (ContentProviderConnection)connection;
8364        } catch (ClassCastException e) {
8365            String msg ="refContentProvider: " + connection
8366                    + " not a ContentProviderConnection";
8367            Slog.w(TAG, msg);
8368            throw new IllegalArgumentException(msg);
8369        }
8370        if (conn == null) {
8371            throw new NullPointerException("connection is null");
8372        }
8373
8374        // Safely retrieve the content provider associated with the connection.
8375        IContentProvider provider;
8376        synchronized (this) {
8377            provider = conn.provider.provider;
8378        }
8379
8380        if (provider == null) {
8381            // Um, yeah, we're way ahead of you.
8382            return;
8383        }
8384
8385        // Make sure the caller is being honest with us.
8386        if (provider.asBinder().pingBinder()) {
8387            // Er, no, still looks good to us.
8388            synchronized (this) {
8389                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8390                        + " says " + conn + " died, but we don't agree");
8391                return;
8392            }
8393        }
8394
8395        // Well look at that!  It's dead!
8396        synchronized (this) {
8397            if (conn.provider.provider != provider) {
8398                // But something changed...  good enough.
8399                return;
8400            }
8401
8402            ProcessRecord proc = conn.provider.proc;
8403            if (proc == null || proc.thread == null) {
8404                // Seems like the process is already cleaned up.
8405                return;
8406            }
8407
8408            // As far as we're concerned, this is just like receiving a
8409            // death notification...  just a bit prematurely.
8410            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8411                    + ") early provider death");
8412            final long ident = Binder.clearCallingIdentity();
8413            try {
8414                appDiedLocked(proc, proc.pid, proc.thread);
8415            } finally {
8416                Binder.restoreCallingIdentity(ident);
8417            }
8418        }
8419    }
8420
8421    @Override
8422    public void appNotRespondingViaProvider(IBinder connection) {
8423        enforceCallingPermission(
8424                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8425
8426        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8427        if (conn == null) {
8428            Slog.w(TAG, "ContentProviderConnection is null");
8429            return;
8430        }
8431
8432        final ProcessRecord host = conn.provider.proc;
8433        if (host == null) {
8434            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8435            return;
8436        }
8437
8438        final long token = Binder.clearCallingIdentity();
8439        try {
8440            appNotResponding(host, null, null, false, "ContentProvider not responding");
8441        } finally {
8442            Binder.restoreCallingIdentity(token);
8443        }
8444    }
8445
8446    public final void installSystemProviders() {
8447        List<ProviderInfo> providers;
8448        synchronized (this) {
8449            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8450            providers = generateApplicationProvidersLocked(app);
8451            if (providers != null) {
8452                for (int i=providers.size()-1; i>=0; i--) {
8453                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8454                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8455                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8456                                + ": not system .apk");
8457                        providers.remove(i);
8458                    }
8459                }
8460            }
8461        }
8462        if (providers != null) {
8463            mSystemThread.installSystemProviders(providers);
8464        }
8465
8466        mCoreSettingsObserver = new CoreSettingsObserver(this);
8467
8468        mUsageStatsService.monitorPackages();
8469    }
8470
8471    /**
8472     * Allows app to retrieve the MIME type of a URI without having permission
8473     * to access its content provider.
8474     *
8475     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8476     *
8477     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8478     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8479     */
8480    public String getProviderMimeType(Uri uri, int userId) {
8481        enforceNotIsolatedCaller("getProviderMimeType");
8482        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8483                userId, false, true, "getProviderMimeType", null);
8484        final String name = uri.getAuthority();
8485        final long ident = Binder.clearCallingIdentity();
8486        ContentProviderHolder holder = null;
8487
8488        try {
8489            holder = getContentProviderExternalUnchecked(name, null, userId);
8490            if (holder != null) {
8491                return holder.provider.getType(uri);
8492            }
8493        } catch (RemoteException e) {
8494            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8495            return null;
8496        } finally {
8497            if (holder != null) {
8498                removeContentProviderExternalUnchecked(name, null, userId);
8499            }
8500            Binder.restoreCallingIdentity(ident);
8501        }
8502
8503        return null;
8504    }
8505
8506    // =========================================================
8507    // GLOBAL MANAGEMENT
8508    // =========================================================
8509
8510    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8511            boolean isolated) {
8512        String proc = customProcess != null ? customProcess : info.processName;
8513        BatteryStatsImpl.Uid.Proc ps = null;
8514        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8515        int uid = info.uid;
8516        if (isolated) {
8517            int userId = UserHandle.getUserId(uid);
8518            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8519            while (true) {
8520                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8521                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8522                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8523                }
8524                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8525                mNextIsolatedProcessUid++;
8526                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8527                    // No process for this uid, use it.
8528                    break;
8529                }
8530                stepsLeft--;
8531                if (stepsLeft <= 0) {
8532                    return null;
8533                }
8534            }
8535        }
8536        return new ProcessRecord(stats, info, proc, uid);
8537    }
8538
8539    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8540        ProcessRecord app;
8541        if (!isolated) {
8542            app = getProcessRecordLocked(info.processName, info.uid, true);
8543        } else {
8544            app = null;
8545        }
8546
8547        if (app == null) {
8548            app = newProcessRecordLocked(info, null, isolated);
8549            mProcessNames.put(info.processName, app.uid, app);
8550            if (isolated) {
8551                mIsolatedProcesses.put(app.uid, app);
8552            }
8553            updateLruProcessLocked(app, false, null);
8554            updateOomAdjLocked();
8555        }
8556
8557        // This package really, really can not be stopped.
8558        try {
8559            AppGlobals.getPackageManager().setPackageStoppedState(
8560                    info.packageName, false, UserHandle.getUserId(app.uid));
8561        } catch (RemoteException e) {
8562        } catch (IllegalArgumentException e) {
8563            Slog.w(TAG, "Failed trying to unstop package "
8564                    + info.packageName + ": " + e);
8565        }
8566
8567        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8568                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8569            app.persistent = true;
8570            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8571        }
8572        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8573            mPersistentStartingProcesses.add(app);
8574            startProcessLocked(app, "added application", app.processName);
8575        }
8576
8577        return app;
8578    }
8579
8580    public void unhandledBack() {
8581        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8582                "unhandledBack()");
8583
8584        synchronized(this) {
8585            final long origId = Binder.clearCallingIdentity();
8586            try {
8587                getFocusedStack().unhandledBackLocked();
8588            } finally {
8589                Binder.restoreCallingIdentity(origId);
8590            }
8591        }
8592    }
8593
8594    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8595        enforceNotIsolatedCaller("openContentUri");
8596        final int userId = UserHandle.getCallingUserId();
8597        String name = uri.getAuthority();
8598        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8599        ParcelFileDescriptor pfd = null;
8600        if (cph != null) {
8601            // We record the binder invoker's uid in thread-local storage before
8602            // going to the content provider to open the file.  Later, in the code
8603            // that handles all permissions checks, we look for this uid and use
8604            // that rather than the Activity Manager's own uid.  The effect is that
8605            // we do the check against the caller's permissions even though it looks
8606            // to the content provider like the Activity Manager itself is making
8607            // the request.
8608            sCallerIdentity.set(new Identity(
8609                    Binder.getCallingPid(), Binder.getCallingUid()));
8610            try {
8611                pfd = cph.provider.openFile(null, uri, "r", null);
8612            } catch (FileNotFoundException e) {
8613                // do nothing; pfd will be returned null
8614            } finally {
8615                // Ensure that whatever happens, we clean up the identity state
8616                sCallerIdentity.remove();
8617            }
8618
8619            // We've got the fd now, so we're done with the provider.
8620            removeContentProviderExternalUnchecked(name, null, userId);
8621        } else {
8622            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8623        }
8624        return pfd;
8625    }
8626
8627    // Actually is sleeping or shutting down or whatever else in the future
8628    // is an inactive state.
8629    public boolean isSleepingOrShuttingDown() {
8630        return mSleeping || mShuttingDown;
8631    }
8632
8633    public boolean isSleeping() {
8634        return mSleeping;
8635    }
8636
8637    void goingToSleep() {
8638        synchronized(this) {
8639            mWentToSleep = true;
8640            updateEventDispatchingLocked();
8641            goToSleepIfNeededLocked();
8642        }
8643    }
8644
8645    void finishRunningVoiceLocked() {
8646        if (mRunningVoice) {
8647            mRunningVoice = false;
8648            goToSleepIfNeededLocked();
8649        }
8650    }
8651
8652    void goToSleepIfNeededLocked() {
8653        if (mWentToSleep && !mRunningVoice) {
8654            if (!mSleeping) {
8655                mSleeping = true;
8656                mStackSupervisor.goingToSleepLocked();
8657
8658                // Initialize the wake times of all processes.
8659                checkExcessivePowerUsageLocked(false);
8660                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8661                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8662                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8663            }
8664        }
8665    }
8666
8667    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8668        mTaskPersister.notify(task, flush);
8669    }
8670
8671    @Override
8672    public boolean shutdown(int timeout) {
8673        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8674                != PackageManager.PERMISSION_GRANTED) {
8675            throw new SecurityException("Requires permission "
8676                    + android.Manifest.permission.SHUTDOWN);
8677        }
8678
8679        boolean timedout = false;
8680
8681        synchronized(this) {
8682            mShuttingDown = true;
8683            updateEventDispatchingLocked();
8684            timedout = mStackSupervisor.shutdownLocked(timeout);
8685        }
8686
8687        mAppOpsService.shutdown();
8688        mUsageStatsService.shutdown();
8689        mBatteryStatsService.shutdown();
8690        synchronized (this) {
8691            mProcessStats.shutdownLocked();
8692        }
8693        notifyTaskPersisterLocked(null, true);
8694
8695        return timedout;
8696    }
8697
8698    public final void activitySlept(IBinder token) {
8699        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8700
8701        final long origId = Binder.clearCallingIdentity();
8702
8703        synchronized (this) {
8704            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8705            if (r != null) {
8706                mStackSupervisor.activitySleptLocked(r);
8707            }
8708        }
8709
8710        Binder.restoreCallingIdentity(origId);
8711    }
8712
8713    void logLockScreen(String msg) {
8714        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8715                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8716                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8717                mStackSupervisor.mDismissKeyguardOnNextActivity);
8718    }
8719
8720    private void comeOutOfSleepIfNeededLocked() {
8721        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8722            if (mSleeping) {
8723                mSleeping = false;
8724                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8725            }
8726        }
8727    }
8728
8729    void wakingUp() {
8730        synchronized(this) {
8731            mWentToSleep = false;
8732            updateEventDispatchingLocked();
8733            comeOutOfSleepIfNeededLocked();
8734        }
8735    }
8736
8737    void startRunningVoiceLocked() {
8738        if (!mRunningVoice) {
8739            mRunningVoice = true;
8740            comeOutOfSleepIfNeededLocked();
8741        }
8742    }
8743
8744    private void updateEventDispatchingLocked() {
8745        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8746    }
8747
8748    public void setLockScreenShown(boolean shown) {
8749        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8750                != PackageManager.PERMISSION_GRANTED) {
8751            throw new SecurityException("Requires permission "
8752                    + android.Manifest.permission.DEVICE_POWER);
8753        }
8754
8755        synchronized(this) {
8756            long ident = Binder.clearCallingIdentity();
8757            try {
8758                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8759                mLockScreenShown = shown;
8760                comeOutOfSleepIfNeededLocked();
8761            } finally {
8762                Binder.restoreCallingIdentity(ident);
8763            }
8764        }
8765    }
8766
8767    public void stopAppSwitches() {
8768        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8769                != PackageManager.PERMISSION_GRANTED) {
8770            throw new SecurityException("Requires permission "
8771                    + android.Manifest.permission.STOP_APP_SWITCHES);
8772        }
8773
8774        synchronized(this) {
8775            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8776                    + APP_SWITCH_DELAY_TIME;
8777            mDidAppSwitch = false;
8778            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8779            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8780            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8781        }
8782    }
8783
8784    public void resumeAppSwitches() {
8785        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8786                != PackageManager.PERMISSION_GRANTED) {
8787            throw new SecurityException("Requires permission "
8788                    + android.Manifest.permission.STOP_APP_SWITCHES);
8789        }
8790
8791        synchronized(this) {
8792            // Note that we don't execute any pending app switches... we will
8793            // let those wait until either the timeout, or the next start
8794            // activity request.
8795            mAppSwitchesAllowedTime = 0;
8796        }
8797    }
8798
8799    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8800            String name) {
8801        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8802            return true;
8803        }
8804
8805        final int perm = checkComponentPermission(
8806                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8807                callingUid, -1, true);
8808        if (perm == PackageManager.PERMISSION_GRANTED) {
8809            return true;
8810        }
8811
8812        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8813        return false;
8814    }
8815
8816    public void setDebugApp(String packageName, boolean waitForDebugger,
8817            boolean persistent) {
8818        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8819                "setDebugApp()");
8820
8821        long ident = Binder.clearCallingIdentity();
8822        try {
8823            // Note that this is not really thread safe if there are multiple
8824            // callers into it at the same time, but that's not a situation we
8825            // care about.
8826            if (persistent) {
8827                final ContentResolver resolver = mContext.getContentResolver();
8828                Settings.Global.putString(
8829                    resolver, Settings.Global.DEBUG_APP,
8830                    packageName);
8831                Settings.Global.putInt(
8832                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8833                    waitForDebugger ? 1 : 0);
8834            }
8835
8836            synchronized (this) {
8837                if (!persistent) {
8838                    mOrigDebugApp = mDebugApp;
8839                    mOrigWaitForDebugger = mWaitForDebugger;
8840                }
8841                mDebugApp = packageName;
8842                mWaitForDebugger = waitForDebugger;
8843                mDebugTransient = !persistent;
8844                if (packageName != null) {
8845                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8846                            false, UserHandle.USER_ALL, "set debug app");
8847                }
8848            }
8849        } finally {
8850            Binder.restoreCallingIdentity(ident);
8851        }
8852    }
8853
8854    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8855        synchronized (this) {
8856            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8857            if (!isDebuggable) {
8858                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8859                    throw new SecurityException("Process not debuggable: " + app.packageName);
8860                }
8861            }
8862
8863            mOpenGlTraceApp = processName;
8864        }
8865    }
8866
8867    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8868            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8869        synchronized (this) {
8870            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8871            if (!isDebuggable) {
8872                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8873                    throw new SecurityException("Process not debuggable: " + app.packageName);
8874                }
8875            }
8876            mProfileApp = processName;
8877            mProfileFile = profileFile;
8878            if (mProfileFd != null) {
8879                try {
8880                    mProfileFd.close();
8881                } catch (IOException e) {
8882                }
8883                mProfileFd = null;
8884            }
8885            mProfileFd = profileFd;
8886            mProfileType = 0;
8887            mAutoStopProfiler = autoStopProfiler;
8888        }
8889    }
8890
8891    @Override
8892    public void setAlwaysFinish(boolean enabled) {
8893        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8894                "setAlwaysFinish()");
8895
8896        Settings.Global.putInt(
8897                mContext.getContentResolver(),
8898                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8899
8900        synchronized (this) {
8901            mAlwaysFinishActivities = enabled;
8902        }
8903    }
8904
8905    @Override
8906    public void setActivityController(IActivityController controller) {
8907        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8908                "setActivityController()");
8909        synchronized (this) {
8910            mController = controller;
8911            Watchdog.getInstance().setActivityController(controller);
8912        }
8913    }
8914
8915    @Override
8916    public void setUserIsMonkey(boolean userIsMonkey) {
8917        synchronized (this) {
8918            synchronized (mPidsSelfLocked) {
8919                final int callingPid = Binder.getCallingPid();
8920                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8921                if (precessRecord == null) {
8922                    throw new SecurityException("Unknown process: " + callingPid);
8923                }
8924                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8925                    throw new SecurityException("Only an instrumentation process "
8926                            + "with a UiAutomation can call setUserIsMonkey");
8927                }
8928            }
8929            mUserIsMonkey = userIsMonkey;
8930        }
8931    }
8932
8933    @Override
8934    public boolean isUserAMonkey() {
8935        synchronized (this) {
8936            // If there is a controller also implies the user is a monkey.
8937            return (mUserIsMonkey || mController != null);
8938        }
8939    }
8940
8941    public void requestBugReport() {
8942        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8943        SystemProperties.set("ctl.start", "bugreport");
8944    }
8945
8946    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8947        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8948    }
8949
8950    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8951        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8952            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8953        }
8954        return KEY_DISPATCHING_TIMEOUT;
8955    }
8956
8957    @Override
8958    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8959        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8960                != PackageManager.PERMISSION_GRANTED) {
8961            throw new SecurityException("Requires permission "
8962                    + android.Manifest.permission.FILTER_EVENTS);
8963        }
8964        ProcessRecord proc;
8965        long timeout;
8966        synchronized (this) {
8967            synchronized (mPidsSelfLocked) {
8968                proc = mPidsSelfLocked.get(pid);
8969            }
8970            timeout = getInputDispatchingTimeoutLocked(proc);
8971        }
8972
8973        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8974            return -1;
8975        }
8976
8977        return timeout;
8978    }
8979
8980    /**
8981     * Handle input dispatching timeouts.
8982     * Returns whether input dispatching should be aborted or not.
8983     */
8984    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8985            final ActivityRecord activity, final ActivityRecord parent,
8986            final boolean aboveSystem, String reason) {
8987        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8988                != PackageManager.PERMISSION_GRANTED) {
8989            throw new SecurityException("Requires permission "
8990                    + android.Manifest.permission.FILTER_EVENTS);
8991        }
8992
8993        final String annotation;
8994        if (reason == null) {
8995            annotation = "Input dispatching timed out";
8996        } else {
8997            annotation = "Input dispatching timed out (" + reason + ")";
8998        }
8999
9000        if (proc != null) {
9001            synchronized (this) {
9002                if (proc.debugging) {
9003                    return false;
9004                }
9005
9006                if (mDidDexOpt) {
9007                    // Give more time since we were dexopting.
9008                    mDidDexOpt = false;
9009                    return false;
9010                }
9011
9012                if (proc.instrumentationClass != null) {
9013                    Bundle info = new Bundle();
9014                    info.putString("shortMsg", "keyDispatchingTimedOut");
9015                    info.putString("longMsg", annotation);
9016                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9017                    return true;
9018                }
9019            }
9020            mHandler.post(new Runnable() {
9021                @Override
9022                public void run() {
9023                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9024                }
9025            });
9026        }
9027
9028        return true;
9029    }
9030
9031    public Bundle getAssistContextExtras(int requestType) {
9032        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9033                "getAssistContextExtras()");
9034        PendingAssistExtras pae;
9035        Bundle extras = new Bundle();
9036        synchronized (this) {
9037            ActivityRecord activity = getFocusedStack().mResumedActivity;
9038            if (activity == null) {
9039                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9040                return null;
9041            }
9042            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9043            if (activity.app == null || activity.app.thread == null) {
9044                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9045                return extras;
9046            }
9047            if (activity.app.pid == Binder.getCallingPid()) {
9048                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9049                return extras;
9050            }
9051            pae = new PendingAssistExtras(activity);
9052            try {
9053                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9054                        requestType);
9055                mPendingAssistExtras.add(pae);
9056                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9057            } catch (RemoteException e) {
9058                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9059                return extras;
9060            }
9061        }
9062        synchronized (pae) {
9063            while (!pae.haveResult) {
9064                try {
9065                    pae.wait();
9066                } catch (InterruptedException e) {
9067                }
9068            }
9069            if (pae.result != null) {
9070                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9071            }
9072        }
9073        synchronized (this) {
9074            mPendingAssistExtras.remove(pae);
9075            mHandler.removeCallbacks(pae);
9076        }
9077        return extras;
9078    }
9079
9080    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9081        PendingAssistExtras pae = (PendingAssistExtras)token;
9082        synchronized (pae) {
9083            pae.result = extras;
9084            pae.haveResult = true;
9085            pae.notifyAll();
9086        }
9087    }
9088
9089    public void registerProcessObserver(IProcessObserver observer) {
9090        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9091                "registerProcessObserver()");
9092        synchronized (this) {
9093            mProcessObservers.register(observer);
9094        }
9095    }
9096
9097    @Override
9098    public void unregisterProcessObserver(IProcessObserver observer) {
9099        synchronized (this) {
9100            mProcessObservers.unregister(observer);
9101        }
9102    }
9103
9104    @Override
9105    public boolean convertFromTranslucent(IBinder token) {
9106        final long origId = Binder.clearCallingIdentity();
9107        try {
9108            synchronized (this) {
9109                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9110                if (r == null) {
9111                    return false;
9112                }
9113                if (r.changeWindowTranslucency(true)) {
9114                    mWindowManager.setAppFullscreen(token, true);
9115                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9116                    return true;
9117                }
9118                return false;
9119            }
9120        } finally {
9121            Binder.restoreCallingIdentity(origId);
9122        }
9123    }
9124
9125    @Override
9126    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9127        final long origId = Binder.clearCallingIdentity();
9128        try {
9129            synchronized (this) {
9130                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9131                if (r == null) {
9132                    return false;
9133                }
9134                if (r.changeWindowTranslucency(false)) {
9135                    r.task.stack.convertToTranslucent(r, options);
9136                    mWindowManager.setAppFullscreen(token, false);
9137                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9138                    return true;
9139                }
9140                return false;
9141            }
9142        } finally {
9143            Binder.restoreCallingIdentity(origId);
9144        }
9145    }
9146
9147    @Override
9148    public ActivityOptions getActivityOptions(IBinder token) {
9149        final long origId = Binder.clearCallingIdentity();
9150        try {
9151            synchronized (this) {
9152                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9153                if (r != null) {
9154                    final ActivityOptions activityOptions = r.pendingOptions;
9155                    r.pendingOptions = null;
9156                    return activityOptions;
9157                }
9158                return null;
9159            }
9160        } finally {
9161            Binder.restoreCallingIdentity(origId);
9162        }
9163    }
9164
9165    @Override
9166    public void setImmersive(IBinder token, boolean immersive) {
9167        synchronized(this) {
9168            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9169            if (r == null) {
9170                throw new IllegalArgumentException();
9171            }
9172            r.immersive = immersive;
9173
9174            // update associated state if we're frontmost
9175            if (r == mFocusedActivity) {
9176                if (DEBUG_IMMERSIVE) {
9177                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9178                }
9179                applyUpdateLockStateLocked(r);
9180            }
9181        }
9182    }
9183
9184    @Override
9185    public boolean isImmersive(IBinder token) {
9186        synchronized (this) {
9187            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9188            if (r == null) {
9189                throw new IllegalArgumentException();
9190            }
9191            return r.immersive;
9192        }
9193    }
9194
9195    public boolean isTopActivityImmersive() {
9196        enforceNotIsolatedCaller("startActivity");
9197        synchronized (this) {
9198            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9199            return (r != null) ? r.immersive : false;
9200        }
9201    }
9202
9203    public final void enterSafeMode() {
9204        synchronized(this) {
9205            // It only makes sense to do this before the system is ready
9206            // and started launching other packages.
9207            if (!mSystemReady) {
9208                try {
9209                    AppGlobals.getPackageManager().enterSafeMode();
9210                } catch (RemoteException e) {
9211                }
9212            }
9213
9214            mSafeMode = true;
9215        }
9216    }
9217
9218    public final void showSafeModeOverlay() {
9219        View v = LayoutInflater.from(mContext).inflate(
9220                com.android.internal.R.layout.safe_mode, null);
9221        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9222        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9223        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9224        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9225        lp.gravity = Gravity.BOTTOM | Gravity.START;
9226        lp.format = v.getBackground().getOpacity();
9227        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9228                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9229        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9230        ((WindowManager)mContext.getSystemService(
9231                Context.WINDOW_SERVICE)).addView(v, lp);
9232    }
9233
9234    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9235        if (!(sender instanceof PendingIntentRecord)) {
9236            return;
9237        }
9238        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9239        synchronized (stats) {
9240            if (mBatteryStatsService.isOnBattery()) {
9241                mBatteryStatsService.enforceCallingPermission();
9242                PendingIntentRecord rec = (PendingIntentRecord)sender;
9243                int MY_UID = Binder.getCallingUid();
9244                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9245                BatteryStatsImpl.Uid.Pkg pkg =
9246                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9247                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9248                pkg.incWakeupsLocked();
9249            }
9250        }
9251    }
9252
9253    public boolean killPids(int[] pids, String pReason, boolean secure) {
9254        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9255            throw new SecurityException("killPids only available to the system");
9256        }
9257        String reason = (pReason == null) ? "Unknown" : pReason;
9258        // XXX Note: don't acquire main activity lock here, because the window
9259        // manager calls in with its locks held.
9260
9261        boolean killed = false;
9262        synchronized (mPidsSelfLocked) {
9263            int[] types = new int[pids.length];
9264            int worstType = 0;
9265            for (int i=0; i<pids.length; i++) {
9266                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9267                if (proc != null) {
9268                    int type = proc.setAdj;
9269                    types[i] = type;
9270                    if (type > worstType) {
9271                        worstType = type;
9272                    }
9273                }
9274            }
9275
9276            // If the worst oom_adj is somewhere in the cached proc LRU range,
9277            // then constrain it so we will kill all cached procs.
9278            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9279                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9280                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9281            }
9282
9283            // If this is not a secure call, don't let it kill processes that
9284            // are important.
9285            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9286                worstType = ProcessList.SERVICE_ADJ;
9287            }
9288
9289            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9290            for (int i=0; i<pids.length; i++) {
9291                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9292                if (proc == null) {
9293                    continue;
9294                }
9295                int adj = proc.setAdj;
9296                if (adj >= worstType && !proc.killedByAm) {
9297                    killUnneededProcessLocked(proc, reason);
9298                    killed = true;
9299                }
9300            }
9301        }
9302        return killed;
9303    }
9304
9305    @Override
9306    public void killUid(int uid, String reason) {
9307        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9308            throw new SecurityException("killUid only available to the system");
9309        }
9310        synchronized (this) {
9311            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9312                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9313                    reason != null ? reason : "kill uid");
9314        }
9315    }
9316
9317    @Override
9318    public boolean killProcessesBelowForeground(String reason) {
9319        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9320            throw new SecurityException("killProcessesBelowForeground() only available to system");
9321        }
9322
9323        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9324    }
9325
9326    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9327        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9328            throw new SecurityException("killProcessesBelowAdj() only available to system");
9329        }
9330
9331        boolean killed = false;
9332        synchronized (mPidsSelfLocked) {
9333            final int size = mPidsSelfLocked.size();
9334            for (int i = 0; i < size; i++) {
9335                final int pid = mPidsSelfLocked.keyAt(i);
9336                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9337                if (proc == null) continue;
9338
9339                final int adj = proc.setAdj;
9340                if (adj > belowAdj && !proc.killedByAm) {
9341                    killUnneededProcessLocked(proc, reason);
9342                    killed = true;
9343                }
9344            }
9345        }
9346        return killed;
9347    }
9348
9349    @Override
9350    public void hang(final IBinder who, boolean allowRestart) {
9351        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9352                != PackageManager.PERMISSION_GRANTED) {
9353            throw new SecurityException("Requires permission "
9354                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9355        }
9356
9357        final IBinder.DeathRecipient death = new DeathRecipient() {
9358            @Override
9359            public void binderDied() {
9360                synchronized (this) {
9361                    notifyAll();
9362                }
9363            }
9364        };
9365
9366        try {
9367            who.linkToDeath(death, 0);
9368        } catch (RemoteException e) {
9369            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9370            return;
9371        }
9372
9373        synchronized (this) {
9374            Watchdog.getInstance().setAllowRestart(allowRestart);
9375            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9376            synchronized (death) {
9377                while (who.isBinderAlive()) {
9378                    try {
9379                        death.wait();
9380                    } catch (InterruptedException e) {
9381                    }
9382                }
9383            }
9384            Watchdog.getInstance().setAllowRestart(true);
9385        }
9386    }
9387
9388    @Override
9389    public void restart() {
9390        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9391                != PackageManager.PERMISSION_GRANTED) {
9392            throw new SecurityException("Requires permission "
9393                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9394        }
9395
9396        Log.i(TAG, "Sending shutdown broadcast...");
9397
9398        BroadcastReceiver br = new BroadcastReceiver() {
9399            @Override public void onReceive(Context context, Intent intent) {
9400                // Now the broadcast is done, finish up the low-level shutdown.
9401                Log.i(TAG, "Shutting down activity manager...");
9402                shutdown(10000);
9403                Log.i(TAG, "Shutdown complete, restarting!");
9404                Process.killProcess(Process.myPid());
9405                System.exit(10);
9406            }
9407        };
9408
9409        // First send the high-level shut down broadcast.
9410        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9411        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9412        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9413        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9414        mContext.sendOrderedBroadcastAsUser(intent,
9415                UserHandle.ALL, null, br, mHandler, 0, null, null);
9416        */
9417        br.onReceive(mContext, intent);
9418    }
9419
9420    private long getLowRamTimeSinceIdle(long now) {
9421        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9422    }
9423
9424    @Override
9425    public void performIdleMaintenance() {
9426        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9427                != PackageManager.PERMISSION_GRANTED) {
9428            throw new SecurityException("Requires permission "
9429                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9430        }
9431
9432        synchronized (this) {
9433            final long now = SystemClock.uptimeMillis();
9434            final long timeSinceLastIdle = now - mLastIdleTime;
9435            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9436            mLastIdleTime = now;
9437            mLowRamTimeSinceLastIdle = 0;
9438            if (mLowRamStartTime != 0) {
9439                mLowRamStartTime = now;
9440            }
9441
9442            StringBuilder sb = new StringBuilder(128);
9443            sb.append("Idle maintenance over ");
9444            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9445            sb.append(" low RAM for ");
9446            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9447            Slog.i(TAG, sb.toString());
9448
9449            // If at least 1/3 of our time since the last idle period has been spent
9450            // with RAM low, then we want to kill processes.
9451            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9452
9453            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9454                ProcessRecord proc = mLruProcesses.get(i);
9455                if (proc.notCachedSinceIdle) {
9456                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9457                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9458                        if (doKilling && proc.initialIdlePss != 0
9459                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9460                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9461                                    + " from " + proc.initialIdlePss + ")");
9462                        }
9463                    }
9464                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9465                    proc.notCachedSinceIdle = true;
9466                    proc.initialIdlePss = 0;
9467                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9468                            isSleeping(), now);
9469                }
9470            }
9471
9472            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9473            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9474        }
9475    }
9476
9477    private void retrieveSettings() {
9478        final ContentResolver resolver = mContext.getContentResolver();
9479        String debugApp = Settings.Global.getString(
9480            resolver, Settings.Global.DEBUG_APP);
9481        boolean waitForDebugger = Settings.Global.getInt(
9482            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9483        boolean alwaysFinishActivities = Settings.Global.getInt(
9484            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9485        boolean forceRtl = Settings.Global.getInt(
9486                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9487        // Transfer any global setting for forcing RTL layout, into a System Property
9488        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9489
9490        Configuration configuration = new Configuration();
9491        Settings.System.getConfiguration(resolver, configuration);
9492        if (forceRtl) {
9493            // This will take care of setting the correct layout direction flags
9494            configuration.setLayoutDirection(configuration.locale);
9495        }
9496
9497        synchronized (this) {
9498            mDebugApp = mOrigDebugApp = debugApp;
9499            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9500            mAlwaysFinishActivities = alwaysFinishActivities;
9501            // This happens before any activities are started, so we can
9502            // change mConfiguration in-place.
9503            updateConfigurationLocked(configuration, null, false, true);
9504            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9505        }
9506    }
9507
9508    public boolean testIsSystemReady() {
9509        // no need to synchronize(this) just to read & return the value
9510        return mSystemReady;
9511    }
9512
9513    private static File getCalledPreBootReceiversFile() {
9514        File dataDir = Environment.getDataDirectory();
9515        File systemDir = new File(dataDir, "system");
9516        File fname = new File(systemDir, "called_pre_boots.dat");
9517        return fname;
9518    }
9519
9520    static final int LAST_DONE_VERSION = 10000;
9521
9522    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9523        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9524        File file = getCalledPreBootReceiversFile();
9525        FileInputStream fis = null;
9526        try {
9527            fis = new FileInputStream(file);
9528            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9529            int fvers = dis.readInt();
9530            if (fvers == LAST_DONE_VERSION) {
9531                String vers = dis.readUTF();
9532                String codename = dis.readUTF();
9533                String build = dis.readUTF();
9534                if (android.os.Build.VERSION.RELEASE.equals(vers)
9535                        && android.os.Build.VERSION.CODENAME.equals(codename)
9536                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9537                    int num = dis.readInt();
9538                    while (num > 0) {
9539                        num--;
9540                        String pkg = dis.readUTF();
9541                        String cls = dis.readUTF();
9542                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9543                    }
9544                }
9545            }
9546        } catch (FileNotFoundException e) {
9547        } catch (IOException e) {
9548            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9549        } finally {
9550            if (fis != null) {
9551                try {
9552                    fis.close();
9553                } catch (IOException e) {
9554                }
9555            }
9556        }
9557        return lastDoneReceivers;
9558    }
9559
9560    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9561        File file = getCalledPreBootReceiversFile();
9562        FileOutputStream fos = null;
9563        DataOutputStream dos = null;
9564        try {
9565            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9566            fos = new FileOutputStream(file);
9567            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9568            dos.writeInt(LAST_DONE_VERSION);
9569            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9570            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9571            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9572            dos.writeInt(list.size());
9573            for (int i=0; i<list.size(); i++) {
9574                dos.writeUTF(list.get(i).getPackageName());
9575                dos.writeUTF(list.get(i).getClassName());
9576            }
9577        } catch (IOException e) {
9578            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9579            file.delete();
9580        } finally {
9581            FileUtils.sync(fos);
9582            if (dos != null) {
9583                try {
9584                    dos.close();
9585                } catch (IOException e) {
9586                    // TODO Auto-generated catch block
9587                    e.printStackTrace();
9588                }
9589            }
9590        }
9591    }
9592
9593    public void systemReady(final Runnable goingCallback) {
9594        synchronized(this) {
9595            if (mSystemReady) {
9596                if (goingCallback != null) goingCallback.run();
9597                return;
9598            }
9599
9600            if (mRecentTasks == null) {
9601                mRecentTasks = mTaskPersister.restoreTasksLocked();
9602                if (!mRecentTasks.isEmpty()) {
9603                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9604                }
9605                mTaskPersister.startPersisting();
9606            }
9607
9608            // Check to see if there are any update receivers to run.
9609            if (!mDidUpdate) {
9610                if (mWaitingUpdate) {
9611                    return;
9612                }
9613                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9614                List<ResolveInfo> ris = null;
9615                try {
9616                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9617                            intent, null, 0, 0);
9618                } catch (RemoteException e) {
9619                }
9620                if (ris != null) {
9621                    for (int i=ris.size()-1; i>=0; i--) {
9622                        if ((ris.get(i).activityInfo.applicationInfo.flags
9623                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9624                            ris.remove(i);
9625                        }
9626                    }
9627                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9628
9629                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9630
9631                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9632                    for (int i=0; i<ris.size(); i++) {
9633                        ActivityInfo ai = ris.get(i).activityInfo;
9634                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9635                        if (lastDoneReceivers.contains(comp)) {
9636                            // We already did the pre boot receiver for this app with the current
9637                            // platform version, so don't do it again...
9638                            ris.remove(i);
9639                            i--;
9640                            // ...however, do keep it as one that has been done, so we don't
9641                            // forget about it when rewriting the file of last done receivers.
9642                            doneReceivers.add(comp);
9643                        }
9644                    }
9645
9646                    final int[] users = getUsersLocked();
9647                    for (int i=0; i<ris.size(); i++) {
9648                        ActivityInfo ai = ris.get(i).activityInfo;
9649                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9650                        doneReceivers.add(comp);
9651                        intent.setComponent(comp);
9652                        for (int j=0; j<users.length; j++) {
9653                            IIntentReceiver finisher = null;
9654                            if (i == ris.size()-1 && j == users.length-1) {
9655                                finisher = new IIntentReceiver.Stub() {
9656                                    public void performReceive(Intent intent, int resultCode,
9657                                            String data, Bundle extras, boolean ordered,
9658                                            boolean sticky, int sendingUser) {
9659                                        // The raw IIntentReceiver interface is called
9660                                        // with the AM lock held, so redispatch to
9661                                        // execute our code without the lock.
9662                                        mHandler.post(new Runnable() {
9663                                            public void run() {
9664                                                synchronized (ActivityManagerService.this) {
9665                                                    mDidUpdate = true;
9666                                                }
9667                                                writeLastDonePreBootReceivers(doneReceivers);
9668                                                showBootMessage(mContext.getText(
9669                                                        R.string.android_upgrading_complete),
9670                                                        false);
9671                                                systemReady(goingCallback);
9672                                            }
9673                                        });
9674                                    }
9675                                };
9676                            }
9677                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9678                                    + " for user " + users[j]);
9679                            broadcastIntentLocked(null, null, intent, null, finisher,
9680                                    0, null, null, null, AppOpsManager.OP_NONE,
9681                                    true, false, MY_PID, Process.SYSTEM_UID,
9682                                    users[j]);
9683                            if (finisher != null) {
9684                                mWaitingUpdate = true;
9685                            }
9686                        }
9687                    }
9688                }
9689                if (mWaitingUpdate) {
9690                    return;
9691                }
9692                mDidUpdate = true;
9693            }
9694
9695            mAppOpsService.systemReady();
9696            mUsageStatsService.systemReady();
9697            mSystemReady = true;
9698        }
9699
9700        ArrayList<ProcessRecord> procsToKill = null;
9701        synchronized(mPidsSelfLocked) {
9702            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9703                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9704                if (!isAllowedWhileBooting(proc.info)){
9705                    if (procsToKill == null) {
9706                        procsToKill = new ArrayList<ProcessRecord>();
9707                    }
9708                    procsToKill.add(proc);
9709                }
9710            }
9711        }
9712
9713        synchronized(this) {
9714            if (procsToKill != null) {
9715                for (int i=procsToKill.size()-1; i>=0; i--) {
9716                    ProcessRecord proc = procsToKill.get(i);
9717                    Slog.i(TAG, "Removing system update proc: " + proc);
9718                    removeProcessLocked(proc, true, false, "system update done");
9719                }
9720            }
9721
9722            // Now that we have cleaned up any update processes, we
9723            // are ready to start launching real processes and know that
9724            // we won't trample on them any more.
9725            mProcessesReady = true;
9726        }
9727
9728        Slog.i(TAG, "System now ready");
9729        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9730            SystemClock.uptimeMillis());
9731
9732        synchronized(this) {
9733            // Make sure we have no pre-ready processes sitting around.
9734
9735            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9736                ResolveInfo ri = mContext.getPackageManager()
9737                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9738                                STOCK_PM_FLAGS);
9739                CharSequence errorMsg = null;
9740                if (ri != null) {
9741                    ActivityInfo ai = ri.activityInfo;
9742                    ApplicationInfo app = ai.applicationInfo;
9743                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9744                        mTopAction = Intent.ACTION_FACTORY_TEST;
9745                        mTopData = null;
9746                        mTopComponent = new ComponentName(app.packageName,
9747                                ai.name);
9748                    } else {
9749                        errorMsg = mContext.getResources().getText(
9750                                com.android.internal.R.string.factorytest_not_system);
9751                    }
9752                } else {
9753                    errorMsg = mContext.getResources().getText(
9754                            com.android.internal.R.string.factorytest_no_action);
9755                }
9756                if (errorMsg != null) {
9757                    mTopAction = null;
9758                    mTopData = null;
9759                    mTopComponent = null;
9760                    Message msg = Message.obtain();
9761                    msg.what = SHOW_FACTORY_ERROR_MSG;
9762                    msg.getData().putCharSequence("msg", errorMsg);
9763                    mHandler.sendMessage(msg);
9764                }
9765            }
9766        }
9767
9768        retrieveSettings();
9769
9770        synchronized (this) {
9771            readGrantedUriPermissionsLocked();
9772        }
9773
9774        if (goingCallback != null) goingCallback.run();
9775
9776        mSystemServiceManager.startUser(mCurrentUserId);
9777
9778        synchronized (this) {
9779            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9780                try {
9781                    List apps = AppGlobals.getPackageManager().
9782                        getPersistentApplications(STOCK_PM_FLAGS);
9783                    if (apps != null) {
9784                        int N = apps.size();
9785                        int i;
9786                        for (i=0; i<N; i++) {
9787                            ApplicationInfo info
9788                                = (ApplicationInfo)apps.get(i);
9789                            if (info != null &&
9790                                    !info.packageName.equals("android")) {
9791                                addAppLocked(info, false);
9792                            }
9793                        }
9794                    }
9795                } catch (RemoteException ex) {
9796                    // pm is in same process, this will never happen.
9797                }
9798            }
9799
9800            // Start up initial activity.
9801            mBooting = true;
9802
9803            try {
9804                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9805                    Message msg = Message.obtain();
9806                    msg.what = SHOW_UID_ERROR_MSG;
9807                    mHandler.sendMessage(msg);
9808                }
9809            } catch (RemoteException e) {
9810            }
9811
9812            long ident = Binder.clearCallingIdentity();
9813            try {
9814                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9815                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9816                        | Intent.FLAG_RECEIVER_FOREGROUND);
9817                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9818                broadcastIntentLocked(null, null, intent,
9819                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9820                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9821                intent = new Intent(Intent.ACTION_USER_STARTING);
9822                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9823                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9824                broadcastIntentLocked(null, null, intent,
9825                        null, new IIntentReceiver.Stub() {
9826                            @Override
9827                            public void performReceive(Intent intent, int resultCode, String data,
9828                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9829                                    throws RemoteException {
9830                            }
9831                        }, 0, null, null,
9832                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9833                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9834            } catch (Throwable t) {
9835                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9836            } finally {
9837                Binder.restoreCallingIdentity(ident);
9838            }
9839            mStackSupervisor.resumeTopActivitiesLocked();
9840            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9841        }
9842    }
9843
9844    private boolean makeAppCrashingLocked(ProcessRecord app,
9845            String shortMsg, String longMsg, String stackTrace) {
9846        app.crashing = true;
9847        app.crashingReport = generateProcessError(app,
9848                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9849        startAppProblemLocked(app);
9850        app.stopFreezingAllLocked();
9851        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9852    }
9853
9854    private void makeAppNotRespondingLocked(ProcessRecord app,
9855            String activity, String shortMsg, String longMsg) {
9856        app.notResponding = true;
9857        app.notRespondingReport = generateProcessError(app,
9858                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9859                activity, shortMsg, longMsg, null);
9860        startAppProblemLocked(app);
9861        app.stopFreezingAllLocked();
9862    }
9863
9864    /**
9865     * Generate a process error record, suitable for attachment to a ProcessRecord.
9866     *
9867     * @param app The ProcessRecord in which the error occurred.
9868     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9869     *                      ActivityManager.AppErrorStateInfo
9870     * @param activity The activity associated with the crash, if known.
9871     * @param shortMsg Short message describing the crash.
9872     * @param longMsg Long message describing the crash.
9873     * @param stackTrace Full crash stack trace, may be null.
9874     *
9875     * @return Returns a fully-formed AppErrorStateInfo record.
9876     */
9877    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9878            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9879        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9880
9881        report.condition = condition;
9882        report.processName = app.processName;
9883        report.pid = app.pid;
9884        report.uid = app.info.uid;
9885        report.tag = activity;
9886        report.shortMsg = shortMsg;
9887        report.longMsg = longMsg;
9888        report.stackTrace = stackTrace;
9889
9890        return report;
9891    }
9892
9893    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9894        synchronized (this) {
9895            app.crashing = false;
9896            app.crashingReport = null;
9897            app.notResponding = false;
9898            app.notRespondingReport = null;
9899            if (app.anrDialog == fromDialog) {
9900                app.anrDialog = null;
9901            }
9902            if (app.waitDialog == fromDialog) {
9903                app.waitDialog = null;
9904            }
9905            if (app.pid > 0 && app.pid != MY_PID) {
9906                handleAppCrashLocked(app, null, null, null);
9907                killUnneededProcessLocked(app, "user request after error");
9908            }
9909        }
9910    }
9911
9912    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9913            String stackTrace) {
9914        long now = SystemClock.uptimeMillis();
9915
9916        Long crashTime;
9917        if (!app.isolated) {
9918            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9919        } else {
9920            crashTime = null;
9921        }
9922        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9923            // This process loses!
9924            Slog.w(TAG, "Process " + app.info.processName
9925                    + " has crashed too many times: killing!");
9926            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9927                    app.userId, app.info.processName, app.uid);
9928            mStackSupervisor.handleAppCrashLocked(app);
9929            if (!app.persistent) {
9930                // We don't want to start this process again until the user
9931                // explicitly does so...  but for persistent process, we really
9932                // need to keep it running.  If a persistent process is actually
9933                // repeatedly crashing, then badness for everyone.
9934                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9935                        app.info.processName);
9936                if (!app.isolated) {
9937                    // XXX We don't have a way to mark isolated processes
9938                    // as bad, since they don't have a peristent identity.
9939                    mBadProcesses.put(app.info.processName, app.uid,
9940                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9941                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9942                }
9943                app.bad = true;
9944                app.removed = true;
9945                // Don't let services in this process be restarted and potentially
9946                // annoy the user repeatedly.  Unless it is persistent, since those
9947                // processes run critical code.
9948                removeProcessLocked(app, false, false, "crash");
9949                mStackSupervisor.resumeTopActivitiesLocked();
9950                return false;
9951            }
9952            mStackSupervisor.resumeTopActivitiesLocked();
9953        } else {
9954            mStackSupervisor.finishTopRunningActivityLocked(app);
9955        }
9956
9957        // Bump up the crash count of any services currently running in the proc.
9958        for (int i=app.services.size()-1; i>=0; i--) {
9959            // Any services running in the application need to be placed
9960            // back in the pending list.
9961            ServiceRecord sr = app.services.valueAt(i);
9962            sr.crashCount++;
9963        }
9964
9965        // If the crashing process is what we consider to be the "home process" and it has been
9966        // replaced by a third-party app, clear the package preferred activities from packages
9967        // with a home activity running in the process to prevent a repeatedly crashing app
9968        // from blocking the user to manually clear the list.
9969        final ArrayList<ActivityRecord> activities = app.activities;
9970        if (app == mHomeProcess && activities.size() > 0
9971                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9972            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9973                final ActivityRecord r = activities.get(activityNdx);
9974                if (r.isHomeActivity()) {
9975                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9976                    try {
9977                        ActivityThread.getPackageManager()
9978                                .clearPackagePreferredActivities(r.packageName);
9979                    } catch (RemoteException c) {
9980                        // pm is in same process, this will never happen.
9981                    }
9982                }
9983            }
9984        }
9985
9986        if (!app.isolated) {
9987            // XXX Can't keep track of crash times for isolated processes,
9988            // because they don't have a perisistent identity.
9989            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9990        }
9991
9992        return true;
9993    }
9994
9995    void startAppProblemLocked(ProcessRecord app) {
9996        if (app.userId == mCurrentUserId) {
9997            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9998                    mContext, app.info.packageName, app.info.flags);
9999        } else {
10000            // If this app is not running under the current user, then we
10001            // can't give it a report button because that would require
10002            // launching the report UI under a different user.
10003            app.errorReportReceiver = null;
10004        }
10005        skipCurrentReceiverLocked(app);
10006    }
10007
10008    void skipCurrentReceiverLocked(ProcessRecord app) {
10009        for (BroadcastQueue queue : mBroadcastQueues) {
10010            queue.skipCurrentReceiverLocked(app);
10011        }
10012    }
10013
10014    /**
10015     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10016     * The application process will exit immediately after this call returns.
10017     * @param app object of the crashing app, null for the system server
10018     * @param crashInfo describing the exception
10019     */
10020    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10021        ProcessRecord r = findAppProcess(app, "Crash");
10022        final String processName = app == null ? "system_server"
10023                : (r == null ? "unknown" : r.processName);
10024
10025        handleApplicationCrashInner("crash", r, processName, crashInfo);
10026    }
10027
10028    /* Native crash reporting uses this inner version because it needs to be somewhat
10029     * decoupled from the AM-managed cleanup lifecycle
10030     */
10031    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10032            ApplicationErrorReport.CrashInfo crashInfo) {
10033        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10034                UserHandle.getUserId(Binder.getCallingUid()), processName,
10035                r == null ? -1 : r.info.flags,
10036                crashInfo.exceptionClassName,
10037                crashInfo.exceptionMessage,
10038                crashInfo.throwFileName,
10039                crashInfo.throwLineNumber);
10040
10041        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10042
10043        crashApplication(r, crashInfo);
10044    }
10045
10046    public void handleApplicationStrictModeViolation(
10047            IBinder app,
10048            int violationMask,
10049            StrictMode.ViolationInfo info) {
10050        ProcessRecord r = findAppProcess(app, "StrictMode");
10051        if (r == null) {
10052            return;
10053        }
10054
10055        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10056            Integer stackFingerprint = info.hashCode();
10057            boolean logIt = true;
10058            synchronized (mAlreadyLoggedViolatedStacks) {
10059                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10060                    logIt = false;
10061                    // TODO: sub-sample into EventLog for these, with
10062                    // the info.durationMillis?  Then we'd get
10063                    // the relative pain numbers, without logging all
10064                    // the stack traces repeatedly.  We'd want to do
10065                    // likewise in the client code, which also does
10066                    // dup suppression, before the Binder call.
10067                } else {
10068                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10069                        mAlreadyLoggedViolatedStacks.clear();
10070                    }
10071                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10072                }
10073            }
10074            if (logIt) {
10075                logStrictModeViolationToDropBox(r, info);
10076            }
10077        }
10078
10079        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10080            AppErrorResult result = new AppErrorResult();
10081            synchronized (this) {
10082                final long origId = Binder.clearCallingIdentity();
10083
10084                Message msg = Message.obtain();
10085                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10086                HashMap<String, Object> data = new HashMap<String, Object>();
10087                data.put("result", result);
10088                data.put("app", r);
10089                data.put("violationMask", violationMask);
10090                data.put("info", info);
10091                msg.obj = data;
10092                mHandler.sendMessage(msg);
10093
10094                Binder.restoreCallingIdentity(origId);
10095            }
10096            int res = result.get();
10097            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10098        }
10099    }
10100
10101    // Depending on the policy in effect, there could be a bunch of
10102    // these in quick succession so we try to batch these together to
10103    // minimize disk writes, number of dropbox entries, and maximize
10104    // compression, by having more fewer, larger records.
10105    private void logStrictModeViolationToDropBox(
10106            ProcessRecord process,
10107            StrictMode.ViolationInfo info) {
10108        if (info == null) {
10109            return;
10110        }
10111        final boolean isSystemApp = process == null ||
10112                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10113                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10114        final String processName = process == null ? "unknown" : process.processName;
10115        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10116        final DropBoxManager dbox = (DropBoxManager)
10117                mContext.getSystemService(Context.DROPBOX_SERVICE);
10118
10119        // Exit early if the dropbox isn't configured to accept this report type.
10120        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10121
10122        boolean bufferWasEmpty;
10123        boolean needsFlush;
10124        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10125        synchronized (sb) {
10126            bufferWasEmpty = sb.length() == 0;
10127            appendDropBoxProcessHeaders(process, processName, sb);
10128            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10129            sb.append("System-App: ").append(isSystemApp).append("\n");
10130            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10131            if (info.violationNumThisLoop != 0) {
10132                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10133            }
10134            if (info.numAnimationsRunning != 0) {
10135                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10136            }
10137            if (info.broadcastIntentAction != null) {
10138                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10139            }
10140            if (info.durationMillis != -1) {
10141                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10142            }
10143            if (info.numInstances != -1) {
10144                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10145            }
10146            if (info.tags != null) {
10147                for (String tag : info.tags) {
10148                    sb.append("Span-Tag: ").append(tag).append("\n");
10149                }
10150            }
10151            sb.append("\n");
10152            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10153                sb.append(info.crashInfo.stackTrace);
10154            }
10155            sb.append("\n");
10156
10157            // Only buffer up to ~64k.  Various logging bits truncate
10158            // things at 128k.
10159            needsFlush = (sb.length() > 64 * 1024);
10160        }
10161
10162        // Flush immediately if the buffer's grown too large, or this
10163        // is a non-system app.  Non-system apps are isolated with a
10164        // different tag & policy and not batched.
10165        //
10166        // Batching is useful during internal testing with
10167        // StrictMode settings turned up high.  Without batching,
10168        // thousands of separate files could be created on boot.
10169        if (!isSystemApp || needsFlush) {
10170            new Thread("Error dump: " + dropboxTag) {
10171                @Override
10172                public void run() {
10173                    String report;
10174                    synchronized (sb) {
10175                        report = sb.toString();
10176                        sb.delete(0, sb.length());
10177                        sb.trimToSize();
10178                    }
10179                    if (report.length() != 0) {
10180                        dbox.addText(dropboxTag, report);
10181                    }
10182                }
10183            }.start();
10184            return;
10185        }
10186
10187        // System app batching:
10188        if (!bufferWasEmpty) {
10189            // An existing dropbox-writing thread is outstanding, so
10190            // we don't need to start it up.  The existing thread will
10191            // catch the buffer appends we just did.
10192            return;
10193        }
10194
10195        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10196        // (After this point, we shouldn't access AMS internal data structures.)
10197        new Thread("Error dump: " + dropboxTag) {
10198            @Override
10199            public void run() {
10200                // 5 second sleep to let stacks arrive and be batched together
10201                try {
10202                    Thread.sleep(5000);  // 5 seconds
10203                } catch (InterruptedException e) {}
10204
10205                String errorReport;
10206                synchronized (mStrictModeBuffer) {
10207                    errorReport = mStrictModeBuffer.toString();
10208                    if (errorReport.length() == 0) {
10209                        return;
10210                    }
10211                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10212                    mStrictModeBuffer.trimToSize();
10213                }
10214                dbox.addText(dropboxTag, errorReport);
10215            }
10216        }.start();
10217    }
10218
10219    /**
10220     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10221     * @param app object of the crashing app, null for the system server
10222     * @param tag reported by the caller
10223     * @param crashInfo describing the context of the error
10224     * @return true if the process should exit immediately (WTF is fatal)
10225     */
10226    public boolean handleApplicationWtf(IBinder app, String tag,
10227            ApplicationErrorReport.CrashInfo crashInfo) {
10228        ProcessRecord r = findAppProcess(app, "WTF");
10229        final String processName = app == null ? "system_server"
10230                : (r == null ? "unknown" : r.processName);
10231
10232        EventLog.writeEvent(EventLogTags.AM_WTF,
10233                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10234                processName,
10235                r == null ? -1 : r.info.flags,
10236                tag, crashInfo.exceptionMessage);
10237
10238        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10239
10240        if (r != null && r.pid != Process.myPid() &&
10241                Settings.Global.getInt(mContext.getContentResolver(),
10242                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10243            crashApplication(r, crashInfo);
10244            return true;
10245        } else {
10246            return false;
10247        }
10248    }
10249
10250    /**
10251     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10252     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10253     */
10254    private ProcessRecord findAppProcess(IBinder app, String reason) {
10255        if (app == null) {
10256            return null;
10257        }
10258
10259        synchronized (this) {
10260            final int NP = mProcessNames.getMap().size();
10261            for (int ip=0; ip<NP; ip++) {
10262                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10263                final int NA = apps.size();
10264                for (int ia=0; ia<NA; ia++) {
10265                    ProcessRecord p = apps.valueAt(ia);
10266                    if (p.thread != null && p.thread.asBinder() == app) {
10267                        return p;
10268                    }
10269                }
10270            }
10271
10272            Slog.w(TAG, "Can't find mystery application for " + reason
10273                    + " from pid=" + Binder.getCallingPid()
10274                    + " uid=" + Binder.getCallingUid() + ": " + app);
10275            return null;
10276        }
10277    }
10278
10279    /**
10280     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10281     * to append various headers to the dropbox log text.
10282     */
10283    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10284            StringBuilder sb) {
10285        // Watchdog thread ends up invoking this function (with
10286        // a null ProcessRecord) to add the stack file to dropbox.
10287        // Do not acquire a lock on this (am) in such cases, as it
10288        // could cause a potential deadlock, if and when watchdog
10289        // is invoked due to unavailability of lock on am and it
10290        // would prevent watchdog from killing system_server.
10291        if (process == null) {
10292            sb.append("Process: ").append(processName).append("\n");
10293            return;
10294        }
10295        // Note: ProcessRecord 'process' is guarded by the service
10296        // instance.  (notably process.pkgList, which could otherwise change
10297        // concurrently during execution of this method)
10298        synchronized (this) {
10299            sb.append("Process: ").append(processName).append("\n");
10300            int flags = process.info.flags;
10301            IPackageManager pm = AppGlobals.getPackageManager();
10302            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10303            for (int ip=0; ip<process.pkgList.size(); ip++) {
10304                String pkg = process.pkgList.keyAt(ip);
10305                sb.append("Package: ").append(pkg);
10306                try {
10307                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10308                    if (pi != null) {
10309                        sb.append(" v").append(pi.versionCode);
10310                        if (pi.versionName != null) {
10311                            sb.append(" (").append(pi.versionName).append(")");
10312                        }
10313                    }
10314                } catch (RemoteException e) {
10315                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10316                }
10317                sb.append("\n");
10318            }
10319        }
10320    }
10321
10322    private static String processClass(ProcessRecord process) {
10323        if (process == null || process.pid == MY_PID) {
10324            return "system_server";
10325        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10326            return "system_app";
10327        } else {
10328            return "data_app";
10329        }
10330    }
10331
10332    /**
10333     * Write a description of an error (crash, WTF, ANR) to the drop box.
10334     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10335     * @param process which caused the error, null means the system server
10336     * @param activity which triggered the error, null if unknown
10337     * @param parent activity related to the error, null if unknown
10338     * @param subject line related to the error, null if absent
10339     * @param report in long form describing the error, null if absent
10340     * @param logFile to include in the report, null if none
10341     * @param crashInfo giving an application stack trace, null if absent
10342     */
10343    public void addErrorToDropBox(String eventType,
10344            ProcessRecord process, String processName, ActivityRecord activity,
10345            ActivityRecord parent, String subject,
10346            final String report, final File logFile,
10347            final ApplicationErrorReport.CrashInfo crashInfo) {
10348        // NOTE -- this must never acquire the ActivityManagerService lock,
10349        // otherwise the watchdog may be prevented from resetting the system.
10350
10351        final String dropboxTag = processClass(process) + "_" + eventType;
10352        final DropBoxManager dbox = (DropBoxManager)
10353                mContext.getSystemService(Context.DROPBOX_SERVICE);
10354
10355        // Exit early if the dropbox isn't configured to accept this report type.
10356        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10357
10358        final StringBuilder sb = new StringBuilder(1024);
10359        appendDropBoxProcessHeaders(process, processName, sb);
10360        if (activity != null) {
10361            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10362        }
10363        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10364            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10365        }
10366        if (parent != null && parent != activity) {
10367            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10368        }
10369        if (subject != null) {
10370            sb.append("Subject: ").append(subject).append("\n");
10371        }
10372        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10373        if (Debug.isDebuggerConnected()) {
10374            sb.append("Debugger: Connected\n");
10375        }
10376        sb.append("\n");
10377
10378        // Do the rest in a worker thread to avoid blocking the caller on I/O
10379        // (After this point, we shouldn't access AMS internal data structures.)
10380        Thread worker = new Thread("Error dump: " + dropboxTag) {
10381            @Override
10382            public void run() {
10383                if (report != null) {
10384                    sb.append(report);
10385                }
10386                if (logFile != null) {
10387                    try {
10388                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10389                                    "\n\n[[TRUNCATED]]"));
10390                    } catch (IOException e) {
10391                        Slog.e(TAG, "Error reading " + logFile, e);
10392                    }
10393                }
10394                if (crashInfo != null && crashInfo.stackTrace != null) {
10395                    sb.append(crashInfo.stackTrace);
10396                }
10397
10398                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10399                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10400                if (lines > 0) {
10401                    sb.append("\n");
10402
10403                    // Merge several logcat streams, and take the last N lines
10404                    InputStreamReader input = null;
10405                    try {
10406                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10407                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10408                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10409
10410                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10411                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10412                        input = new InputStreamReader(logcat.getInputStream());
10413
10414                        int num;
10415                        char[] buf = new char[8192];
10416                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10417                    } catch (IOException e) {
10418                        Slog.e(TAG, "Error running logcat", e);
10419                    } finally {
10420                        if (input != null) try { input.close(); } catch (IOException e) {}
10421                    }
10422                }
10423
10424                dbox.addText(dropboxTag, sb.toString());
10425            }
10426        };
10427
10428        if (process == null) {
10429            // If process is null, we are being called from some internal code
10430            // and may be about to die -- run this synchronously.
10431            worker.run();
10432        } else {
10433            worker.start();
10434        }
10435    }
10436
10437    /**
10438     * Bring up the "unexpected error" dialog box for a crashing app.
10439     * Deal with edge cases (intercepts from instrumented applications,
10440     * ActivityController, error intent receivers, that sort of thing).
10441     * @param r the application crashing
10442     * @param crashInfo describing the failure
10443     */
10444    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10445        long timeMillis = System.currentTimeMillis();
10446        String shortMsg = crashInfo.exceptionClassName;
10447        String longMsg = crashInfo.exceptionMessage;
10448        String stackTrace = crashInfo.stackTrace;
10449        if (shortMsg != null && longMsg != null) {
10450            longMsg = shortMsg + ": " + longMsg;
10451        } else if (shortMsg != null) {
10452            longMsg = shortMsg;
10453        }
10454
10455        AppErrorResult result = new AppErrorResult();
10456        synchronized (this) {
10457            if (mController != null) {
10458                try {
10459                    String name = r != null ? r.processName : null;
10460                    int pid = r != null ? r.pid : Binder.getCallingPid();
10461                    if (!mController.appCrashed(name, pid,
10462                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10463                        Slog.w(TAG, "Force-killing crashed app " + name
10464                                + " at watcher's request");
10465                        Process.killProcess(pid);
10466                        return;
10467                    }
10468                } catch (RemoteException e) {
10469                    mController = null;
10470                    Watchdog.getInstance().setActivityController(null);
10471                }
10472            }
10473
10474            final long origId = Binder.clearCallingIdentity();
10475
10476            // If this process is running instrumentation, finish it.
10477            if (r != null && r.instrumentationClass != null) {
10478                Slog.w(TAG, "Error in app " + r.processName
10479                      + " running instrumentation " + r.instrumentationClass + ":");
10480                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10481                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10482                Bundle info = new Bundle();
10483                info.putString("shortMsg", shortMsg);
10484                info.putString("longMsg", longMsg);
10485                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10486                Binder.restoreCallingIdentity(origId);
10487                return;
10488            }
10489
10490            // If we can't identify the process or it's already exceeded its crash quota,
10491            // quit right away without showing a crash dialog.
10492            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10493                Binder.restoreCallingIdentity(origId);
10494                return;
10495            }
10496
10497            Message msg = Message.obtain();
10498            msg.what = SHOW_ERROR_MSG;
10499            HashMap data = new HashMap();
10500            data.put("result", result);
10501            data.put("app", r);
10502            msg.obj = data;
10503            mHandler.sendMessage(msg);
10504
10505            Binder.restoreCallingIdentity(origId);
10506        }
10507
10508        int res = result.get();
10509
10510        Intent appErrorIntent = null;
10511        synchronized (this) {
10512            if (r != null && !r.isolated) {
10513                // XXX Can't keep track of crash time for isolated processes,
10514                // since they don't have a persistent identity.
10515                mProcessCrashTimes.put(r.info.processName, r.uid,
10516                        SystemClock.uptimeMillis());
10517            }
10518            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10519                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10520            }
10521        }
10522
10523        if (appErrorIntent != null) {
10524            try {
10525                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10526            } catch (ActivityNotFoundException e) {
10527                Slog.w(TAG, "bug report receiver dissappeared", e);
10528            }
10529        }
10530    }
10531
10532    Intent createAppErrorIntentLocked(ProcessRecord r,
10533            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10534        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10535        if (report == null) {
10536            return null;
10537        }
10538        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10539        result.setComponent(r.errorReportReceiver);
10540        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10541        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10542        return result;
10543    }
10544
10545    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10546            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10547        if (r.errorReportReceiver == null) {
10548            return null;
10549        }
10550
10551        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10552            return null;
10553        }
10554
10555        ApplicationErrorReport report = new ApplicationErrorReport();
10556        report.packageName = r.info.packageName;
10557        report.installerPackageName = r.errorReportReceiver.getPackageName();
10558        report.processName = r.processName;
10559        report.time = timeMillis;
10560        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10561
10562        if (r.crashing || r.forceCrashReport) {
10563            report.type = ApplicationErrorReport.TYPE_CRASH;
10564            report.crashInfo = crashInfo;
10565        } else if (r.notResponding) {
10566            report.type = ApplicationErrorReport.TYPE_ANR;
10567            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10568
10569            report.anrInfo.activity = r.notRespondingReport.tag;
10570            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10571            report.anrInfo.info = r.notRespondingReport.longMsg;
10572        }
10573
10574        return report;
10575    }
10576
10577    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10578        enforceNotIsolatedCaller("getProcessesInErrorState");
10579        // assume our apps are happy - lazy create the list
10580        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10581
10582        final boolean allUsers = ActivityManager.checkUidPermission(
10583                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10584                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10585        int userId = UserHandle.getUserId(Binder.getCallingUid());
10586
10587        synchronized (this) {
10588
10589            // iterate across all processes
10590            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10591                ProcessRecord app = mLruProcesses.get(i);
10592                if (!allUsers && app.userId != userId) {
10593                    continue;
10594                }
10595                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10596                    // This one's in trouble, so we'll generate a report for it
10597                    // crashes are higher priority (in case there's a crash *and* an anr)
10598                    ActivityManager.ProcessErrorStateInfo report = null;
10599                    if (app.crashing) {
10600                        report = app.crashingReport;
10601                    } else if (app.notResponding) {
10602                        report = app.notRespondingReport;
10603                    }
10604
10605                    if (report != null) {
10606                        if (errList == null) {
10607                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10608                        }
10609                        errList.add(report);
10610                    } else {
10611                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10612                                " crashing = " + app.crashing +
10613                                " notResponding = " + app.notResponding);
10614                    }
10615                }
10616            }
10617        }
10618
10619        return errList;
10620    }
10621
10622    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10623        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10624            if (currApp != null) {
10625                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10626            }
10627            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10628        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10629            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10630        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10631            if (currApp != null) {
10632                currApp.lru = 0;
10633            }
10634            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10635        } else if (adj >= ProcessList.SERVICE_ADJ) {
10636            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10637        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10638            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10639        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10640            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10641        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10642            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10643        } else {
10644            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10645        }
10646    }
10647
10648    private void fillInProcMemInfo(ProcessRecord app,
10649            ActivityManager.RunningAppProcessInfo outInfo) {
10650        outInfo.pid = app.pid;
10651        outInfo.uid = app.info.uid;
10652        if (mHeavyWeightProcess == app) {
10653            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10654        }
10655        if (app.persistent) {
10656            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10657        }
10658        if (app.activities.size() > 0) {
10659            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10660        }
10661        outInfo.lastTrimLevel = app.trimMemoryLevel;
10662        int adj = app.curAdj;
10663        outInfo.importance = oomAdjToImportance(adj, outInfo);
10664        outInfo.importanceReasonCode = app.adjTypeCode;
10665        outInfo.processState = app.curProcState;
10666    }
10667
10668    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10669        enforceNotIsolatedCaller("getRunningAppProcesses");
10670        // Lazy instantiation of list
10671        List<ActivityManager.RunningAppProcessInfo> runList = null;
10672        final boolean allUsers = ActivityManager.checkUidPermission(
10673                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10674                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10675        int userId = UserHandle.getUserId(Binder.getCallingUid());
10676        synchronized (this) {
10677            // Iterate across all processes
10678            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10679                ProcessRecord app = mLruProcesses.get(i);
10680                if (!allUsers && app.userId != userId) {
10681                    continue;
10682                }
10683                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10684                    // Generate process state info for running application
10685                    ActivityManager.RunningAppProcessInfo currApp =
10686                        new ActivityManager.RunningAppProcessInfo(app.processName,
10687                                app.pid, app.getPackageList());
10688                    fillInProcMemInfo(app, currApp);
10689                    if (app.adjSource instanceof ProcessRecord) {
10690                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10691                        currApp.importanceReasonImportance = oomAdjToImportance(
10692                                app.adjSourceOom, null);
10693                    } else if (app.adjSource instanceof ActivityRecord) {
10694                        ActivityRecord r = (ActivityRecord)app.adjSource;
10695                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10696                    }
10697                    if (app.adjTarget instanceof ComponentName) {
10698                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10699                    }
10700                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10701                    //        + " lru=" + currApp.lru);
10702                    if (runList == null) {
10703                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10704                    }
10705                    runList.add(currApp);
10706                }
10707            }
10708        }
10709        return runList;
10710    }
10711
10712    public List<ApplicationInfo> getRunningExternalApplications() {
10713        enforceNotIsolatedCaller("getRunningExternalApplications");
10714        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10715        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10716        if (runningApps != null && runningApps.size() > 0) {
10717            Set<String> extList = new HashSet<String>();
10718            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10719                if (app.pkgList != null) {
10720                    for (String pkg : app.pkgList) {
10721                        extList.add(pkg);
10722                    }
10723                }
10724            }
10725            IPackageManager pm = AppGlobals.getPackageManager();
10726            for (String pkg : extList) {
10727                try {
10728                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10729                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10730                        retList.add(info);
10731                    }
10732                } catch (RemoteException e) {
10733                }
10734            }
10735        }
10736        return retList;
10737    }
10738
10739    @Override
10740    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10741        enforceNotIsolatedCaller("getMyMemoryState");
10742        synchronized (this) {
10743            ProcessRecord proc;
10744            synchronized (mPidsSelfLocked) {
10745                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10746            }
10747            fillInProcMemInfo(proc, outInfo);
10748        }
10749    }
10750
10751    @Override
10752    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10753        if (checkCallingPermission(android.Manifest.permission.DUMP)
10754                != PackageManager.PERMISSION_GRANTED) {
10755            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10756                    + Binder.getCallingPid()
10757                    + ", uid=" + Binder.getCallingUid()
10758                    + " without permission "
10759                    + android.Manifest.permission.DUMP);
10760            return;
10761        }
10762
10763        boolean dumpAll = false;
10764        boolean dumpClient = false;
10765        String dumpPackage = null;
10766
10767        int opti = 0;
10768        while (opti < args.length) {
10769            String opt = args[opti];
10770            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10771                break;
10772            }
10773            opti++;
10774            if ("-a".equals(opt)) {
10775                dumpAll = true;
10776            } else if ("-c".equals(opt)) {
10777                dumpClient = true;
10778            } else if ("-h".equals(opt)) {
10779                pw.println("Activity manager dump options:");
10780                pw.println("  [-a] [-c] [-h] [cmd] ...");
10781                pw.println("  cmd may be one of:");
10782                pw.println("    a[ctivities]: activity stack state");
10783                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10784                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10785                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10786                pw.println("    o[om]: out of memory management");
10787                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10788                pw.println("    provider [COMP_SPEC]: provider client-side state");
10789                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10790                pw.println("    service [COMP_SPEC]: service client-side state");
10791                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10792                pw.println("    all: dump all activities");
10793                pw.println("    top: dump the top activity");
10794                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10795                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10796                pw.println("    a partial substring in a component name, a");
10797                pw.println("    hex object identifier.");
10798                pw.println("  -a: include all available server state.");
10799                pw.println("  -c: include client state.");
10800                return;
10801            } else {
10802                pw.println("Unknown argument: " + opt + "; use -h for help");
10803            }
10804        }
10805
10806        long origId = Binder.clearCallingIdentity();
10807        boolean more = false;
10808        // Is the caller requesting to dump a particular piece of data?
10809        if (opti < args.length) {
10810            String cmd = args[opti];
10811            opti++;
10812            if ("activities".equals(cmd) || "a".equals(cmd)) {
10813                synchronized (this) {
10814                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10815                }
10816            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10817                String[] newArgs;
10818                String name;
10819                if (opti >= args.length) {
10820                    name = null;
10821                    newArgs = EMPTY_STRING_ARRAY;
10822                } else {
10823                    name = args[opti];
10824                    opti++;
10825                    newArgs = new String[args.length - opti];
10826                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10827                            args.length - opti);
10828                }
10829                synchronized (this) {
10830                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10831                }
10832            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10833                String[] newArgs;
10834                String name;
10835                if (opti >= args.length) {
10836                    name = null;
10837                    newArgs = EMPTY_STRING_ARRAY;
10838                } else {
10839                    name = args[opti];
10840                    opti++;
10841                    newArgs = new String[args.length - opti];
10842                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10843                            args.length - opti);
10844                }
10845                synchronized (this) {
10846                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10847                }
10848            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10849                String[] newArgs;
10850                String name;
10851                if (opti >= args.length) {
10852                    name = null;
10853                    newArgs = EMPTY_STRING_ARRAY;
10854                } else {
10855                    name = args[opti];
10856                    opti++;
10857                    newArgs = new String[args.length - opti];
10858                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10859                            args.length - opti);
10860                }
10861                synchronized (this) {
10862                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10863                }
10864            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10865                synchronized (this) {
10866                    dumpOomLocked(fd, pw, args, opti, true);
10867                }
10868            } else if ("provider".equals(cmd)) {
10869                String[] newArgs;
10870                String name;
10871                if (opti >= args.length) {
10872                    name = null;
10873                    newArgs = EMPTY_STRING_ARRAY;
10874                } else {
10875                    name = args[opti];
10876                    opti++;
10877                    newArgs = new String[args.length - opti];
10878                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10879                }
10880                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10881                    pw.println("No providers match: " + name);
10882                    pw.println("Use -h for help.");
10883                }
10884            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10885                synchronized (this) {
10886                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10887                }
10888            } else if ("service".equals(cmd)) {
10889                String[] newArgs;
10890                String name;
10891                if (opti >= args.length) {
10892                    name = null;
10893                    newArgs = EMPTY_STRING_ARRAY;
10894                } else {
10895                    name = args[opti];
10896                    opti++;
10897                    newArgs = new String[args.length - opti];
10898                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10899                            args.length - opti);
10900                }
10901                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10902                    pw.println("No services match: " + name);
10903                    pw.println("Use -h for help.");
10904                }
10905            } else if ("package".equals(cmd)) {
10906                String[] newArgs;
10907                if (opti >= args.length) {
10908                    pw.println("package: no package name specified");
10909                    pw.println("Use -h for help.");
10910                } else {
10911                    dumpPackage = args[opti];
10912                    opti++;
10913                    newArgs = new String[args.length - opti];
10914                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10915                            args.length - opti);
10916                    args = newArgs;
10917                    opti = 0;
10918                    more = true;
10919                }
10920            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10921                synchronized (this) {
10922                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10923                }
10924            } else {
10925                // Dumping a single activity?
10926                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10927                    pw.println("Bad activity command, or no activities match: " + cmd);
10928                    pw.println("Use -h for help.");
10929                }
10930            }
10931            if (!more) {
10932                Binder.restoreCallingIdentity(origId);
10933                return;
10934            }
10935        }
10936
10937        // No piece of data specified, dump everything.
10938        synchronized (this) {
10939            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10940            pw.println();
10941            if (dumpAll) {
10942                pw.println("-------------------------------------------------------------------------------");
10943            }
10944            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10945            pw.println();
10946            if (dumpAll) {
10947                pw.println("-------------------------------------------------------------------------------");
10948            }
10949            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10950            pw.println();
10951            if (dumpAll) {
10952                pw.println("-------------------------------------------------------------------------------");
10953            }
10954            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10955            pw.println();
10956            if (dumpAll) {
10957                pw.println("-------------------------------------------------------------------------------");
10958            }
10959            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10960            pw.println();
10961            if (dumpAll) {
10962                pw.println("-------------------------------------------------------------------------------");
10963            }
10964            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10965        }
10966        Binder.restoreCallingIdentity(origId);
10967    }
10968
10969    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10970            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10971        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10972
10973        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10974                dumpPackage);
10975        boolean needSep = printedAnything;
10976
10977        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10978                dumpPackage, needSep, "  mFocusedActivity: ");
10979        if (printed) {
10980            printedAnything = true;
10981            needSep = false;
10982        }
10983
10984        if (dumpPackage == null) {
10985            if (needSep) {
10986                pw.println();
10987            }
10988            needSep = true;
10989            printedAnything = true;
10990            mStackSupervisor.dump(pw, "  ");
10991        }
10992
10993        if (mRecentTasks.size() > 0) {
10994            boolean printedHeader = false;
10995
10996            final int N = mRecentTasks.size();
10997            for (int i=0; i<N; i++) {
10998                TaskRecord tr = mRecentTasks.get(i);
10999                if (dumpPackage != null) {
11000                    if (tr.realActivity == null ||
11001                            !dumpPackage.equals(tr.realActivity)) {
11002                        continue;
11003                    }
11004                }
11005                if (!printedHeader) {
11006                    if (needSep) {
11007                        pw.println();
11008                    }
11009                    pw.println("  Recent tasks:");
11010                    printedHeader = true;
11011                    printedAnything = true;
11012                }
11013                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11014                        pw.println(tr);
11015                if (dumpAll) {
11016                    mRecentTasks.get(i).dump(pw, "    ");
11017                }
11018            }
11019        }
11020
11021        if (!printedAnything) {
11022            pw.println("  (nothing)");
11023        }
11024    }
11025
11026    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11027            int opti, boolean dumpAll, String dumpPackage) {
11028        boolean needSep = false;
11029        boolean printedAnything = false;
11030        int numPers = 0;
11031
11032        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11033
11034        if (dumpAll) {
11035            final int NP = mProcessNames.getMap().size();
11036            for (int ip=0; ip<NP; ip++) {
11037                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11038                final int NA = procs.size();
11039                for (int ia=0; ia<NA; ia++) {
11040                    ProcessRecord r = procs.valueAt(ia);
11041                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11042                        continue;
11043                    }
11044                    if (!needSep) {
11045                        pw.println("  All known processes:");
11046                        needSep = true;
11047                        printedAnything = true;
11048                    }
11049                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11050                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11051                        pw.print(" "); pw.println(r);
11052                    r.dump(pw, "    ");
11053                    if (r.persistent) {
11054                        numPers++;
11055                    }
11056                }
11057            }
11058        }
11059
11060        if (mIsolatedProcesses.size() > 0) {
11061            boolean printed = false;
11062            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11063                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11064                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11065                    continue;
11066                }
11067                if (!printed) {
11068                    if (needSep) {
11069                        pw.println();
11070                    }
11071                    pw.println("  Isolated process list (sorted by uid):");
11072                    printedAnything = true;
11073                    printed = true;
11074                    needSep = true;
11075                }
11076                pw.println(String.format("%sIsolated #%2d: %s",
11077                        "    ", i, r.toString()));
11078            }
11079        }
11080
11081        if (mLruProcesses.size() > 0) {
11082            if (needSep) {
11083                pw.println();
11084            }
11085            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11086                    pw.print(" total, non-act at ");
11087                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11088                    pw.print(", non-svc at ");
11089                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11090                    pw.println("):");
11091            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11092            needSep = true;
11093            printedAnything = true;
11094        }
11095
11096        if (dumpAll || dumpPackage != null) {
11097            synchronized (mPidsSelfLocked) {
11098                boolean printed = false;
11099                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11100                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11101                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11102                        continue;
11103                    }
11104                    if (!printed) {
11105                        if (needSep) pw.println();
11106                        needSep = true;
11107                        pw.println("  PID mappings:");
11108                        printed = true;
11109                        printedAnything = true;
11110                    }
11111                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11112                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11113                }
11114            }
11115        }
11116
11117        if (mForegroundProcesses.size() > 0) {
11118            synchronized (mPidsSelfLocked) {
11119                boolean printed = false;
11120                for (int i=0; i<mForegroundProcesses.size(); i++) {
11121                    ProcessRecord r = mPidsSelfLocked.get(
11122                            mForegroundProcesses.valueAt(i).pid);
11123                    if (dumpPackage != null && (r == null
11124                            || !r.pkgList.containsKey(dumpPackage))) {
11125                        continue;
11126                    }
11127                    if (!printed) {
11128                        if (needSep) pw.println();
11129                        needSep = true;
11130                        pw.println("  Foreground Processes:");
11131                        printed = true;
11132                        printedAnything = true;
11133                    }
11134                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11135                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11136                }
11137            }
11138        }
11139
11140        if (mPersistentStartingProcesses.size() > 0) {
11141            if (needSep) pw.println();
11142            needSep = true;
11143            printedAnything = true;
11144            pw.println("  Persisent processes that are starting:");
11145            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11146                    "Starting Norm", "Restarting PERS", dumpPackage);
11147        }
11148
11149        if (mRemovedProcesses.size() > 0) {
11150            if (needSep) pw.println();
11151            needSep = true;
11152            printedAnything = true;
11153            pw.println("  Processes that are being removed:");
11154            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11155                    "Removed Norm", "Removed PERS", dumpPackage);
11156        }
11157
11158        if (mProcessesOnHold.size() > 0) {
11159            if (needSep) pw.println();
11160            needSep = true;
11161            printedAnything = true;
11162            pw.println("  Processes that are on old until the system is ready:");
11163            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11164                    "OnHold Norm", "OnHold PERS", dumpPackage);
11165        }
11166
11167        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11168
11169        if (mProcessCrashTimes.getMap().size() > 0) {
11170            boolean printed = false;
11171            long now = SystemClock.uptimeMillis();
11172            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11173            final int NP = pmap.size();
11174            for (int ip=0; ip<NP; ip++) {
11175                String pname = pmap.keyAt(ip);
11176                SparseArray<Long> uids = pmap.valueAt(ip);
11177                final int N = uids.size();
11178                for (int i=0; i<N; i++) {
11179                    int puid = uids.keyAt(i);
11180                    ProcessRecord r = mProcessNames.get(pname, puid);
11181                    if (dumpPackage != null && (r == null
11182                            || !r.pkgList.containsKey(dumpPackage))) {
11183                        continue;
11184                    }
11185                    if (!printed) {
11186                        if (needSep) pw.println();
11187                        needSep = true;
11188                        pw.println("  Time since processes crashed:");
11189                        printed = true;
11190                        printedAnything = true;
11191                    }
11192                    pw.print("    Process "); pw.print(pname);
11193                            pw.print(" uid "); pw.print(puid);
11194                            pw.print(": last crashed ");
11195                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11196                            pw.println(" ago");
11197                }
11198            }
11199        }
11200
11201        if (mBadProcesses.getMap().size() > 0) {
11202            boolean printed = false;
11203            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11204            final int NP = pmap.size();
11205            for (int ip=0; ip<NP; ip++) {
11206                String pname = pmap.keyAt(ip);
11207                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11208                final int N = uids.size();
11209                for (int i=0; i<N; i++) {
11210                    int puid = uids.keyAt(i);
11211                    ProcessRecord r = mProcessNames.get(pname, puid);
11212                    if (dumpPackage != null && (r == null
11213                            || !r.pkgList.containsKey(dumpPackage))) {
11214                        continue;
11215                    }
11216                    if (!printed) {
11217                        if (needSep) pw.println();
11218                        needSep = true;
11219                        pw.println("  Bad processes:");
11220                        printedAnything = true;
11221                    }
11222                    BadProcessInfo info = uids.valueAt(i);
11223                    pw.print("    Bad process "); pw.print(pname);
11224                            pw.print(" uid "); pw.print(puid);
11225                            pw.print(": crashed at time "); pw.println(info.time);
11226                    if (info.shortMsg != null) {
11227                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11228                    }
11229                    if (info.longMsg != null) {
11230                        pw.print("      Long msg: "); pw.println(info.longMsg);
11231                    }
11232                    if (info.stack != null) {
11233                        pw.println("      Stack:");
11234                        int lastPos = 0;
11235                        for (int pos=0; pos<info.stack.length(); pos++) {
11236                            if (info.stack.charAt(pos) == '\n') {
11237                                pw.print("        ");
11238                                pw.write(info.stack, lastPos, pos-lastPos);
11239                                pw.println();
11240                                lastPos = pos+1;
11241                            }
11242                        }
11243                        if (lastPos < info.stack.length()) {
11244                            pw.print("        ");
11245                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11246                            pw.println();
11247                        }
11248                    }
11249                }
11250            }
11251        }
11252
11253        if (dumpPackage == null) {
11254            pw.println();
11255            needSep = false;
11256            pw.println("  mStartedUsers:");
11257            for (int i=0; i<mStartedUsers.size(); i++) {
11258                UserStartedState uss = mStartedUsers.valueAt(i);
11259                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11260                        pw.print(": "); uss.dump("", pw);
11261            }
11262            pw.print("  mStartedUserArray: [");
11263            for (int i=0; i<mStartedUserArray.length; i++) {
11264                if (i > 0) pw.print(", ");
11265                pw.print(mStartedUserArray[i]);
11266            }
11267            pw.println("]");
11268            pw.print("  mUserLru: [");
11269            for (int i=0; i<mUserLru.size(); i++) {
11270                if (i > 0) pw.print(", ");
11271                pw.print(mUserLru.get(i));
11272            }
11273            pw.println("]");
11274            if (dumpAll) {
11275                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11276            }
11277        }
11278        if (mHomeProcess != null && (dumpPackage == null
11279                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11280            if (needSep) {
11281                pw.println();
11282                needSep = false;
11283            }
11284            pw.println("  mHomeProcess: " + mHomeProcess);
11285        }
11286        if (mPreviousProcess != null && (dumpPackage == null
11287                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11288            if (needSep) {
11289                pw.println();
11290                needSep = false;
11291            }
11292            pw.println("  mPreviousProcess: " + mPreviousProcess);
11293        }
11294        if (dumpAll) {
11295            StringBuilder sb = new StringBuilder(128);
11296            sb.append("  mPreviousProcessVisibleTime: ");
11297            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11298            pw.println(sb);
11299        }
11300        if (mHeavyWeightProcess != null && (dumpPackage == null
11301                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11302            if (needSep) {
11303                pw.println();
11304                needSep = false;
11305            }
11306            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11307        }
11308        if (dumpPackage == null) {
11309            pw.println("  mConfiguration: " + mConfiguration);
11310        }
11311        if (dumpAll) {
11312            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11313            if (mCompatModePackages.getPackages().size() > 0) {
11314                boolean printed = false;
11315                for (Map.Entry<String, Integer> entry
11316                        : mCompatModePackages.getPackages().entrySet()) {
11317                    String pkg = entry.getKey();
11318                    int mode = entry.getValue();
11319                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11320                        continue;
11321                    }
11322                    if (!printed) {
11323                        pw.println("  mScreenCompatPackages:");
11324                        printed = true;
11325                    }
11326                    pw.print("    "); pw.print(pkg); pw.print(": ");
11327                            pw.print(mode); pw.println();
11328                }
11329            }
11330        }
11331        if (dumpPackage == null) {
11332            if (mSleeping || mWentToSleep || mLockScreenShown) {
11333                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11334                        + " mLockScreenShown " + mLockScreenShown);
11335            }
11336            if (mShuttingDown || mRunningVoice) {
11337                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11338            }
11339        }
11340        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11341                || mOrigWaitForDebugger) {
11342            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11343                    || dumpPackage.equals(mOrigDebugApp)) {
11344                if (needSep) {
11345                    pw.println();
11346                    needSep = false;
11347                }
11348                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11349                        + " mDebugTransient=" + mDebugTransient
11350                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11351            }
11352        }
11353        if (mOpenGlTraceApp != null) {
11354            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11355                if (needSep) {
11356                    pw.println();
11357                    needSep = false;
11358                }
11359                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11360            }
11361        }
11362        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11363                || mProfileFd != null) {
11364            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11365                if (needSep) {
11366                    pw.println();
11367                    needSep = false;
11368                }
11369                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11370                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11371                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11372                        + mAutoStopProfiler);
11373            }
11374        }
11375        if (dumpPackage == null) {
11376            if (mAlwaysFinishActivities || mController != null) {
11377                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11378                        + " mController=" + mController);
11379            }
11380            if (dumpAll) {
11381                pw.println("  Total persistent processes: " + numPers);
11382                pw.println("  mProcessesReady=" + mProcessesReady
11383                        + " mSystemReady=" + mSystemReady);
11384                pw.println("  mBooting=" + mBooting
11385                        + " mBooted=" + mBooted
11386                        + " mFactoryTest=" + mFactoryTest);
11387                pw.print("  mLastPowerCheckRealtime=");
11388                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11389                        pw.println("");
11390                pw.print("  mLastPowerCheckUptime=");
11391                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11392                        pw.println("");
11393                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11394                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11395                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11396                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11397                        + " (" + mLruProcesses.size() + " total)"
11398                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11399                        + " mNumServiceProcs=" + mNumServiceProcs
11400                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11401                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11402                        + " mLastMemoryLevel" + mLastMemoryLevel
11403                        + " mLastNumProcesses" + mLastNumProcesses);
11404                long now = SystemClock.uptimeMillis();
11405                pw.print("  mLastIdleTime=");
11406                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11407                        pw.print(" mLowRamSinceLastIdle=");
11408                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11409                        pw.println();
11410            }
11411        }
11412
11413        if (!printedAnything) {
11414            pw.println("  (nothing)");
11415        }
11416    }
11417
11418    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11419            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11420        if (mProcessesToGc.size() > 0) {
11421            boolean printed = false;
11422            long now = SystemClock.uptimeMillis();
11423            for (int i=0; i<mProcessesToGc.size(); i++) {
11424                ProcessRecord proc = mProcessesToGc.get(i);
11425                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11426                    continue;
11427                }
11428                if (!printed) {
11429                    if (needSep) pw.println();
11430                    needSep = true;
11431                    pw.println("  Processes that are waiting to GC:");
11432                    printed = true;
11433                }
11434                pw.print("    Process "); pw.println(proc);
11435                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11436                        pw.print(", last gced=");
11437                        pw.print(now-proc.lastRequestedGc);
11438                        pw.print(" ms ago, last lowMem=");
11439                        pw.print(now-proc.lastLowMemory);
11440                        pw.println(" ms ago");
11441
11442            }
11443        }
11444        return needSep;
11445    }
11446
11447    void printOomLevel(PrintWriter pw, String name, int adj) {
11448        pw.print("    ");
11449        if (adj >= 0) {
11450            pw.print(' ');
11451            if (adj < 10) pw.print(' ');
11452        } else {
11453            if (adj > -10) pw.print(' ');
11454        }
11455        pw.print(adj);
11456        pw.print(": ");
11457        pw.print(name);
11458        pw.print(" (");
11459        pw.print(mProcessList.getMemLevel(adj)/1024);
11460        pw.println(" kB)");
11461    }
11462
11463    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11464            int opti, boolean dumpAll) {
11465        boolean needSep = false;
11466
11467        if (mLruProcesses.size() > 0) {
11468            if (needSep) pw.println();
11469            needSep = true;
11470            pw.println("  OOM levels:");
11471            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11472            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11473            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11474            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11475            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11476            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11477            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11478            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11479            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11480            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11481            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11482            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11483            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11484
11485            if (needSep) pw.println();
11486            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11487                    pw.print(" total, non-act at ");
11488                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11489                    pw.print(", non-svc at ");
11490                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11491                    pw.println("):");
11492            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11493            needSep = true;
11494        }
11495
11496        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11497
11498        pw.println();
11499        pw.println("  mHomeProcess: " + mHomeProcess);
11500        pw.println("  mPreviousProcess: " + mPreviousProcess);
11501        if (mHeavyWeightProcess != null) {
11502            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11503        }
11504
11505        return true;
11506    }
11507
11508    /**
11509     * There are three ways to call this:
11510     *  - no provider specified: dump all the providers
11511     *  - a flattened component name that matched an existing provider was specified as the
11512     *    first arg: dump that one provider
11513     *  - the first arg isn't the flattened component name of an existing provider:
11514     *    dump all providers whose component contains the first arg as a substring
11515     */
11516    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11517            int opti, boolean dumpAll) {
11518        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11519    }
11520
11521    static class ItemMatcher {
11522        ArrayList<ComponentName> components;
11523        ArrayList<String> strings;
11524        ArrayList<Integer> objects;
11525        boolean all;
11526
11527        ItemMatcher() {
11528            all = true;
11529        }
11530
11531        void build(String name) {
11532            ComponentName componentName = ComponentName.unflattenFromString(name);
11533            if (componentName != null) {
11534                if (components == null) {
11535                    components = new ArrayList<ComponentName>();
11536                }
11537                components.add(componentName);
11538                all = false;
11539            } else {
11540                int objectId = 0;
11541                // Not a '/' separated full component name; maybe an object ID?
11542                try {
11543                    objectId = Integer.parseInt(name, 16);
11544                    if (objects == null) {
11545                        objects = new ArrayList<Integer>();
11546                    }
11547                    objects.add(objectId);
11548                    all = false;
11549                } catch (RuntimeException e) {
11550                    // Not an integer; just do string match.
11551                    if (strings == null) {
11552                        strings = new ArrayList<String>();
11553                    }
11554                    strings.add(name);
11555                    all = false;
11556                }
11557            }
11558        }
11559
11560        int build(String[] args, int opti) {
11561            for (; opti<args.length; opti++) {
11562                String name = args[opti];
11563                if ("--".equals(name)) {
11564                    return opti+1;
11565                }
11566                build(name);
11567            }
11568            return opti;
11569        }
11570
11571        boolean match(Object object, ComponentName comp) {
11572            if (all) {
11573                return true;
11574            }
11575            if (components != null) {
11576                for (int i=0; i<components.size(); i++) {
11577                    if (components.get(i).equals(comp)) {
11578                        return true;
11579                    }
11580                }
11581            }
11582            if (objects != null) {
11583                for (int i=0; i<objects.size(); i++) {
11584                    if (System.identityHashCode(object) == objects.get(i)) {
11585                        return true;
11586                    }
11587                }
11588            }
11589            if (strings != null) {
11590                String flat = comp.flattenToString();
11591                for (int i=0; i<strings.size(); i++) {
11592                    if (flat.contains(strings.get(i))) {
11593                        return true;
11594                    }
11595                }
11596            }
11597            return false;
11598        }
11599    }
11600
11601    /**
11602     * There are three things that cmd can be:
11603     *  - a flattened component name that matches an existing activity
11604     *  - the cmd arg isn't the flattened component name of an existing activity:
11605     *    dump all activity whose component contains the cmd as a substring
11606     *  - A hex number of the ActivityRecord object instance.
11607     */
11608    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11609            int opti, boolean dumpAll) {
11610        ArrayList<ActivityRecord> activities;
11611
11612        synchronized (this) {
11613            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11614        }
11615
11616        if (activities.size() <= 0) {
11617            return false;
11618        }
11619
11620        String[] newArgs = new String[args.length - opti];
11621        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11622
11623        TaskRecord lastTask = null;
11624        boolean needSep = false;
11625        for (int i=activities.size()-1; i>=0; i--) {
11626            ActivityRecord r = activities.get(i);
11627            if (needSep) {
11628                pw.println();
11629            }
11630            needSep = true;
11631            synchronized (this) {
11632                if (lastTask != r.task) {
11633                    lastTask = r.task;
11634                    pw.print("TASK "); pw.print(lastTask.affinity);
11635                            pw.print(" id="); pw.println(lastTask.taskId);
11636                    if (dumpAll) {
11637                        lastTask.dump(pw, "  ");
11638                    }
11639                }
11640            }
11641            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11642        }
11643        return true;
11644    }
11645
11646    /**
11647     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11648     * there is a thread associated with the activity.
11649     */
11650    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11651            final ActivityRecord r, String[] args, boolean dumpAll) {
11652        String innerPrefix = prefix + "  ";
11653        synchronized (this) {
11654            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11655                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11656                    pw.print(" pid=");
11657                    if (r.app != null) pw.println(r.app.pid);
11658                    else pw.println("(not running)");
11659            if (dumpAll) {
11660                r.dump(pw, innerPrefix);
11661            }
11662        }
11663        if (r.app != null && r.app.thread != null) {
11664            // flush anything that is already in the PrintWriter since the thread is going
11665            // to write to the file descriptor directly
11666            pw.flush();
11667            try {
11668                TransferPipe tp = new TransferPipe();
11669                try {
11670                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11671                            r.appToken, innerPrefix, args);
11672                    tp.go(fd);
11673                } finally {
11674                    tp.kill();
11675                }
11676            } catch (IOException e) {
11677                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11678            } catch (RemoteException e) {
11679                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11680            }
11681        }
11682    }
11683
11684    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11685            int opti, boolean dumpAll, String dumpPackage) {
11686        boolean needSep = false;
11687        boolean onlyHistory = false;
11688        boolean printedAnything = false;
11689
11690        if ("history".equals(dumpPackage)) {
11691            if (opti < args.length && "-s".equals(args[opti])) {
11692                dumpAll = false;
11693            }
11694            onlyHistory = true;
11695            dumpPackage = null;
11696        }
11697
11698        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11699        if (!onlyHistory && dumpAll) {
11700            if (mRegisteredReceivers.size() > 0) {
11701                boolean printed = false;
11702                Iterator it = mRegisteredReceivers.values().iterator();
11703                while (it.hasNext()) {
11704                    ReceiverList r = (ReceiverList)it.next();
11705                    if (dumpPackage != null && (r.app == null ||
11706                            !dumpPackage.equals(r.app.info.packageName))) {
11707                        continue;
11708                    }
11709                    if (!printed) {
11710                        pw.println("  Registered Receivers:");
11711                        needSep = true;
11712                        printed = true;
11713                        printedAnything = true;
11714                    }
11715                    pw.print("  * "); pw.println(r);
11716                    r.dump(pw, "    ");
11717                }
11718            }
11719
11720            if (mReceiverResolver.dump(pw, needSep ?
11721                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11722                    "    ", dumpPackage, false)) {
11723                needSep = true;
11724                printedAnything = true;
11725            }
11726        }
11727
11728        for (BroadcastQueue q : mBroadcastQueues) {
11729            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11730            printedAnything |= needSep;
11731        }
11732
11733        needSep = true;
11734
11735        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11736            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11737                if (needSep) {
11738                    pw.println();
11739                }
11740                needSep = true;
11741                printedAnything = true;
11742                pw.print("  Sticky broadcasts for user ");
11743                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11744                StringBuilder sb = new StringBuilder(128);
11745                for (Map.Entry<String, ArrayList<Intent>> ent
11746                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11747                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11748                    if (dumpAll) {
11749                        pw.println(":");
11750                        ArrayList<Intent> intents = ent.getValue();
11751                        final int N = intents.size();
11752                        for (int i=0; i<N; i++) {
11753                            sb.setLength(0);
11754                            sb.append("    Intent: ");
11755                            intents.get(i).toShortString(sb, false, true, false, false);
11756                            pw.println(sb.toString());
11757                            Bundle bundle = intents.get(i).getExtras();
11758                            if (bundle != null) {
11759                                pw.print("      ");
11760                                pw.println(bundle.toString());
11761                            }
11762                        }
11763                    } else {
11764                        pw.println("");
11765                    }
11766                }
11767            }
11768        }
11769
11770        if (!onlyHistory && dumpAll) {
11771            pw.println();
11772            for (BroadcastQueue queue : mBroadcastQueues) {
11773                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11774                        + queue.mBroadcastsScheduled);
11775            }
11776            pw.println("  mHandler:");
11777            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11778            needSep = true;
11779            printedAnything = true;
11780        }
11781
11782        if (!printedAnything) {
11783            pw.println("  (nothing)");
11784        }
11785    }
11786
11787    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11788            int opti, boolean dumpAll, String dumpPackage) {
11789        boolean needSep;
11790        boolean printedAnything = false;
11791
11792        ItemMatcher matcher = new ItemMatcher();
11793        matcher.build(args, opti);
11794
11795        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11796
11797        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11798        printedAnything |= needSep;
11799
11800        if (mLaunchingProviders.size() > 0) {
11801            boolean printed = false;
11802            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11803                ContentProviderRecord r = mLaunchingProviders.get(i);
11804                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11805                    continue;
11806                }
11807                if (!printed) {
11808                    if (needSep) pw.println();
11809                    needSep = true;
11810                    pw.println("  Launching content providers:");
11811                    printed = true;
11812                    printedAnything = true;
11813                }
11814                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11815                        pw.println(r);
11816            }
11817        }
11818
11819        if (mGrantedUriPermissions.size() > 0) {
11820            boolean printed = false;
11821            int dumpUid = -2;
11822            if (dumpPackage != null) {
11823                try {
11824                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11825                } catch (NameNotFoundException e) {
11826                    dumpUid = -1;
11827                }
11828            }
11829            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11830                int uid = mGrantedUriPermissions.keyAt(i);
11831                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11832                    continue;
11833                }
11834                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11835                if (!printed) {
11836                    if (needSep) pw.println();
11837                    needSep = true;
11838                    pw.println("  Granted Uri Permissions:");
11839                    printed = true;
11840                    printedAnything = true;
11841                }
11842                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11843                for (UriPermission perm : perms.values()) {
11844                    pw.print("    "); pw.println(perm);
11845                    if (dumpAll) {
11846                        perm.dump(pw, "      ");
11847                    }
11848                }
11849            }
11850        }
11851
11852        if (!printedAnything) {
11853            pw.println("  (nothing)");
11854        }
11855    }
11856
11857    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11858            int opti, boolean dumpAll, String dumpPackage) {
11859        boolean printed = false;
11860
11861        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11862
11863        if (mIntentSenderRecords.size() > 0) {
11864            Iterator<WeakReference<PendingIntentRecord>> it
11865                    = mIntentSenderRecords.values().iterator();
11866            while (it.hasNext()) {
11867                WeakReference<PendingIntentRecord> ref = it.next();
11868                PendingIntentRecord rec = ref != null ? ref.get(): null;
11869                if (dumpPackage != null && (rec == null
11870                        || !dumpPackage.equals(rec.key.packageName))) {
11871                    continue;
11872                }
11873                printed = true;
11874                if (rec != null) {
11875                    pw.print("  * "); pw.println(rec);
11876                    if (dumpAll) {
11877                        rec.dump(pw, "    ");
11878                    }
11879                } else {
11880                    pw.print("  * "); pw.println(ref);
11881                }
11882            }
11883        }
11884
11885        if (!printed) {
11886            pw.println("  (nothing)");
11887        }
11888    }
11889
11890    private static final int dumpProcessList(PrintWriter pw,
11891            ActivityManagerService service, List list,
11892            String prefix, String normalLabel, String persistentLabel,
11893            String dumpPackage) {
11894        int numPers = 0;
11895        final int N = list.size()-1;
11896        for (int i=N; i>=0; i--) {
11897            ProcessRecord r = (ProcessRecord)list.get(i);
11898            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11899                continue;
11900            }
11901            pw.println(String.format("%s%s #%2d: %s",
11902                    prefix, (r.persistent ? persistentLabel : normalLabel),
11903                    i, r.toString()));
11904            if (r.persistent) {
11905                numPers++;
11906            }
11907        }
11908        return numPers;
11909    }
11910
11911    private static final boolean dumpProcessOomList(PrintWriter pw,
11912            ActivityManagerService service, List<ProcessRecord> origList,
11913            String prefix, String normalLabel, String persistentLabel,
11914            boolean inclDetails, String dumpPackage) {
11915
11916        ArrayList<Pair<ProcessRecord, Integer>> list
11917                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11918        for (int i=0; i<origList.size(); i++) {
11919            ProcessRecord r = origList.get(i);
11920            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11921                continue;
11922            }
11923            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11924        }
11925
11926        if (list.size() <= 0) {
11927            return false;
11928        }
11929
11930        Comparator<Pair<ProcessRecord, Integer>> comparator
11931                = new Comparator<Pair<ProcessRecord, Integer>>() {
11932            @Override
11933            public int compare(Pair<ProcessRecord, Integer> object1,
11934                    Pair<ProcessRecord, Integer> object2) {
11935                if (object1.first.setAdj != object2.first.setAdj) {
11936                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11937                }
11938                if (object1.second.intValue() != object2.second.intValue()) {
11939                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11940                }
11941                return 0;
11942            }
11943        };
11944
11945        Collections.sort(list, comparator);
11946
11947        final long curRealtime = SystemClock.elapsedRealtime();
11948        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11949        final long curUptime = SystemClock.uptimeMillis();
11950        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11951
11952        for (int i=list.size()-1; i>=0; i--) {
11953            ProcessRecord r = list.get(i).first;
11954            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11955            char schedGroup;
11956            switch (r.setSchedGroup) {
11957                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11958                    schedGroup = 'B';
11959                    break;
11960                case Process.THREAD_GROUP_DEFAULT:
11961                    schedGroup = 'F';
11962                    break;
11963                default:
11964                    schedGroup = '?';
11965                    break;
11966            }
11967            char foreground;
11968            if (r.foregroundActivities) {
11969                foreground = 'A';
11970            } else if (r.foregroundServices) {
11971                foreground = 'S';
11972            } else {
11973                foreground = ' ';
11974            }
11975            String procState = ProcessList.makeProcStateString(r.curProcState);
11976            pw.print(prefix);
11977            pw.print(r.persistent ? persistentLabel : normalLabel);
11978            pw.print(" #");
11979            int num = (origList.size()-1)-list.get(i).second;
11980            if (num < 10) pw.print(' ');
11981            pw.print(num);
11982            pw.print(": ");
11983            pw.print(oomAdj);
11984            pw.print(' ');
11985            pw.print(schedGroup);
11986            pw.print('/');
11987            pw.print(foreground);
11988            pw.print('/');
11989            pw.print(procState);
11990            pw.print(" trm:");
11991            if (r.trimMemoryLevel < 10) pw.print(' ');
11992            pw.print(r.trimMemoryLevel);
11993            pw.print(' ');
11994            pw.print(r.toShortString());
11995            pw.print(" (");
11996            pw.print(r.adjType);
11997            pw.println(')');
11998            if (r.adjSource != null || r.adjTarget != null) {
11999                pw.print(prefix);
12000                pw.print("    ");
12001                if (r.adjTarget instanceof ComponentName) {
12002                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12003                } else if (r.adjTarget != null) {
12004                    pw.print(r.adjTarget.toString());
12005                } else {
12006                    pw.print("{null}");
12007                }
12008                pw.print("<=");
12009                if (r.adjSource instanceof ProcessRecord) {
12010                    pw.print("Proc{");
12011                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12012                    pw.println("}");
12013                } else if (r.adjSource != null) {
12014                    pw.println(r.adjSource.toString());
12015                } else {
12016                    pw.println("{null}");
12017                }
12018            }
12019            if (inclDetails) {
12020                pw.print(prefix);
12021                pw.print("    ");
12022                pw.print("oom: max="); pw.print(r.maxAdj);
12023                pw.print(" curRaw="); pw.print(r.curRawAdj);
12024                pw.print(" setRaw="); pw.print(r.setRawAdj);
12025                pw.print(" cur="); pw.print(r.curAdj);
12026                pw.print(" set="); pw.println(r.setAdj);
12027                pw.print(prefix);
12028                pw.print("    ");
12029                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12030                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12031                pw.print(" lastPss="); pw.print(r.lastPss);
12032                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12033                pw.print(prefix);
12034                pw.print("    ");
12035                pw.print("keeping="); pw.print(r.keeping);
12036                pw.print(" cached="); pw.print(r.cached);
12037                pw.print(" empty="); pw.print(r.empty);
12038                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12039
12040                if (!r.keeping) {
12041                    if (r.lastWakeTime != 0) {
12042                        long wtime;
12043                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12044                        synchronized (stats) {
12045                            wtime = stats.getProcessWakeTime(r.info.uid,
12046                                    r.pid, curRealtime);
12047                        }
12048                        long timeUsed = wtime - r.lastWakeTime;
12049                        pw.print(prefix);
12050                        pw.print("    ");
12051                        pw.print("keep awake over ");
12052                        TimeUtils.formatDuration(realtimeSince, pw);
12053                        pw.print(" used ");
12054                        TimeUtils.formatDuration(timeUsed, pw);
12055                        pw.print(" (");
12056                        pw.print((timeUsed*100)/realtimeSince);
12057                        pw.println("%)");
12058                    }
12059                    if (r.lastCpuTime != 0) {
12060                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12061                        pw.print(prefix);
12062                        pw.print("    ");
12063                        pw.print("run cpu over ");
12064                        TimeUtils.formatDuration(uptimeSince, pw);
12065                        pw.print(" used ");
12066                        TimeUtils.formatDuration(timeUsed, pw);
12067                        pw.print(" (");
12068                        pw.print((timeUsed*100)/uptimeSince);
12069                        pw.println("%)");
12070                    }
12071                }
12072            }
12073        }
12074        return true;
12075    }
12076
12077    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12078        ArrayList<ProcessRecord> procs;
12079        synchronized (this) {
12080            if (args != null && args.length > start
12081                    && args[start].charAt(0) != '-') {
12082                procs = new ArrayList<ProcessRecord>();
12083                int pid = -1;
12084                try {
12085                    pid = Integer.parseInt(args[start]);
12086                } catch (NumberFormatException e) {
12087                }
12088                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12089                    ProcessRecord proc = mLruProcesses.get(i);
12090                    if (proc.pid == pid) {
12091                        procs.add(proc);
12092                    } else if (proc.processName.equals(args[start])) {
12093                        procs.add(proc);
12094                    }
12095                }
12096                if (procs.size() <= 0) {
12097                    return null;
12098                }
12099            } else {
12100                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12101            }
12102        }
12103        return procs;
12104    }
12105
12106    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12107            PrintWriter pw, String[] args) {
12108        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12109        if (procs == null) {
12110            pw.println("No process found for: " + args[0]);
12111            return;
12112        }
12113
12114        long uptime = SystemClock.uptimeMillis();
12115        long realtime = SystemClock.elapsedRealtime();
12116        pw.println("Applications Graphics Acceleration Info:");
12117        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12118
12119        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12120            ProcessRecord r = procs.get(i);
12121            if (r.thread != null) {
12122                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12123                pw.flush();
12124                try {
12125                    TransferPipe tp = new TransferPipe();
12126                    try {
12127                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12128                        tp.go(fd);
12129                    } finally {
12130                        tp.kill();
12131                    }
12132                } catch (IOException e) {
12133                    pw.println("Failure while dumping the app: " + r);
12134                    pw.flush();
12135                } catch (RemoteException e) {
12136                    pw.println("Got a RemoteException while dumping the app " + r);
12137                    pw.flush();
12138                }
12139            }
12140        }
12141    }
12142
12143    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12144        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12145        if (procs == null) {
12146            pw.println("No process found for: " + args[0]);
12147            return;
12148        }
12149
12150        pw.println("Applications Database Info:");
12151
12152        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12153            ProcessRecord r = procs.get(i);
12154            if (r.thread != null) {
12155                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12156                pw.flush();
12157                try {
12158                    TransferPipe tp = new TransferPipe();
12159                    try {
12160                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12161                        tp.go(fd);
12162                    } finally {
12163                        tp.kill();
12164                    }
12165                } catch (IOException e) {
12166                    pw.println("Failure while dumping the app: " + r);
12167                    pw.flush();
12168                } catch (RemoteException e) {
12169                    pw.println("Got a RemoteException while dumping the app " + r);
12170                    pw.flush();
12171                }
12172            }
12173        }
12174    }
12175
12176    final static class MemItem {
12177        final boolean isProc;
12178        final String label;
12179        final String shortLabel;
12180        final long pss;
12181        final int id;
12182        final boolean hasActivities;
12183        ArrayList<MemItem> subitems;
12184
12185        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12186                boolean _hasActivities) {
12187            isProc = true;
12188            label = _label;
12189            shortLabel = _shortLabel;
12190            pss = _pss;
12191            id = _id;
12192            hasActivities = _hasActivities;
12193        }
12194
12195        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12196            isProc = false;
12197            label = _label;
12198            shortLabel = _shortLabel;
12199            pss = _pss;
12200            id = _id;
12201            hasActivities = false;
12202        }
12203    }
12204
12205    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12206            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12207        if (sort && !isCompact) {
12208            Collections.sort(items, new Comparator<MemItem>() {
12209                @Override
12210                public int compare(MemItem lhs, MemItem rhs) {
12211                    if (lhs.pss < rhs.pss) {
12212                        return 1;
12213                    } else if (lhs.pss > rhs.pss) {
12214                        return -1;
12215                    }
12216                    return 0;
12217                }
12218            });
12219        }
12220
12221        for (int i=0; i<items.size(); i++) {
12222            MemItem mi = items.get(i);
12223            if (!isCompact) {
12224                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12225            } else if (mi.isProc) {
12226                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12227                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12228                pw.println(mi.hasActivities ? ",a" : ",e");
12229            } else {
12230                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12231                pw.println(mi.pss);
12232            }
12233            if (mi.subitems != null) {
12234                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12235                        true, isCompact);
12236            }
12237        }
12238    }
12239
12240    // These are in KB.
12241    static final long[] DUMP_MEM_BUCKETS = new long[] {
12242        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12243        120*1024, 160*1024, 200*1024,
12244        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12245        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12246    };
12247
12248    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12249            boolean stackLike) {
12250        int start = label.lastIndexOf('.');
12251        if (start >= 0) start++;
12252        else start = 0;
12253        int end = label.length();
12254        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12255            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12256                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12257                out.append(bucket);
12258                out.append(stackLike ? "MB." : "MB ");
12259                out.append(label, start, end);
12260                return;
12261            }
12262        }
12263        out.append(memKB/1024);
12264        out.append(stackLike ? "MB." : "MB ");
12265        out.append(label, start, end);
12266    }
12267
12268    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12269            ProcessList.NATIVE_ADJ,
12270            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12271            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12272            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12273            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12274            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12275    };
12276    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12277            "Native",
12278            "System", "Persistent", "Foreground",
12279            "Visible", "Perceptible",
12280            "Heavy Weight", "Backup",
12281            "A Services", "Home",
12282            "Previous", "B Services", "Cached"
12283    };
12284    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12285            "native",
12286            "sys", "pers", "fore",
12287            "vis", "percept",
12288            "heavy", "backup",
12289            "servicea", "home",
12290            "prev", "serviceb", "cached"
12291    };
12292
12293    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12294            long realtime, boolean isCheckinRequest, boolean isCompact) {
12295        if (isCheckinRequest || isCompact) {
12296            // short checkin version
12297            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12298        } else {
12299            pw.println("Applications Memory Usage (kB):");
12300            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12301        }
12302    }
12303
12304    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12305            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12306        boolean dumpDetails = false;
12307        boolean dumpFullDetails = false;
12308        boolean dumpDalvik = false;
12309        boolean oomOnly = false;
12310        boolean isCompact = false;
12311        boolean localOnly = false;
12312
12313        int opti = 0;
12314        while (opti < args.length) {
12315            String opt = args[opti];
12316            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12317                break;
12318            }
12319            opti++;
12320            if ("-a".equals(opt)) {
12321                dumpDetails = true;
12322                dumpFullDetails = true;
12323                dumpDalvik = true;
12324            } else if ("-d".equals(opt)) {
12325                dumpDalvik = true;
12326            } else if ("-c".equals(opt)) {
12327                isCompact = true;
12328            } else if ("--oom".equals(opt)) {
12329                oomOnly = true;
12330            } else if ("--local".equals(opt)) {
12331                localOnly = true;
12332            } else if ("-h".equals(opt)) {
12333                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12334                pw.println("  -a: include all available information for each process.");
12335                pw.println("  -d: include dalvik details when dumping process details.");
12336                pw.println("  -c: dump in a compact machine-parseable representation.");
12337                pw.println("  --oom: only show processes organized by oom adj.");
12338                pw.println("  --local: only collect details locally, don't call process.");
12339                pw.println("If [process] is specified it can be the name or ");
12340                pw.println("pid of a specific process to dump.");
12341                return;
12342            } else {
12343                pw.println("Unknown argument: " + opt + "; use -h for help");
12344            }
12345        }
12346
12347        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12348        long uptime = SystemClock.uptimeMillis();
12349        long realtime = SystemClock.elapsedRealtime();
12350        final long[] tmpLong = new long[1];
12351
12352        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12353        if (procs == null) {
12354            // No Java processes.  Maybe they want to print a native process.
12355            if (args != null && args.length > opti
12356                    && args[opti].charAt(0) != '-') {
12357                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12358                        = new ArrayList<ProcessCpuTracker.Stats>();
12359                updateCpuStatsNow();
12360                int findPid = -1;
12361                try {
12362                    findPid = Integer.parseInt(args[opti]);
12363                } catch (NumberFormatException e) {
12364                }
12365                synchronized (mProcessCpuThread) {
12366                    final int N = mProcessCpuTracker.countStats();
12367                    for (int i=0; i<N; i++) {
12368                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12369                        if (st.pid == findPid || (st.baseName != null
12370                                && st.baseName.equals(args[opti]))) {
12371                            nativeProcs.add(st);
12372                        }
12373                    }
12374                }
12375                if (nativeProcs.size() > 0) {
12376                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12377                            isCompact);
12378                    Debug.MemoryInfo mi = null;
12379                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12380                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12381                        final int pid = r.pid;
12382                        if (!isCheckinRequest && dumpDetails) {
12383                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12384                        }
12385                        if (mi == null) {
12386                            mi = new Debug.MemoryInfo();
12387                        }
12388                        if (dumpDetails || (!brief && !oomOnly)) {
12389                            Debug.getMemoryInfo(pid, mi);
12390                        } else {
12391                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12392                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12393                        }
12394                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12395                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12396                        if (isCheckinRequest) {
12397                            pw.println();
12398                        }
12399                    }
12400                    return;
12401                }
12402            }
12403            pw.println("No process found for: " + args[opti]);
12404            return;
12405        }
12406
12407        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12408            dumpDetails = true;
12409        }
12410
12411        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12412
12413        String[] innerArgs = new String[args.length-opti];
12414        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12415
12416        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12417        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12418        long nativePss=0, dalvikPss=0, otherPss=0;
12419        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12420
12421        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12422        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12423                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12424
12425        long totalPss = 0;
12426        long cachedPss = 0;
12427
12428        Debug.MemoryInfo mi = null;
12429        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12430            final ProcessRecord r = procs.get(i);
12431            final IApplicationThread thread;
12432            final int pid;
12433            final int oomAdj;
12434            final boolean hasActivities;
12435            synchronized (this) {
12436                thread = r.thread;
12437                pid = r.pid;
12438                oomAdj = r.getSetAdjWithServices();
12439                hasActivities = r.activities.size() > 0;
12440            }
12441            if (thread != null) {
12442                if (!isCheckinRequest && dumpDetails) {
12443                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12444                }
12445                if (mi == null) {
12446                    mi = new Debug.MemoryInfo();
12447                }
12448                if (dumpDetails || (!brief && !oomOnly)) {
12449                    Debug.getMemoryInfo(pid, mi);
12450                } else {
12451                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12452                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12453                }
12454                if (dumpDetails) {
12455                    if (localOnly) {
12456                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12457                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12458                        if (isCheckinRequest) {
12459                            pw.println();
12460                        }
12461                    } else {
12462                        try {
12463                            pw.flush();
12464                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12465                                    dumpDalvik, innerArgs);
12466                        } catch (RemoteException e) {
12467                            if (!isCheckinRequest) {
12468                                pw.println("Got RemoteException!");
12469                                pw.flush();
12470                            }
12471                        }
12472                    }
12473                }
12474
12475                final long myTotalPss = mi.getTotalPss();
12476                final long myTotalUss = mi.getTotalUss();
12477
12478                synchronized (this) {
12479                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12480                        // Record this for posterity if the process has been stable.
12481                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12482                    }
12483                }
12484
12485                if (!isCheckinRequest && mi != null) {
12486                    totalPss += myTotalPss;
12487                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12488                            (hasActivities ? " / activities)" : ")"),
12489                            r.processName, myTotalPss, pid, hasActivities);
12490                    procMems.add(pssItem);
12491                    procMemsMap.put(pid, pssItem);
12492
12493                    nativePss += mi.nativePss;
12494                    dalvikPss += mi.dalvikPss;
12495                    otherPss += mi.otherPss;
12496                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12497                        long mem = mi.getOtherPss(j);
12498                        miscPss[j] += mem;
12499                        otherPss -= mem;
12500                    }
12501
12502                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12503                        cachedPss += myTotalPss;
12504                    }
12505
12506                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12507                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12508                                || oomIndex == (oomPss.length-1)) {
12509                            oomPss[oomIndex] += myTotalPss;
12510                            if (oomProcs[oomIndex] == null) {
12511                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12512                            }
12513                            oomProcs[oomIndex].add(pssItem);
12514                            break;
12515                        }
12516                    }
12517                }
12518            }
12519        }
12520
12521        if (!isCheckinRequest && procs.size() > 1) {
12522            // If we are showing aggregations, also look for native processes to
12523            // include so that our aggregations are more accurate.
12524            updateCpuStatsNow();
12525            synchronized (mProcessCpuThread) {
12526                final int N = mProcessCpuTracker.countStats();
12527                for (int i=0; i<N; i++) {
12528                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12529                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12530                        if (mi == null) {
12531                            mi = new Debug.MemoryInfo();
12532                        }
12533                        if (!brief && !oomOnly) {
12534                            Debug.getMemoryInfo(st.pid, mi);
12535                        } else {
12536                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12537                            mi.nativePrivateDirty = (int)tmpLong[0];
12538                        }
12539
12540                        final long myTotalPss = mi.getTotalPss();
12541                        totalPss += myTotalPss;
12542
12543                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12544                                st.name, myTotalPss, st.pid, false);
12545                        procMems.add(pssItem);
12546
12547                        nativePss += mi.nativePss;
12548                        dalvikPss += mi.dalvikPss;
12549                        otherPss += mi.otherPss;
12550                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12551                            long mem = mi.getOtherPss(j);
12552                            miscPss[j] += mem;
12553                            otherPss -= mem;
12554                        }
12555                        oomPss[0] += myTotalPss;
12556                        if (oomProcs[0] == null) {
12557                            oomProcs[0] = new ArrayList<MemItem>();
12558                        }
12559                        oomProcs[0].add(pssItem);
12560                    }
12561                }
12562            }
12563
12564            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12565
12566            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12567            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12568            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12569            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12570                String label = Debug.MemoryInfo.getOtherLabel(j);
12571                catMems.add(new MemItem(label, label, miscPss[j], j));
12572            }
12573
12574            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12575            for (int j=0; j<oomPss.length; j++) {
12576                if (oomPss[j] != 0) {
12577                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12578                            : DUMP_MEM_OOM_LABEL[j];
12579                    MemItem item = new MemItem(label, label, oomPss[j],
12580                            DUMP_MEM_OOM_ADJ[j]);
12581                    item.subitems = oomProcs[j];
12582                    oomMems.add(item);
12583                }
12584            }
12585
12586            if (!brief && !oomOnly && !isCompact) {
12587                pw.println();
12588                pw.println("Total PSS by process:");
12589                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12590                pw.println();
12591            }
12592            if (!isCompact) {
12593                pw.println("Total PSS by OOM adjustment:");
12594            }
12595            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12596            if (!brief && !oomOnly) {
12597                PrintWriter out = categoryPw != null ? categoryPw : pw;
12598                if (!isCompact) {
12599                    out.println();
12600                    out.println("Total PSS by category:");
12601                }
12602                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12603            }
12604            if (!isCompact) {
12605                pw.println();
12606            }
12607            MemInfoReader memInfo = new MemInfoReader();
12608            memInfo.readMemInfo();
12609            if (!brief) {
12610                if (!isCompact) {
12611                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12612                    pw.print(" kB (status ");
12613                    switch (mLastMemoryLevel) {
12614                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12615                            pw.println("normal)");
12616                            break;
12617                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12618                            pw.println("moderate)");
12619                            break;
12620                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12621                            pw.println("low)");
12622                            break;
12623                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12624                            pw.println("critical)");
12625                            break;
12626                        default:
12627                            pw.print(mLastMemoryLevel);
12628                            pw.println(")");
12629                            break;
12630                    }
12631                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12632                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12633                            pw.print(cachedPss); pw.print(" cached pss + ");
12634                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12635                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12636                } else {
12637                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12638                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12639                            + memInfo.getFreeSizeKb()); pw.print(",");
12640                    pw.println(totalPss - cachedPss);
12641                }
12642            }
12643            if (!isCompact) {
12644                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12645                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12646                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12647                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12648                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12649                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12650                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12651                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12652                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12653                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12654                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12655            }
12656            if (!brief) {
12657                if (memInfo.getZramTotalSizeKb() != 0) {
12658                    if (!isCompact) {
12659                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12660                                pw.print(" kB physical used for ");
12661                                pw.print(memInfo.getSwapTotalSizeKb()
12662                                        - memInfo.getSwapFreeSizeKb());
12663                                pw.print(" kB in swap (");
12664                                pw.print(memInfo.getSwapTotalSizeKb());
12665                                pw.println(" kB total swap)");
12666                    } else {
12667                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12668                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12669                                pw.println(memInfo.getSwapFreeSizeKb());
12670                    }
12671                }
12672                final int[] SINGLE_LONG_FORMAT = new int[] {
12673                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12674                };
12675                long[] longOut = new long[1];
12676                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12677                        SINGLE_LONG_FORMAT, null, longOut, null);
12678                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12679                longOut[0] = 0;
12680                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12681                        SINGLE_LONG_FORMAT, null, longOut, null);
12682                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12683                longOut[0] = 0;
12684                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12685                        SINGLE_LONG_FORMAT, null, longOut, null);
12686                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12687                longOut[0] = 0;
12688                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12689                        SINGLE_LONG_FORMAT, null, longOut, null);
12690                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12691                if (!isCompact) {
12692                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12693                        pw.print("      KSM: "); pw.print(sharing);
12694                                pw.print(" kB saved from shared ");
12695                                pw.print(shared); pw.println(" kB");
12696                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12697                                pw.print(voltile); pw.println(" kB volatile");
12698                    }
12699                    pw.print("   Tuning: ");
12700                    pw.print(ActivityManager.staticGetMemoryClass());
12701                    pw.print(" (large ");
12702                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12703                    pw.print("), oom ");
12704                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12705                    pw.print(" kB");
12706                    pw.print(", restore limit ");
12707                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12708                    pw.print(" kB");
12709                    if (ActivityManager.isLowRamDeviceStatic()) {
12710                        pw.print(" (low-ram)");
12711                    }
12712                    if (ActivityManager.isHighEndGfx()) {
12713                        pw.print(" (high-end-gfx)");
12714                    }
12715                    pw.println();
12716                } else {
12717                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12718                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12719                    pw.println(voltile);
12720                    pw.print("tuning,");
12721                    pw.print(ActivityManager.staticGetMemoryClass());
12722                    pw.print(',');
12723                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12724                    pw.print(',');
12725                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12726                    if (ActivityManager.isLowRamDeviceStatic()) {
12727                        pw.print(",low-ram");
12728                    }
12729                    if (ActivityManager.isHighEndGfx()) {
12730                        pw.print(",high-end-gfx");
12731                    }
12732                    pw.println();
12733                }
12734            }
12735        }
12736    }
12737
12738    /**
12739     * Searches array of arguments for the specified string
12740     * @param args array of argument strings
12741     * @param value value to search for
12742     * @return true if the value is contained in the array
12743     */
12744    private static boolean scanArgs(String[] args, String value) {
12745        if (args != null) {
12746            for (String arg : args) {
12747                if (value.equals(arg)) {
12748                    return true;
12749                }
12750            }
12751        }
12752        return false;
12753    }
12754
12755    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12756            ContentProviderRecord cpr, boolean always) {
12757        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12758
12759        if (!inLaunching || always) {
12760            synchronized (cpr) {
12761                cpr.launchingApp = null;
12762                cpr.notifyAll();
12763            }
12764            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12765            String names[] = cpr.info.authority.split(";");
12766            for (int j = 0; j < names.length; j++) {
12767                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12768            }
12769        }
12770
12771        for (int i=0; i<cpr.connections.size(); i++) {
12772            ContentProviderConnection conn = cpr.connections.get(i);
12773            if (conn.waiting) {
12774                // If this connection is waiting for the provider, then we don't
12775                // need to mess with its process unless we are always removing
12776                // or for some reason the provider is not currently launching.
12777                if (inLaunching && !always) {
12778                    continue;
12779                }
12780            }
12781            ProcessRecord capp = conn.client;
12782            conn.dead = true;
12783            if (conn.stableCount > 0) {
12784                if (!capp.persistent && capp.thread != null
12785                        && capp.pid != 0
12786                        && capp.pid != MY_PID) {
12787                    killUnneededProcessLocked(capp, "depends on provider "
12788                            + cpr.name.flattenToShortString()
12789                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12790                }
12791            } else if (capp.thread != null && conn.provider.provider != null) {
12792                try {
12793                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12794                } catch (RemoteException e) {
12795                }
12796                // In the protocol here, we don't expect the client to correctly
12797                // clean up this connection, we'll just remove it.
12798                cpr.connections.remove(i);
12799                conn.client.conProviders.remove(conn);
12800            }
12801        }
12802
12803        if (inLaunching && always) {
12804            mLaunchingProviders.remove(cpr);
12805        }
12806        return inLaunching;
12807    }
12808
12809    /**
12810     * Main code for cleaning up a process when it has gone away.  This is
12811     * called both as a result of the process dying, or directly when stopping
12812     * a process when running in single process mode.
12813     */
12814    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12815            boolean restarting, boolean allowRestart, int index) {
12816        if (index >= 0) {
12817            removeLruProcessLocked(app);
12818            ProcessList.remove(app.pid);
12819        }
12820
12821        mProcessesToGc.remove(app);
12822        mPendingPssProcesses.remove(app);
12823
12824        // Dismiss any open dialogs.
12825        if (app.crashDialog != null && !app.forceCrashReport) {
12826            app.crashDialog.dismiss();
12827            app.crashDialog = null;
12828        }
12829        if (app.anrDialog != null) {
12830            app.anrDialog.dismiss();
12831            app.anrDialog = null;
12832        }
12833        if (app.waitDialog != null) {
12834            app.waitDialog.dismiss();
12835            app.waitDialog = null;
12836        }
12837
12838        app.crashing = false;
12839        app.notResponding = false;
12840
12841        app.resetPackageList(mProcessStats);
12842        app.unlinkDeathRecipient();
12843        app.makeInactive(mProcessStats);
12844        app.forcingToForeground = null;
12845        updateProcessForegroundLocked(app, false, false);
12846        app.foregroundActivities = false;
12847        app.hasShownUi = false;
12848        app.treatLikeActivity = false;
12849        app.hasAboveClient = false;
12850        app.hasClientActivities = false;
12851
12852        mServices.killServicesLocked(app, allowRestart);
12853
12854        boolean restart = false;
12855
12856        // Remove published content providers.
12857        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12858            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12859            final boolean always = app.bad || !allowRestart;
12860            if (removeDyingProviderLocked(app, cpr, always) || always) {
12861                // We left the provider in the launching list, need to
12862                // restart it.
12863                restart = true;
12864            }
12865
12866            cpr.provider = null;
12867            cpr.proc = null;
12868        }
12869        app.pubProviders.clear();
12870
12871        // Take care of any launching providers waiting for this process.
12872        if (checkAppInLaunchingProvidersLocked(app, false)) {
12873            restart = true;
12874        }
12875
12876        // Unregister from connected content providers.
12877        if (!app.conProviders.isEmpty()) {
12878            for (int i=0; i<app.conProviders.size(); i++) {
12879                ContentProviderConnection conn = app.conProviders.get(i);
12880                conn.provider.connections.remove(conn);
12881            }
12882            app.conProviders.clear();
12883        }
12884
12885        // At this point there may be remaining entries in mLaunchingProviders
12886        // where we were the only one waiting, so they are no longer of use.
12887        // Look for these and clean up if found.
12888        // XXX Commented out for now.  Trying to figure out a way to reproduce
12889        // the actual situation to identify what is actually going on.
12890        if (false) {
12891            for (int i=0; i<mLaunchingProviders.size(); i++) {
12892                ContentProviderRecord cpr = (ContentProviderRecord)
12893                        mLaunchingProviders.get(i);
12894                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12895                    synchronized (cpr) {
12896                        cpr.launchingApp = null;
12897                        cpr.notifyAll();
12898                    }
12899                }
12900            }
12901        }
12902
12903        skipCurrentReceiverLocked(app);
12904
12905        // Unregister any receivers.
12906        for (int i=app.receivers.size()-1; i>=0; i--) {
12907            removeReceiverLocked(app.receivers.valueAt(i));
12908        }
12909        app.receivers.clear();
12910
12911        // If the app is undergoing backup, tell the backup manager about it
12912        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12913            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12914                    + mBackupTarget.appInfo + " died during backup");
12915            try {
12916                IBackupManager bm = IBackupManager.Stub.asInterface(
12917                        ServiceManager.getService(Context.BACKUP_SERVICE));
12918                bm.agentDisconnected(app.info.packageName);
12919            } catch (RemoteException e) {
12920                // can't happen; backup manager is local
12921            }
12922        }
12923
12924        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12925            ProcessChangeItem item = mPendingProcessChanges.get(i);
12926            if (item.pid == app.pid) {
12927                mPendingProcessChanges.remove(i);
12928                mAvailProcessChanges.add(item);
12929            }
12930        }
12931        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12932
12933        // If the caller is restarting this app, then leave it in its
12934        // current lists and let the caller take care of it.
12935        if (restarting) {
12936            return;
12937        }
12938
12939        if (!app.persistent || app.isolated) {
12940            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12941                    "Removing non-persistent process during cleanup: " + app);
12942            mProcessNames.remove(app.processName, app.uid);
12943            mIsolatedProcesses.remove(app.uid);
12944            if (mHeavyWeightProcess == app) {
12945                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12946                        mHeavyWeightProcess.userId, 0));
12947                mHeavyWeightProcess = null;
12948            }
12949        } else if (!app.removed) {
12950            // This app is persistent, so we need to keep its record around.
12951            // If it is not already on the pending app list, add it there
12952            // and start a new process for it.
12953            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12954                mPersistentStartingProcesses.add(app);
12955                restart = true;
12956            }
12957        }
12958        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12959                "Clean-up removing on hold: " + app);
12960        mProcessesOnHold.remove(app);
12961
12962        if (app == mHomeProcess) {
12963            mHomeProcess = null;
12964        }
12965        if (app == mPreviousProcess) {
12966            mPreviousProcess = null;
12967        }
12968
12969        if (restart && !app.isolated) {
12970            // We have components that still need to be running in the
12971            // process, so re-launch it.
12972            mProcessNames.put(app.processName, app.uid, app);
12973            startProcessLocked(app, "restart", app.processName);
12974        } else if (app.pid > 0 && app.pid != MY_PID) {
12975            // Goodbye!
12976            boolean removed;
12977            synchronized (mPidsSelfLocked) {
12978                mPidsSelfLocked.remove(app.pid);
12979                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12980            }
12981            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12982                    app.processName, app.info.uid);
12983            if (app.isolated) {
12984                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12985            }
12986            app.setPid(0);
12987        }
12988    }
12989
12990    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12991        // Look through the content providers we are waiting to have launched,
12992        // and if any run in this process then either schedule a restart of
12993        // the process or kill the client waiting for it if this process has
12994        // gone bad.
12995        int NL = mLaunchingProviders.size();
12996        boolean restart = false;
12997        for (int i=0; i<NL; i++) {
12998            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12999            if (cpr.launchingApp == app) {
13000                if (!alwaysBad && !app.bad) {
13001                    restart = true;
13002                } else {
13003                    removeDyingProviderLocked(app, cpr, true);
13004                    // cpr should have been removed from mLaunchingProviders
13005                    NL = mLaunchingProviders.size();
13006                    i--;
13007                }
13008            }
13009        }
13010        return restart;
13011    }
13012
13013    // =========================================================
13014    // SERVICES
13015    // =========================================================
13016
13017    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13018            int flags) {
13019        enforceNotIsolatedCaller("getServices");
13020        synchronized (this) {
13021            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13022        }
13023    }
13024
13025    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13026        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13027        synchronized (this) {
13028            return mServices.getRunningServiceControlPanelLocked(name);
13029        }
13030    }
13031
13032    public ComponentName startService(IApplicationThread caller, Intent service,
13033            String resolvedType, int userId) {
13034        enforceNotIsolatedCaller("startService");
13035        // Refuse possible leaked file descriptors
13036        if (service != null && service.hasFileDescriptors() == true) {
13037            throw new IllegalArgumentException("File descriptors passed in Intent");
13038        }
13039
13040        if (DEBUG_SERVICE)
13041            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13042        synchronized(this) {
13043            final int callingPid = Binder.getCallingPid();
13044            final int callingUid = Binder.getCallingUid();
13045            final long origId = Binder.clearCallingIdentity();
13046            ComponentName res = mServices.startServiceLocked(caller, service,
13047                    resolvedType, callingPid, callingUid, userId);
13048            Binder.restoreCallingIdentity(origId);
13049            return res;
13050        }
13051    }
13052
13053    ComponentName startServiceInPackage(int uid,
13054            Intent service, String resolvedType, int userId) {
13055        synchronized(this) {
13056            if (DEBUG_SERVICE)
13057                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13058            final long origId = Binder.clearCallingIdentity();
13059            ComponentName res = mServices.startServiceLocked(null, service,
13060                    resolvedType, -1, uid, userId);
13061            Binder.restoreCallingIdentity(origId);
13062            return res;
13063        }
13064    }
13065
13066    public int stopService(IApplicationThread caller, Intent service,
13067            String resolvedType, int userId) {
13068        enforceNotIsolatedCaller("stopService");
13069        // Refuse possible leaked file descriptors
13070        if (service != null && service.hasFileDescriptors() == true) {
13071            throw new IllegalArgumentException("File descriptors passed in Intent");
13072        }
13073
13074        synchronized(this) {
13075            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13076        }
13077    }
13078
13079    public IBinder peekService(Intent service, String resolvedType) {
13080        enforceNotIsolatedCaller("peekService");
13081        // Refuse possible leaked file descriptors
13082        if (service != null && service.hasFileDescriptors() == true) {
13083            throw new IllegalArgumentException("File descriptors passed in Intent");
13084        }
13085        synchronized(this) {
13086            return mServices.peekServiceLocked(service, resolvedType);
13087        }
13088    }
13089
13090    public boolean stopServiceToken(ComponentName className, IBinder token,
13091            int startId) {
13092        synchronized(this) {
13093            return mServices.stopServiceTokenLocked(className, token, startId);
13094        }
13095    }
13096
13097    public void setServiceForeground(ComponentName className, IBinder token,
13098            int id, Notification notification, boolean removeNotification) {
13099        synchronized(this) {
13100            mServices.setServiceForegroundLocked(className, token, id, notification,
13101                    removeNotification);
13102        }
13103    }
13104
13105    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13106            boolean requireFull, String name, String callerPackage) {
13107        final int callingUserId = UserHandle.getUserId(callingUid);
13108        if (callingUserId != userId) {
13109            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13110                if ((requireFull || checkComponentPermission(
13111                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13112                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13113                        && checkComponentPermission(
13114                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13115                                callingPid, callingUid, -1, true)
13116                                != PackageManager.PERMISSION_GRANTED) {
13117                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13118                        // In this case, they would like to just execute as their
13119                        // owner user instead of failing.
13120                        userId = callingUserId;
13121                    } else {
13122                        StringBuilder builder = new StringBuilder(128);
13123                        builder.append("Permission Denial: ");
13124                        builder.append(name);
13125                        if (callerPackage != null) {
13126                            builder.append(" from ");
13127                            builder.append(callerPackage);
13128                        }
13129                        builder.append(" asks to run as user ");
13130                        builder.append(userId);
13131                        builder.append(" but is calling from user ");
13132                        builder.append(UserHandle.getUserId(callingUid));
13133                        builder.append("; this requires ");
13134                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13135                        if (!requireFull) {
13136                            builder.append(" or ");
13137                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13138                        }
13139                        String msg = builder.toString();
13140                        Slog.w(TAG, msg);
13141                        throw new SecurityException(msg);
13142                    }
13143                }
13144            }
13145            if (userId == UserHandle.USER_CURRENT
13146                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13147                // Note that we may be accessing this outside of a lock...
13148                // shouldn't be a big deal, if this is being called outside
13149                // of a locked context there is intrinsically a race with
13150                // the value the caller will receive and someone else changing it.
13151                userId = mCurrentUserId;
13152            }
13153            if (!allowAll && userId < 0) {
13154                throw new IllegalArgumentException(
13155                        "Call does not support special user #" + userId);
13156            }
13157        }
13158        return userId;
13159    }
13160
13161    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13162            String className, int flags) {
13163        boolean result = false;
13164        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13165            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13166                if (ActivityManager.checkUidPermission(
13167                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13168                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13169                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13170                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13171                            + " requests FLAG_SINGLE_USER, but app does not hold "
13172                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13173                    Slog.w(TAG, msg);
13174                    throw new SecurityException(msg);
13175                }
13176                result = true;
13177            }
13178        } else if (componentProcessName == aInfo.packageName) {
13179            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13180        } else if ("system".equals(componentProcessName)) {
13181            result = true;
13182        }
13183        if (DEBUG_MU) {
13184            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13185                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13186        }
13187        return result;
13188    }
13189
13190    public int bindService(IApplicationThread caller, IBinder token,
13191            Intent service, String resolvedType,
13192            IServiceConnection connection, int flags, int userId) {
13193        enforceNotIsolatedCaller("bindService");
13194        // Refuse possible leaked file descriptors
13195        if (service != null && service.hasFileDescriptors() == true) {
13196            throw new IllegalArgumentException("File descriptors passed in Intent");
13197        }
13198
13199        synchronized(this) {
13200            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13201                    connection, flags, userId);
13202        }
13203    }
13204
13205    public boolean unbindService(IServiceConnection connection) {
13206        synchronized (this) {
13207            return mServices.unbindServiceLocked(connection);
13208        }
13209    }
13210
13211    public void publishService(IBinder token, Intent intent, IBinder service) {
13212        // Refuse possible leaked file descriptors
13213        if (intent != null && intent.hasFileDescriptors() == true) {
13214            throw new IllegalArgumentException("File descriptors passed in Intent");
13215        }
13216
13217        synchronized(this) {
13218            if (!(token instanceof ServiceRecord)) {
13219                throw new IllegalArgumentException("Invalid service token");
13220            }
13221            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13222        }
13223    }
13224
13225    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13226        // Refuse possible leaked file descriptors
13227        if (intent != null && intent.hasFileDescriptors() == true) {
13228            throw new IllegalArgumentException("File descriptors passed in Intent");
13229        }
13230
13231        synchronized(this) {
13232            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13233        }
13234    }
13235
13236    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13237        synchronized(this) {
13238            if (!(token instanceof ServiceRecord)) {
13239                throw new IllegalArgumentException("Invalid service token");
13240            }
13241            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13242        }
13243    }
13244
13245    // =========================================================
13246    // BACKUP AND RESTORE
13247    // =========================================================
13248
13249    // Cause the target app to be launched if necessary and its backup agent
13250    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13251    // activity manager to announce its creation.
13252    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13253        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13254        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13255
13256        synchronized(this) {
13257            // !!! TODO: currently no check here that we're already bound
13258            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13259            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13260            synchronized (stats) {
13261                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13262            }
13263
13264            // Backup agent is now in use, its package can't be stopped.
13265            try {
13266                AppGlobals.getPackageManager().setPackageStoppedState(
13267                        app.packageName, false, UserHandle.getUserId(app.uid));
13268            } catch (RemoteException e) {
13269            } catch (IllegalArgumentException e) {
13270                Slog.w(TAG, "Failed trying to unstop package "
13271                        + app.packageName + ": " + e);
13272            }
13273
13274            BackupRecord r = new BackupRecord(ss, app, backupMode);
13275            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13276                    ? new ComponentName(app.packageName, app.backupAgentName)
13277                    : new ComponentName("android", "FullBackupAgent");
13278            // startProcessLocked() returns existing proc's record if it's already running
13279            ProcessRecord proc = startProcessLocked(app.processName, app,
13280                    false, 0, "backup", hostingName, false, false, false);
13281            if (proc == null) {
13282                Slog.e(TAG, "Unable to start backup agent process " + r);
13283                return false;
13284            }
13285
13286            r.app = proc;
13287            mBackupTarget = r;
13288            mBackupAppName = app.packageName;
13289
13290            // Try not to kill the process during backup
13291            updateOomAdjLocked(proc);
13292
13293            // If the process is already attached, schedule the creation of the backup agent now.
13294            // If it is not yet live, this will be done when it attaches to the framework.
13295            if (proc.thread != null) {
13296                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13297                try {
13298                    proc.thread.scheduleCreateBackupAgent(app,
13299                            compatibilityInfoForPackageLocked(app), backupMode);
13300                } catch (RemoteException e) {
13301                    // Will time out on the backup manager side
13302                }
13303            } else {
13304                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13305            }
13306            // Invariants: at this point, the target app process exists and the application
13307            // is either already running or in the process of coming up.  mBackupTarget and
13308            // mBackupAppName describe the app, so that when it binds back to the AM we
13309            // know that it's scheduled for a backup-agent operation.
13310        }
13311
13312        return true;
13313    }
13314
13315    @Override
13316    public void clearPendingBackup() {
13317        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13318        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13319
13320        synchronized (this) {
13321            mBackupTarget = null;
13322            mBackupAppName = null;
13323        }
13324    }
13325
13326    // A backup agent has just come up
13327    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13328        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13329                + " = " + agent);
13330
13331        synchronized(this) {
13332            if (!agentPackageName.equals(mBackupAppName)) {
13333                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13334                return;
13335            }
13336        }
13337
13338        long oldIdent = Binder.clearCallingIdentity();
13339        try {
13340            IBackupManager bm = IBackupManager.Stub.asInterface(
13341                    ServiceManager.getService(Context.BACKUP_SERVICE));
13342            bm.agentConnected(agentPackageName, agent);
13343        } catch (RemoteException e) {
13344            // can't happen; the backup manager service is local
13345        } catch (Exception e) {
13346            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13347            e.printStackTrace();
13348        } finally {
13349            Binder.restoreCallingIdentity(oldIdent);
13350        }
13351    }
13352
13353    // done with this agent
13354    public void unbindBackupAgent(ApplicationInfo appInfo) {
13355        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13356        if (appInfo == null) {
13357            Slog.w(TAG, "unbind backup agent for null app");
13358            return;
13359        }
13360
13361        synchronized(this) {
13362            try {
13363                if (mBackupAppName == null) {
13364                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13365                    return;
13366                }
13367
13368                if (!mBackupAppName.equals(appInfo.packageName)) {
13369                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13370                    return;
13371                }
13372
13373                // Not backing this app up any more; reset its OOM adjustment
13374                final ProcessRecord proc = mBackupTarget.app;
13375                updateOomAdjLocked(proc);
13376
13377                // If the app crashed during backup, 'thread' will be null here
13378                if (proc.thread != null) {
13379                    try {
13380                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13381                                compatibilityInfoForPackageLocked(appInfo));
13382                    } catch (Exception e) {
13383                        Slog.e(TAG, "Exception when unbinding backup agent:");
13384                        e.printStackTrace();
13385                    }
13386                }
13387            } finally {
13388                mBackupTarget = null;
13389                mBackupAppName = null;
13390            }
13391        }
13392    }
13393    // =========================================================
13394    // BROADCASTS
13395    // =========================================================
13396
13397    private final List getStickiesLocked(String action, IntentFilter filter,
13398            List cur, int userId) {
13399        final ContentResolver resolver = mContext.getContentResolver();
13400        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13401        if (stickies == null) {
13402            return cur;
13403        }
13404        final ArrayList<Intent> list = stickies.get(action);
13405        if (list == null) {
13406            return cur;
13407        }
13408        int N = list.size();
13409        for (int i=0; i<N; i++) {
13410            Intent intent = list.get(i);
13411            if (filter.match(resolver, intent, true, TAG) >= 0) {
13412                if (cur == null) {
13413                    cur = new ArrayList<Intent>();
13414                }
13415                cur.add(intent);
13416            }
13417        }
13418        return cur;
13419    }
13420
13421    boolean isPendingBroadcastProcessLocked(int pid) {
13422        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13423                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13424    }
13425
13426    void skipPendingBroadcastLocked(int pid) {
13427            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13428            for (BroadcastQueue queue : mBroadcastQueues) {
13429                queue.skipPendingBroadcastLocked(pid);
13430            }
13431    }
13432
13433    // The app just attached; send any pending broadcasts that it should receive
13434    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13435        boolean didSomething = false;
13436        for (BroadcastQueue queue : mBroadcastQueues) {
13437            didSomething |= queue.sendPendingBroadcastsLocked(app);
13438        }
13439        return didSomething;
13440    }
13441
13442    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13443            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13444        enforceNotIsolatedCaller("registerReceiver");
13445        int callingUid;
13446        int callingPid;
13447        synchronized(this) {
13448            ProcessRecord callerApp = null;
13449            if (caller != null) {
13450                callerApp = getRecordForAppLocked(caller);
13451                if (callerApp == null) {
13452                    throw new SecurityException(
13453                            "Unable to find app for caller " + caller
13454                            + " (pid=" + Binder.getCallingPid()
13455                            + ") when registering receiver " + receiver);
13456                }
13457                if (callerApp.info.uid != Process.SYSTEM_UID &&
13458                        !callerApp.pkgList.containsKey(callerPackage) &&
13459                        !"android".equals(callerPackage)) {
13460                    throw new SecurityException("Given caller package " + callerPackage
13461                            + " is not running in process " + callerApp);
13462                }
13463                callingUid = callerApp.info.uid;
13464                callingPid = callerApp.pid;
13465            } else {
13466                callerPackage = null;
13467                callingUid = Binder.getCallingUid();
13468                callingPid = Binder.getCallingPid();
13469            }
13470
13471            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13472                    true, true, "registerReceiver", callerPackage);
13473
13474            List allSticky = null;
13475
13476            // Look for any matching sticky broadcasts...
13477            Iterator actions = filter.actionsIterator();
13478            if (actions != null) {
13479                while (actions.hasNext()) {
13480                    String action = (String)actions.next();
13481                    allSticky = getStickiesLocked(action, filter, allSticky,
13482                            UserHandle.USER_ALL);
13483                    allSticky = getStickiesLocked(action, filter, allSticky,
13484                            UserHandle.getUserId(callingUid));
13485                }
13486            } else {
13487                allSticky = getStickiesLocked(null, filter, allSticky,
13488                        UserHandle.USER_ALL);
13489                allSticky = getStickiesLocked(null, filter, allSticky,
13490                        UserHandle.getUserId(callingUid));
13491            }
13492
13493            // The first sticky in the list is returned directly back to
13494            // the client.
13495            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13496
13497            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13498                    + ": " + sticky);
13499
13500            if (receiver == null) {
13501                return sticky;
13502            }
13503
13504            ReceiverList rl
13505                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13506            if (rl == null) {
13507                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13508                        userId, receiver);
13509                if (rl.app != null) {
13510                    rl.app.receivers.add(rl);
13511                } else {
13512                    try {
13513                        receiver.asBinder().linkToDeath(rl, 0);
13514                    } catch (RemoteException e) {
13515                        return sticky;
13516                    }
13517                    rl.linkedToDeath = true;
13518                }
13519                mRegisteredReceivers.put(receiver.asBinder(), rl);
13520            } else if (rl.uid != callingUid) {
13521                throw new IllegalArgumentException(
13522                        "Receiver requested to register for uid " + callingUid
13523                        + " was previously registered for uid " + rl.uid);
13524            } else if (rl.pid != callingPid) {
13525                throw new IllegalArgumentException(
13526                        "Receiver requested to register for pid " + callingPid
13527                        + " was previously registered for pid " + rl.pid);
13528            } else if (rl.userId != userId) {
13529                throw new IllegalArgumentException(
13530                        "Receiver requested to register for user " + userId
13531                        + " was previously registered for user " + rl.userId);
13532            }
13533            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13534                    permission, callingUid, userId);
13535            rl.add(bf);
13536            if (!bf.debugCheck()) {
13537                Slog.w(TAG, "==> For Dynamic broadast");
13538            }
13539            mReceiverResolver.addFilter(bf);
13540
13541            // Enqueue broadcasts for all existing stickies that match
13542            // this filter.
13543            if (allSticky != null) {
13544                ArrayList receivers = new ArrayList();
13545                receivers.add(bf);
13546
13547                int N = allSticky.size();
13548                for (int i=0; i<N; i++) {
13549                    Intent intent = (Intent)allSticky.get(i);
13550                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13551                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13552                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13553                            null, null, false, true, true, -1);
13554                    queue.enqueueParallelBroadcastLocked(r);
13555                    queue.scheduleBroadcastsLocked();
13556                }
13557            }
13558
13559            return sticky;
13560        }
13561    }
13562
13563    public void unregisterReceiver(IIntentReceiver receiver) {
13564        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13565
13566        final long origId = Binder.clearCallingIdentity();
13567        try {
13568            boolean doTrim = false;
13569
13570            synchronized(this) {
13571                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13572                if (rl != null) {
13573                    if (rl.curBroadcast != null) {
13574                        BroadcastRecord r = rl.curBroadcast;
13575                        final boolean doNext = finishReceiverLocked(
13576                                receiver.asBinder(), r.resultCode, r.resultData,
13577                                r.resultExtras, r.resultAbort);
13578                        if (doNext) {
13579                            doTrim = true;
13580                            r.queue.processNextBroadcast(false);
13581                        }
13582                    }
13583
13584                    if (rl.app != null) {
13585                        rl.app.receivers.remove(rl);
13586                    }
13587                    removeReceiverLocked(rl);
13588                    if (rl.linkedToDeath) {
13589                        rl.linkedToDeath = false;
13590                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13591                    }
13592                }
13593            }
13594
13595            // If we actually concluded any broadcasts, we might now be able
13596            // to trim the recipients' apps from our working set
13597            if (doTrim) {
13598                trimApplications();
13599                return;
13600            }
13601
13602        } finally {
13603            Binder.restoreCallingIdentity(origId);
13604        }
13605    }
13606
13607    void removeReceiverLocked(ReceiverList rl) {
13608        mRegisteredReceivers.remove(rl.receiver.asBinder());
13609        int N = rl.size();
13610        for (int i=0; i<N; i++) {
13611            mReceiverResolver.removeFilter(rl.get(i));
13612        }
13613    }
13614
13615    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13616        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13617            ProcessRecord r = mLruProcesses.get(i);
13618            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13619                try {
13620                    r.thread.dispatchPackageBroadcast(cmd, packages);
13621                } catch (RemoteException ex) {
13622                }
13623            }
13624        }
13625    }
13626
13627    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13628            int[] users) {
13629        List<ResolveInfo> receivers = null;
13630        try {
13631            HashSet<ComponentName> singleUserReceivers = null;
13632            boolean scannedFirstReceivers = false;
13633            for (int user : users) {
13634                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13635                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13636                if (user != 0 && newReceivers != null) {
13637                    // If this is not the primary user, we need to check for
13638                    // any receivers that should be filtered out.
13639                    for (int i=0; i<newReceivers.size(); i++) {
13640                        ResolveInfo ri = newReceivers.get(i);
13641                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13642                            newReceivers.remove(i);
13643                            i--;
13644                        }
13645                    }
13646                }
13647                if (newReceivers != null && newReceivers.size() == 0) {
13648                    newReceivers = null;
13649                }
13650                if (receivers == null) {
13651                    receivers = newReceivers;
13652                } else if (newReceivers != null) {
13653                    // We need to concatenate the additional receivers
13654                    // found with what we have do far.  This would be easy,
13655                    // but we also need to de-dup any receivers that are
13656                    // singleUser.
13657                    if (!scannedFirstReceivers) {
13658                        // Collect any single user receivers we had already retrieved.
13659                        scannedFirstReceivers = true;
13660                        for (int i=0; i<receivers.size(); i++) {
13661                            ResolveInfo ri = receivers.get(i);
13662                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13663                                ComponentName cn = new ComponentName(
13664                                        ri.activityInfo.packageName, ri.activityInfo.name);
13665                                if (singleUserReceivers == null) {
13666                                    singleUserReceivers = new HashSet<ComponentName>();
13667                                }
13668                                singleUserReceivers.add(cn);
13669                            }
13670                        }
13671                    }
13672                    // Add the new results to the existing results, tracking
13673                    // and de-dupping single user receivers.
13674                    for (int i=0; i<newReceivers.size(); i++) {
13675                        ResolveInfo ri = newReceivers.get(i);
13676                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13677                            ComponentName cn = new ComponentName(
13678                                    ri.activityInfo.packageName, ri.activityInfo.name);
13679                            if (singleUserReceivers == null) {
13680                                singleUserReceivers = new HashSet<ComponentName>();
13681                            }
13682                            if (!singleUserReceivers.contains(cn)) {
13683                                singleUserReceivers.add(cn);
13684                                receivers.add(ri);
13685                            }
13686                        } else {
13687                            receivers.add(ri);
13688                        }
13689                    }
13690                }
13691            }
13692        } catch (RemoteException ex) {
13693            // pm is in same process, this will never happen.
13694        }
13695        return receivers;
13696    }
13697
13698    private final int broadcastIntentLocked(ProcessRecord callerApp,
13699            String callerPackage, Intent intent, String resolvedType,
13700            IIntentReceiver resultTo, int resultCode, String resultData,
13701            Bundle map, String requiredPermission, int appOp,
13702            boolean ordered, boolean sticky, int callingPid, int callingUid,
13703            int userId) {
13704        intent = new Intent(intent);
13705
13706        // By default broadcasts do not go to stopped apps.
13707        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13708
13709        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13710            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13711            + " ordered=" + ordered + " userid=" + userId);
13712        if ((resultTo != null) && !ordered) {
13713            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13714        }
13715
13716        userId = handleIncomingUser(callingPid, callingUid, userId,
13717                true, false, "broadcast", callerPackage);
13718
13719        // Make sure that the user who is receiving this broadcast is started.
13720        // If not, we will just skip it.
13721        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13722            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13723                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13724                Slog.w(TAG, "Skipping broadcast of " + intent
13725                        + ": user " + userId + " is stopped");
13726                return ActivityManager.BROADCAST_SUCCESS;
13727            }
13728        }
13729
13730        /*
13731         * Prevent non-system code (defined here to be non-persistent
13732         * processes) from sending protected broadcasts.
13733         */
13734        int callingAppId = UserHandle.getAppId(callingUid);
13735        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13736            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13737            callingUid == 0) {
13738            // Always okay.
13739        } else if (callerApp == null || !callerApp.persistent) {
13740            try {
13741                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13742                        intent.getAction())) {
13743                    String msg = "Permission Denial: not allowed to send broadcast "
13744                            + intent.getAction() + " from pid="
13745                            + callingPid + ", uid=" + callingUid;
13746                    Slog.w(TAG, msg);
13747                    throw new SecurityException(msg);
13748                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13749                    // Special case for compatibility: we don't want apps to send this,
13750                    // but historically it has not been protected and apps may be using it
13751                    // to poke their own app widget.  So, instead of making it protected,
13752                    // just limit it to the caller.
13753                    if (callerApp == null) {
13754                        String msg = "Permission Denial: not allowed to send broadcast "
13755                                + intent.getAction() + " from unknown caller.";
13756                        Slog.w(TAG, msg);
13757                        throw new SecurityException(msg);
13758                    } else if (intent.getComponent() != null) {
13759                        // They are good enough to send to an explicit component...  verify
13760                        // it is being sent to the calling app.
13761                        if (!intent.getComponent().getPackageName().equals(
13762                                callerApp.info.packageName)) {
13763                            String msg = "Permission Denial: not allowed to send broadcast "
13764                                    + intent.getAction() + " to "
13765                                    + intent.getComponent().getPackageName() + " from "
13766                                    + callerApp.info.packageName;
13767                            Slog.w(TAG, msg);
13768                            throw new SecurityException(msg);
13769                        }
13770                    } else {
13771                        // Limit broadcast to their own package.
13772                        intent.setPackage(callerApp.info.packageName);
13773                    }
13774                }
13775            } catch (RemoteException e) {
13776                Slog.w(TAG, "Remote exception", e);
13777                return ActivityManager.BROADCAST_SUCCESS;
13778            }
13779        }
13780
13781        // Handle special intents: if this broadcast is from the package
13782        // manager about a package being removed, we need to remove all of
13783        // its activities from the history stack.
13784        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13785                intent.getAction());
13786        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13787                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13788                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13789                || uidRemoved) {
13790            if (checkComponentPermission(
13791                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13792                    callingPid, callingUid, -1, true)
13793                    == PackageManager.PERMISSION_GRANTED) {
13794                if (uidRemoved) {
13795                    final Bundle intentExtras = intent.getExtras();
13796                    final int uid = intentExtras != null
13797                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13798                    if (uid >= 0) {
13799                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13800                        synchronized (bs) {
13801                            bs.removeUidStatsLocked(uid);
13802                        }
13803                        mAppOpsService.uidRemoved(uid);
13804                    }
13805                } else {
13806                    // If resources are unavailable just force stop all
13807                    // those packages and flush the attribute cache as well.
13808                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13809                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13810                        if (list != null && (list.length > 0)) {
13811                            for (String pkg : list) {
13812                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13813                                        "storage unmount");
13814                            }
13815                            sendPackageBroadcastLocked(
13816                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13817                        }
13818                    } else {
13819                        Uri data = intent.getData();
13820                        String ssp;
13821                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13822                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13823                                    intent.getAction());
13824                            boolean fullUninstall = removed &&
13825                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13826                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13827                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13828                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13829                                        false, fullUninstall, userId,
13830                                        removed ? "pkg removed" : "pkg changed");
13831                            }
13832                            if (removed) {
13833                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13834                                        new String[] {ssp}, userId);
13835                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13836                                    mAppOpsService.packageRemoved(
13837                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13838
13839                                    // Remove all permissions granted from/to this package
13840                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13841                                }
13842                            }
13843                        }
13844                    }
13845                }
13846            } else {
13847                String msg = "Permission Denial: " + intent.getAction()
13848                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13849                        + ", uid=" + callingUid + ")"
13850                        + " requires "
13851                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13852                Slog.w(TAG, msg);
13853                throw new SecurityException(msg);
13854            }
13855
13856        // Special case for adding a package: by default turn on compatibility
13857        // mode.
13858        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13859            Uri data = intent.getData();
13860            String ssp;
13861            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13862                mCompatModePackages.handlePackageAddedLocked(ssp,
13863                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13864            }
13865        }
13866
13867        /*
13868         * If this is the time zone changed action, queue up a message that will reset the timezone
13869         * of all currently running processes. This message will get queued up before the broadcast
13870         * happens.
13871         */
13872        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13873            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13874        }
13875
13876        /*
13877         * If the user set the time, let all running processes know.
13878         */
13879        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13880            final int is24Hour = intent.getBooleanExtra(
13881                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13882            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13883        }
13884
13885        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13886            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13887        }
13888
13889        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13890            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13891            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13892        }
13893
13894        // Add to the sticky list if requested.
13895        if (sticky) {
13896            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13897                    callingPid, callingUid)
13898                    != PackageManager.PERMISSION_GRANTED) {
13899                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13900                        + callingPid + ", uid=" + callingUid
13901                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13902                Slog.w(TAG, msg);
13903                throw new SecurityException(msg);
13904            }
13905            if (requiredPermission != null) {
13906                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13907                        + " and enforce permission " + requiredPermission);
13908                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13909            }
13910            if (intent.getComponent() != null) {
13911                throw new SecurityException(
13912                        "Sticky broadcasts can't target a specific component");
13913            }
13914            // We use userId directly here, since the "all" target is maintained
13915            // as a separate set of sticky broadcasts.
13916            if (userId != UserHandle.USER_ALL) {
13917                // But first, if this is not a broadcast to all users, then
13918                // make sure it doesn't conflict with an existing broadcast to
13919                // all users.
13920                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13921                        UserHandle.USER_ALL);
13922                if (stickies != null) {
13923                    ArrayList<Intent> list = stickies.get(intent.getAction());
13924                    if (list != null) {
13925                        int N = list.size();
13926                        int i;
13927                        for (i=0; i<N; i++) {
13928                            if (intent.filterEquals(list.get(i))) {
13929                                throw new IllegalArgumentException(
13930                                        "Sticky broadcast " + intent + " for user "
13931                                        + userId + " conflicts with existing global broadcast");
13932                            }
13933                        }
13934                    }
13935                }
13936            }
13937            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13938            if (stickies == null) {
13939                stickies = new ArrayMap<String, ArrayList<Intent>>();
13940                mStickyBroadcasts.put(userId, stickies);
13941            }
13942            ArrayList<Intent> list = stickies.get(intent.getAction());
13943            if (list == null) {
13944                list = new ArrayList<Intent>();
13945                stickies.put(intent.getAction(), list);
13946            }
13947            int N = list.size();
13948            int i;
13949            for (i=0; i<N; i++) {
13950                if (intent.filterEquals(list.get(i))) {
13951                    // This sticky already exists, replace it.
13952                    list.set(i, new Intent(intent));
13953                    break;
13954                }
13955            }
13956            if (i >= N) {
13957                list.add(new Intent(intent));
13958            }
13959        }
13960
13961        int[] users;
13962        if (userId == UserHandle.USER_ALL) {
13963            // Caller wants broadcast to go to all started users.
13964            users = mStartedUserArray;
13965        } else {
13966            // Caller wants broadcast to go to one specific user.
13967            users = new int[] {userId};
13968        }
13969
13970        // Figure out who all will receive this broadcast.
13971        List receivers = null;
13972        List<BroadcastFilter> registeredReceivers = null;
13973        // Need to resolve the intent to interested receivers...
13974        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13975                 == 0) {
13976            receivers = collectReceiverComponents(intent, resolvedType, users);
13977        }
13978        if (intent.getComponent() == null) {
13979            registeredReceivers = mReceiverResolver.queryIntent(intent,
13980                    resolvedType, false, userId);
13981        }
13982
13983        final boolean replacePending =
13984                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13985
13986        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13987                + " replacePending=" + replacePending);
13988
13989        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13990        if (!ordered && NR > 0) {
13991            // If we are not serializing this broadcast, then send the
13992            // registered receivers separately so they don't wait for the
13993            // components to be launched.
13994            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13995            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13996                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13997                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13998                    ordered, sticky, false, userId);
13999            if (DEBUG_BROADCAST) Slog.v(
14000                    TAG, "Enqueueing parallel broadcast " + r);
14001            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14002            if (!replaced) {
14003                queue.enqueueParallelBroadcastLocked(r);
14004                queue.scheduleBroadcastsLocked();
14005            }
14006            registeredReceivers = null;
14007            NR = 0;
14008        }
14009
14010        // Merge into one list.
14011        int ir = 0;
14012        if (receivers != null) {
14013            // A special case for PACKAGE_ADDED: do not allow the package
14014            // being added to see this broadcast.  This prevents them from
14015            // using this as a back door to get run as soon as they are
14016            // installed.  Maybe in the future we want to have a special install
14017            // broadcast or such for apps, but we'd like to deliberately make
14018            // this decision.
14019            String skipPackages[] = null;
14020            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14021                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14022                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14023                Uri data = intent.getData();
14024                if (data != null) {
14025                    String pkgName = data.getSchemeSpecificPart();
14026                    if (pkgName != null) {
14027                        skipPackages = new String[] { pkgName };
14028                    }
14029                }
14030            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14031                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14032            }
14033            if (skipPackages != null && (skipPackages.length > 0)) {
14034                for (String skipPackage : skipPackages) {
14035                    if (skipPackage != null) {
14036                        int NT = receivers.size();
14037                        for (int it=0; it<NT; it++) {
14038                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14039                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14040                                receivers.remove(it);
14041                                it--;
14042                                NT--;
14043                            }
14044                        }
14045                    }
14046                }
14047            }
14048
14049            int NT = receivers != null ? receivers.size() : 0;
14050            int it = 0;
14051            ResolveInfo curt = null;
14052            BroadcastFilter curr = null;
14053            while (it < NT && ir < NR) {
14054                if (curt == null) {
14055                    curt = (ResolveInfo)receivers.get(it);
14056                }
14057                if (curr == null) {
14058                    curr = registeredReceivers.get(ir);
14059                }
14060                if (curr.getPriority() >= curt.priority) {
14061                    // Insert this broadcast record into the final list.
14062                    receivers.add(it, curr);
14063                    ir++;
14064                    curr = null;
14065                    it++;
14066                    NT++;
14067                } else {
14068                    // Skip to the next ResolveInfo in the final list.
14069                    it++;
14070                    curt = null;
14071                }
14072            }
14073        }
14074        while (ir < NR) {
14075            if (receivers == null) {
14076                receivers = new ArrayList();
14077            }
14078            receivers.add(registeredReceivers.get(ir));
14079            ir++;
14080        }
14081
14082        if ((receivers != null && receivers.size() > 0)
14083                || resultTo != null) {
14084            BroadcastQueue queue = broadcastQueueForIntent(intent);
14085            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14086                    callerPackage, callingPid, callingUid, resolvedType,
14087                    requiredPermission, appOp, receivers, resultTo, resultCode,
14088                    resultData, map, ordered, sticky, false, userId);
14089            if (DEBUG_BROADCAST) Slog.v(
14090                    TAG, "Enqueueing ordered broadcast " + r
14091                    + ": prev had " + queue.mOrderedBroadcasts.size());
14092            if (DEBUG_BROADCAST) {
14093                int seq = r.intent.getIntExtra("seq", -1);
14094                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14095            }
14096            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14097            if (!replaced) {
14098                queue.enqueueOrderedBroadcastLocked(r);
14099                queue.scheduleBroadcastsLocked();
14100            }
14101        }
14102
14103        return ActivityManager.BROADCAST_SUCCESS;
14104    }
14105
14106    final Intent verifyBroadcastLocked(Intent intent) {
14107        // Refuse possible leaked file descriptors
14108        if (intent != null && intent.hasFileDescriptors() == true) {
14109            throw new IllegalArgumentException("File descriptors passed in Intent");
14110        }
14111
14112        int flags = intent.getFlags();
14113
14114        if (!mProcessesReady) {
14115            // if the caller really truly claims to know what they're doing, go
14116            // ahead and allow the broadcast without launching any receivers
14117            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14118                intent = new Intent(intent);
14119                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14120            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14121                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14122                        + " before boot completion");
14123                throw new IllegalStateException("Cannot broadcast before boot completed");
14124            }
14125        }
14126
14127        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14128            throw new IllegalArgumentException(
14129                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14130        }
14131
14132        return intent;
14133    }
14134
14135    public final int broadcastIntent(IApplicationThread caller,
14136            Intent intent, String resolvedType, IIntentReceiver resultTo,
14137            int resultCode, String resultData, Bundle map,
14138            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14139        enforceNotIsolatedCaller("broadcastIntent");
14140        synchronized(this) {
14141            intent = verifyBroadcastLocked(intent);
14142
14143            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14144            final int callingPid = Binder.getCallingPid();
14145            final int callingUid = Binder.getCallingUid();
14146            final long origId = Binder.clearCallingIdentity();
14147            int res = broadcastIntentLocked(callerApp,
14148                    callerApp != null ? callerApp.info.packageName : null,
14149                    intent, resolvedType, resultTo,
14150                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14151                    callingPid, callingUid, userId);
14152            Binder.restoreCallingIdentity(origId);
14153            return res;
14154        }
14155    }
14156
14157    int broadcastIntentInPackage(String packageName, int uid,
14158            Intent intent, String resolvedType, IIntentReceiver resultTo,
14159            int resultCode, String resultData, Bundle map,
14160            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14161        synchronized(this) {
14162            intent = verifyBroadcastLocked(intent);
14163
14164            final long origId = Binder.clearCallingIdentity();
14165            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14166                    resultTo, resultCode, resultData, map, requiredPermission,
14167                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14168            Binder.restoreCallingIdentity(origId);
14169            return res;
14170        }
14171    }
14172
14173    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14174        // Refuse possible leaked file descriptors
14175        if (intent != null && intent.hasFileDescriptors() == true) {
14176            throw new IllegalArgumentException("File descriptors passed in Intent");
14177        }
14178
14179        userId = handleIncomingUser(Binder.getCallingPid(),
14180                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14181
14182        synchronized(this) {
14183            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14184                    != PackageManager.PERMISSION_GRANTED) {
14185                String msg = "Permission Denial: unbroadcastIntent() from pid="
14186                        + Binder.getCallingPid()
14187                        + ", uid=" + Binder.getCallingUid()
14188                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14189                Slog.w(TAG, msg);
14190                throw new SecurityException(msg);
14191            }
14192            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14193            if (stickies != null) {
14194                ArrayList<Intent> list = stickies.get(intent.getAction());
14195                if (list != null) {
14196                    int N = list.size();
14197                    int i;
14198                    for (i=0; i<N; i++) {
14199                        if (intent.filterEquals(list.get(i))) {
14200                            list.remove(i);
14201                            break;
14202                        }
14203                    }
14204                    if (list.size() <= 0) {
14205                        stickies.remove(intent.getAction());
14206                    }
14207                }
14208                if (stickies.size() <= 0) {
14209                    mStickyBroadcasts.remove(userId);
14210                }
14211            }
14212        }
14213    }
14214
14215    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14216            String resultData, Bundle resultExtras, boolean resultAbort) {
14217        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14218        if (r == null) {
14219            Slog.w(TAG, "finishReceiver called but not found on queue");
14220            return false;
14221        }
14222
14223        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14224    }
14225
14226    void backgroundServicesFinishedLocked(int userId) {
14227        for (BroadcastQueue queue : mBroadcastQueues) {
14228            queue.backgroundServicesFinishedLocked(userId);
14229        }
14230    }
14231
14232    public void finishReceiver(IBinder who, int resultCode, String resultData,
14233            Bundle resultExtras, boolean resultAbort) {
14234        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14235
14236        // Refuse possible leaked file descriptors
14237        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14238            throw new IllegalArgumentException("File descriptors passed in Bundle");
14239        }
14240
14241        final long origId = Binder.clearCallingIdentity();
14242        try {
14243            boolean doNext = false;
14244            BroadcastRecord r;
14245
14246            synchronized(this) {
14247                r = broadcastRecordForReceiverLocked(who);
14248                if (r != null) {
14249                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14250                        resultData, resultExtras, resultAbort, true);
14251                }
14252            }
14253
14254            if (doNext) {
14255                r.queue.processNextBroadcast(false);
14256            }
14257            trimApplications();
14258        } finally {
14259            Binder.restoreCallingIdentity(origId);
14260        }
14261    }
14262
14263    // =========================================================
14264    // INSTRUMENTATION
14265    // =========================================================
14266
14267    public boolean startInstrumentation(ComponentName className,
14268            String profileFile, int flags, Bundle arguments,
14269            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14270            int userId) {
14271        enforceNotIsolatedCaller("startInstrumentation");
14272        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14273                userId, false, true, "startInstrumentation", null);
14274        // Refuse possible leaked file descriptors
14275        if (arguments != null && arguments.hasFileDescriptors()) {
14276            throw new IllegalArgumentException("File descriptors passed in Bundle");
14277        }
14278
14279        synchronized(this) {
14280            InstrumentationInfo ii = null;
14281            ApplicationInfo ai = null;
14282            try {
14283                ii = mContext.getPackageManager().getInstrumentationInfo(
14284                    className, STOCK_PM_FLAGS);
14285                ai = AppGlobals.getPackageManager().getApplicationInfo(
14286                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14287            } catch (PackageManager.NameNotFoundException e) {
14288            } catch (RemoteException e) {
14289            }
14290            if (ii == null) {
14291                reportStartInstrumentationFailure(watcher, className,
14292                        "Unable to find instrumentation info for: " + className);
14293                return false;
14294            }
14295            if (ai == null) {
14296                reportStartInstrumentationFailure(watcher, className,
14297                        "Unable to find instrumentation target package: " + ii.targetPackage);
14298                return false;
14299            }
14300
14301            int match = mContext.getPackageManager().checkSignatures(
14302                    ii.targetPackage, ii.packageName);
14303            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14304                String msg = "Permission Denial: starting instrumentation "
14305                        + className + " from pid="
14306                        + Binder.getCallingPid()
14307                        + ", uid=" + Binder.getCallingPid()
14308                        + " not allowed because package " + ii.packageName
14309                        + " does not have a signature matching the target "
14310                        + ii.targetPackage;
14311                reportStartInstrumentationFailure(watcher, className, msg);
14312                throw new SecurityException(msg);
14313            }
14314
14315            final long origId = Binder.clearCallingIdentity();
14316            // Instrumentation can kill and relaunch even persistent processes
14317            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14318                    "start instr");
14319            ProcessRecord app = addAppLocked(ai, false);
14320            app.instrumentationClass = className;
14321            app.instrumentationInfo = ai;
14322            app.instrumentationProfileFile = profileFile;
14323            app.instrumentationArguments = arguments;
14324            app.instrumentationWatcher = watcher;
14325            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14326            app.instrumentationResultClass = className;
14327            Binder.restoreCallingIdentity(origId);
14328        }
14329
14330        return true;
14331    }
14332
14333    /**
14334     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14335     * error to the logs, but if somebody is watching, send the report there too.  This enables
14336     * the "am" command to report errors with more information.
14337     *
14338     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14339     * @param cn The component name of the instrumentation.
14340     * @param report The error report.
14341     */
14342    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14343            ComponentName cn, String report) {
14344        Slog.w(TAG, report);
14345        try {
14346            if (watcher != null) {
14347                Bundle results = new Bundle();
14348                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14349                results.putString("Error", report);
14350                watcher.instrumentationStatus(cn, -1, results);
14351            }
14352        } catch (RemoteException e) {
14353            Slog.w(TAG, e);
14354        }
14355    }
14356
14357    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14358        if (app.instrumentationWatcher != null) {
14359            try {
14360                // NOTE:  IInstrumentationWatcher *must* be oneway here
14361                app.instrumentationWatcher.instrumentationFinished(
14362                    app.instrumentationClass,
14363                    resultCode,
14364                    results);
14365            } catch (RemoteException e) {
14366            }
14367        }
14368        if (app.instrumentationUiAutomationConnection != null) {
14369            try {
14370                app.instrumentationUiAutomationConnection.shutdown();
14371            } catch (RemoteException re) {
14372                /* ignore */
14373            }
14374            // Only a UiAutomation can set this flag and now that
14375            // it is finished we make sure it is reset to its default.
14376            mUserIsMonkey = false;
14377        }
14378        app.instrumentationWatcher = null;
14379        app.instrumentationUiAutomationConnection = null;
14380        app.instrumentationClass = null;
14381        app.instrumentationInfo = null;
14382        app.instrumentationProfileFile = null;
14383        app.instrumentationArguments = null;
14384
14385        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14386                "finished inst");
14387    }
14388
14389    public void finishInstrumentation(IApplicationThread target,
14390            int resultCode, Bundle results) {
14391        int userId = UserHandle.getCallingUserId();
14392        // Refuse possible leaked file descriptors
14393        if (results != null && results.hasFileDescriptors()) {
14394            throw new IllegalArgumentException("File descriptors passed in Intent");
14395        }
14396
14397        synchronized(this) {
14398            ProcessRecord app = getRecordForAppLocked(target);
14399            if (app == null) {
14400                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14401                return;
14402            }
14403            final long origId = Binder.clearCallingIdentity();
14404            finishInstrumentationLocked(app, resultCode, results);
14405            Binder.restoreCallingIdentity(origId);
14406        }
14407    }
14408
14409    // =========================================================
14410    // CONFIGURATION
14411    // =========================================================
14412
14413    public ConfigurationInfo getDeviceConfigurationInfo() {
14414        ConfigurationInfo config = new ConfigurationInfo();
14415        synchronized (this) {
14416            config.reqTouchScreen = mConfiguration.touchscreen;
14417            config.reqKeyboardType = mConfiguration.keyboard;
14418            config.reqNavigation = mConfiguration.navigation;
14419            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14420                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14421                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14422            }
14423            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14424                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14425                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14426            }
14427            config.reqGlEsVersion = GL_ES_VERSION;
14428        }
14429        return config;
14430    }
14431
14432    ActivityStack getFocusedStack() {
14433        return mStackSupervisor.getFocusedStack();
14434    }
14435
14436    public Configuration getConfiguration() {
14437        Configuration ci;
14438        synchronized(this) {
14439            ci = new Configuration(mConfiguration);
14440        }
14441        return ci;
14442    }
14443
14444    public void updatePersistentConfiguration(Configuration values) {
14445        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14446                "updateConfiguration()");
14447        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14448                "updateConfiguration()");
14449        if (values == null) {
14450            throw new NullPointerException("Configuration must not be null");
14451        }
14452
14453        synchronized(this) {
14454            final long origId = Binder.clearCallingIdentity();
14455            updateConfigurationLocked(values, null, true, false);
14456            Binder.restoreCallingIdentity(origId);
14457        }
14458    }
14459
14460    public void updateConfiguration(Configuration values) {
14461        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14462                "updateConfiguration()");
14463
14464        synchronized(this) {
14465            if (values == null && mWindowManager != null) {
14466                // sentinel: fetch the current configuration from the window manager
14467                values = mWindowManager.computeNewConfiguration();
14468            }
14469
14470            if (mWindowManager != null) {
14471                mProcessList.applyDisplaySize(mWindowManager);
14472            }
14473
14474            final long origId = Binder.clearCallingIdentity();
14475            if (values != null) {
14476                Settings.System.clearConfiguration(values);
14477            }
14478            updateConfigurationLocked(values, null, false, false);
14479            Binder.restoreCallingIdentity(origId);
14480        }
14481    }
14482
14483    /**
14484     * Do either or both things: (1) change the current configuration, and (2)
14485     * make sure the given activity is running with the (now) current
14486     * configuration.  Returns true if the activity has been left running, or
14487     * false if <var>starting</var> is being destroyed to match the new
14488     * configuration.
14489     * @param persistent TODO
14490     */
14491    boolean updateConfigurationLocked(Configuration values,
14492            ActivityRecord starting, boolean persistent, boolean initLocale) {
14493        int changes = 0;
14494
14495        if (values != null) {
14496            Configuration newConfig = new Configuration(mConfiguration);
14497            changes = newConfig.updateFrom(values);
14498            if (changes != 0) {
14499                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14500                    Slog.i(TAG, "Updating configuration to: " + values);
14501                }
14502
14503                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14504
14505                if (values.locale != null && !initLocale) {
14506                    saveLocaleLocked(values.locale,
14507                                     !values.locale.equals(mConfiguration.locale),
14508                                     values.userSetLocale);
14509                }
14510
14511                mConfigurationSeq++;
14512                if (mConfigurationSeq <= 0) {
14513                    mConfigurationSeq = 1;
14514                }
14515                newConfig.seq = mConfigurationSeq;
14516                mConfiguration = newConfig;
14517                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14518                mUsageStatsService.noteStartConfig(newConfig);
14519
14520                final Configuration configCopy = new Configuration(mConfiguration);
14521
14522                // TODO: If our config changes, should we auto dismiss any currently
14523                // showing dialogs?
14524                mShowDialogs = shouldShowDialogs(newConfig);
14525
14526                AttributeCache ac = AttributeCache.instance();
14527                if (ac != null) {
14528                    ac.updateConfiguration(configCopy);
14529                }
14530
14531                // Make sure all resources in our process are updated
14532                // right now, so that anyone who is going to retrieve
14533                // resource values after we return will be sure to get
14534                // the new ones.  This is especially important during
14535                // boot, where the first config change needs to guarantee
14536                // all resources have that config before following boot
14537                // code is executed.
14538                mSystemThread.applyConfigurationToResources(configCopy);
14539
14540                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14541                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14542                    msg.obj = new Configuration(configCopy);
14543                    mHandler.sendMessage(msg);
14544                }
14545
14546                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14547                    ProcessRecord app = mLruProcesses.get(i);
14548                    try {
14549                        if (app.thread != null) {
14550                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14551                                    + app.processName + " new config " + mConfiguration);
14552                            app.thread.scheduleConfigurationChanged(configCopy);
14553                        }
14554                    } catch (Exception e) {
14555                    }
14556                }
14557                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14558                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14559                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14560                        | Intent.FLAG_RECEIVER_FOREGROUND);
14561                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14562                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14563                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14564                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14565                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14566                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14567                    broadcastIntentLocked(null, null, intent,
14568                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14569                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14570                }
14571            }
14572        }
14573
14574        boolean kept = true;
14575        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14576        // mainStack is null during startup.
14577        if (mainStack != null) {
14578            if (changes != 0 && starting == null) {
14579                // If the configuration changed, and the caller is not already
14580                // in the process of starting an activity, then find the top
14581                // activity to check if its configuration needs to change.
14582                starting = mainStack.topRunningActivityLocked(null);
14583            }
14584
14585            if (starting != null) {
14586                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14587                // And we need to make sure at this point that all other activities
14588                // are made visible with the correct configuration.
14589                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14590            }
14591        }
14592
14593        if (values != null && mWindowManager != null) {
14594            mWindowManager.setNewConfiguration(mConfiguration);
14595        }
14596
14597        return kept;
14598    }
14599
14600    /**
14601     * Decide based on the configuration whether we should shouw the ANR,
14602     * crash, etc dialogs.  The idea is that if there is no affordnace to
14603     * press the on-screen buttons, we shouldn't show the dialog.
14604     *
14605     * A thought: SystemUI might also want to get told about this, the Power
14606     * dialog / global actions also might want different behaviors.
14607     */
14608    private static final boolean shouldShowDialogs(Configuration config) {
14609        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14610                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14611    }
14612
14613    /**
14614     * Save the locale.  You must be inside a synchronized (this) block.
14615     */
14616    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14617        if(isDiff) {
14618            SystemProperties.set("user.language", l.getLanguage());
14619            SystemProperties.set("user.region", l.getCountry());
14620        }
14621
14622        if(isPersist) {
14623            SystemProperties.set("persist.sys.language", l.getLanguage());
14624            SystemProperties.set("persist.sys.country", l.getCountry());
14625            SystemProperties.set("persist.sys.localevar", l.getVariant());
14626        }
14627    }
14628
14629    @Override
14630    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14631        ActivityRecord srec = ActivityRecord.forToken(token);
14632        return srec != null && srec.task.affinity != null &&
14633                srec.task.affinity.equals(destAffinity);
14634    }
14635
14636    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14637            Intent resultData) {
14638
14639        synchronized (this) {
14640            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14641            if (stack != null) {
14642                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14643            }
14644            return false;
14645        }
14646    }
14647
14648    public int getLaunchedFromUid(IBinder activityToken) {
14649        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14650        if (srec == null) {
14651            return -1;
14652        }
14653        return srec.launchedFromUid;
14654    }
14655
14656    public String getLaunchedFromPackage(IBinder activityToken) {
14657        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14658        if (srec == null) {
14659            return null;
14660        }
14661        return srec.launchedFromPackage;
14662    }
14663
14664    // =========================================================
14665    // LIFETIME MANAGEMENT
14666    // =========================================================
14667
14668    // Returns which broadcast queue the app is the current [or imminent] receiver
14669    // on, or 'null' if the app is not an active broadcast recipient.
14670    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14671        BroadcastRecord r = app.curReceiver;
14672        if (r != null) {
14673            return r.queue;
14674        }
14675
14676        // It's not the current receiver, but it might be starting up to become one
14677        synchronized (this) {
14678            for (BroadcastQueue queue : mBroadcastQueues) {
14679                r = queue.mPendingBroadcast;
14680                if (r != null && r.curApp == app) {
14681                    // found it; report which queue it's in
14682                    return queue;
14683                }
14684            }
14685        }
14686
14687        return null;
14688    }
14689
14690    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14691            boolean doingAll, long now) {
14692        if (mAdjSeq == app.adjSeq) {
14693            // This adjustment has already been computed.
14694            return app.curRawAdj;
14695        }
14696
14697        if (app.thread == null) {
14698            app.adjSeq = mAdjSeq;
14699            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14700            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14701            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14702        }
14703
14704        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14705        app.adjSource = null;
14706        app.adjTarget = null;
14707        app.empty = false;
14708        app.cached = false;
14709
14710        final int activitiesSize = app.activities.size();
14711
14712        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14713            // The max adjustment doesn't allow this app to be anything
14714            // below foreground, so it is not worth doing work for it.
14715            app.adjType = "fixed";
14716            app.adjSeq = mAdjSeq;
14717            app.curRawAdj = app.maxAdj;
14718            app.foregroundActivities = false;
14719            app.keeping = true;
14720            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14721            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14722            // System processes can do UI, and when they do we want to have
14723            // them trim their memory after the user leaves the UI.  To
14724            // facilitate this, here we need to determine whether or not it
14725            // is currently showing UI.
14726            app.systemNoUi = true;
14727            if (app == TOP_APP) {
14728                app.systemNoUi = false;
14729            } else if (activitiesSize > 0) {
14730                for (int j = 0; j < activitiesSize; j++) {
14731                    final ActivityRecord r = app.activities.get(j);
14732                    if (r.visible) {
14733                        app.systemNoUi = false;
14734                    }
14735                }
14736            }
14737            if (!app.systemNoUi) {
14738                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14739            }
14740            return (app.curAdj=app.maxAdj);
14741        }
14742
14743        app.keeping = false;
14744        app.systemNoUi = false;
14745
14746        // Determine the importance of the process, starting with most
14747        // important to least, and assign an appropriate OOM adjustment.
14748        int adj;
14749        int schedGroup;
14750        int procState;
14751        boolean foregroundActivities = false;
14752        boolean interesting = false;
14753        BroadcastQueue queue;
14754        if (app == TOP_APP) {
14755            // The last app on the list is the foreground app.
14756            adj = ProcessList.FOREGROUND_APP_ADJ;
14757            schedGroup = Process.THREAD_GROUP_DEFAULT;
14758            app.adjType = "top-activity";
14759            foregroundActivities = true;
14760            interesting = true;
14761            procState = ActivityManager.PROCESS_STATE_TOP;
14762        } else if (app.instrumentationClass != null) {
14763            // Don't want to kill running instrumentation.
14764            adj = ProcessList.FOREGROUND_APP_ADJ;
14765            schedGroup = Process.THREAD_GROUP_DEFAULT;
14766            app.adjType = "instrumentation";
14767            interesting = true;
14768            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14769        } else if ((queue = isReceivingBroadcast(app)) != null) {
14770            // An app that is currently receiving a broadcast also
14771            // counts as being in the foreground for OOM killer purposes.
14772            // It's placed in a sched group based on the nature of the
14773            // broadcast as reflected by which queue it's active in.
14774            adj = ProcessList.FOREGROUND_APP_ADJ;
14775            schedGroup = (queue == mFgBroadcastQueue)
14776                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14777            app.adjType = "broadcast";
14778            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14779        } else if (app.executingServices.size() > 0) {
14780            // An app that is currently executing a service callback also
14781            // counts as being in the foreground.
14782            adj = ProcessList.FOREGROUND_APP_ADJ;
14783            schedGroup = app.execServicesFg ?
14784                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14785            app.adjType = "exec-service";
14786            procState = ActivityManager.PROCESS_STATE_SERVICE;
14787            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14788        } else {
14789            // As far as we know the process is empty.  We may change our mind later.
14790            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14791            // At this point we don't actually know the adjustment.  Use the cached adj
14792            // value that the caller wants us to.
14793            adj = cachedAdj;
14794            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14795            app.cached = true;
14796            app.empty = true;
14797            app.adjType = "cch-empty";
14798        }
14799
14800        // Examine all activities if not already foreground.
14801        if (!foregroundActivities && activitiesSize > 0) {
14802            for (int j = 0; j < activitiesSize; j++) {
14803                final ActivityRecord r = app.activities.get(j);
14804                if (r.app != app) {
14805                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14806                            + app + "?!?");
14807                    continue;
14808                }
14809                if (r.visible) {
14810                    // App has a visible activity; only upgrade adjustment.
14811                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14812                        adj = ProcessList.VISIBLE_APP_ADJ;
14813                        app.adjType = "visible";
14814                    }
14815                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14816                        procState = ActivityManager.PROCESS_STATE_TOP;
14817                    }
14818                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14819                    app.cached = false;
14820                    app.empty = false;
14821                    foregroundActivities = true;
14822                    break;
14823                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14824                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14825                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14826                        app.adjType = "pausing";
14827                    }
14828                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14829                        procState = ActivityManager.PROCESS_STATE_TOP;
14830                    }
14831                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14832                    app.cached = false;
14833                    app.empty = false;
14834                    foregroundActivities = true;
14835                } else if (r.state == ActivityState.STOPPING) {
14836                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14837                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14838                        app.adjType = "stopping";
14839                    }
14840                    // For the process state, we will at this point consider the
14841                    // process to be cached.  It will be cached either as an activity
14842                    // or empty depending on whether the activity is finishing.  We do
14843                    // this so that we can treat the process as cached for purposes of
14844                    // memory trimming (determing current memory level, trim command to
14845                    // send to process) since there can be an arbitrary number of stopping
14846                    // processes and they should soon all go into the cached state.
14847                    if (!r.finishing) {
14848                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14849                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14850                        }
14851                    }
14852                    app.cached = false;
14853                    app.empty = false;
14854                    foregroundActivities = true;
14855                } else {
14856                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14857                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14858                        app.adjType = "cch-act";
14859                    }
14860                }
14861            }
14862        }
14863
14864        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14865            if (app.foregroundServices) {
14866                // The user is aware of this app, so make it visible.
14867                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14868                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14869                app.cached = false;
14870                app.adjType = "fg-service";
14871                schedGroup = Process.THREAD_GROUP_DEFAULT;
14872            } else if (app.forcingToForeground != null) {
14873                // The user is aware of this app, so make it visible.
14874                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14875                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14876                app.cached = false;
14877                app.adjType = "force-fg";
14878                app.adjSource = app.forcingToForeground;
14879                schedGroup = Process.THREAD_GROUP_DEFAULT;
14880            }
14881        }
14882
14883        if (app.foregroundServices) {
14884            interesting = true;
14885        }
14886
14887        if (app == mHeavyWeightProcess) {
14888            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14889                // We don't want to kill the current heavy-weight process.
14890                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14891                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14892                app.cached = false;
14893                app.adjType = "heavy";
14894            }
14895            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14896                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14897            }
14898        }
14899
14900        if (app == mHomeProcess) {
14901            if (adj > ProcessList.HOME_APP_ADJ) {
14902                // This process is hosting what we currently consider to be the
14903                // home app, so we don't want to let it go into the background.
14904                adj = ProcessList.HOME_APP_ADJ;
14905                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14906                app.cached = false;
14907                app.adjType = "home";
14908            }
14909            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14910                procState = ActivityManager.PROCESS_STATE_HOME;
14911            }
14912        }
14913
14914        if (app == mPreviousProcess && app.activities.size() > 0) {
14915            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14916                // This was the previous process that showed UI to the user.
14917                // We want to try to keep it around more aggressively, to give
14918                // a good experience around switching between two apps.
14919                adj = ProcessList.PREVIOUS_APP_ADJ;
14920                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14921                app.cached = false;
14922                app.adjType = "previous";
14923            }
14924            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14925                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14926            }
14927        }
14928
14929        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14930                + " reason=" + app.adjType);
14931
14932        // By default, we use the computed adjustment.  It may be changed if
14933        // there are applications dependent on our services or providers, but
14934        // this gives us a baseline and makes sure we don't get into an
14935        // infinite recursion.
14936        app.adjSeq = mAdjSeq;
14937        app.curRawAdj = adj;
14938        app.hasStartedServices = false;
14939
14940        if (mBackupTarget != null && app == mBackupTarget.app) {
14941            // If possible we want to avoid killing apps while they're being backed up
14942            if (adj > ProcessList.BACKUP_APP_ADJ) {
14943                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14944                adj = ProcessList.BACKUP_APP_ADJ;
14945                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14946                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14947                }
14948                app.adjType = "backup";
14949                app.cached = false;
14950            }
14951            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14952                procState = ActivityManager.PROCESS_STATE_BACKUP;
14953            }
14954        }
14955
14956        boolean mayBeTop = false;
14957
14958        for (int is = app.services.size()-1;
14959                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14960                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14961                        || procState > ActivityManager.PROCESS_STATE_TOP);
14962                is--) {
14963            ServiceRecord s = app.services.valueAt(is);
14964            if (s.startRequested) {
14965                app.hasStartedServices = true;
14966                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14967                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14968                }
14969                if (app.hasShownUi && app != mHomeProcess) {
14970                    // If this process has shown some UI, let it immediately
14971                    // go to the LRU list because it may be pretty heavy with
14972                    // UI stuff.  We'll tag it with a label just to help
14973                    // debug and understand what is going on.
14974                    if (adj > ProcessList.SERVICE_ADJ) {
14975                        app.adjType = "cch-started-ui-services";
14976                    }
14977                } else {
14978                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14979                        // This service has seen some activity within
14980                        // recent memory, so we will keep its process ahead
14981                        // of the background processes.
14982                        if (adj > ProcessList.SERVICE_ADJ) {
14983                            adj = ProcessList.SERVICE_ADJ;
14984                            app.adjType = "started-services";
14985                            app.cached = false;
14986                        }
14987                    }
14988                    // If we have let the service slide into the background
14989                    // state, still have some text describing what it is doing
14990                    // even though the service no longer has an impact.
14991                    if (adj > ProcessList.SERVICE_ADJ) {
14992                        app.adjType = "cch-started-services";
14993                    }
14994                }
14995                // Don't kill this process because it is doing work; it
14996                // has said it is doing work.
14997                app.keeping = true;
14998            }
14999            for (int conni = s.connections.size()-1;
15000                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15001                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15002                            || procState > ActivityManager.PROCESS_STATE_TOP);
15003                    conni--) {
15004                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15005                for (int i = 0;
15006                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15007                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15008                                || procState > ActivityManager.PROCESS_STATE_TOP);
15009                        i++) {
15010                    // XXX should compute this based on the max of
15011                    // all connected clients.
15012                    ConnectionRecord cr = clist.get(i);
15013                    if (cr.binding.client == app) {
15014                        // Binding to ourself is not interesting.
15015                        continue;
15016                    }
15017                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15018                        ProcessRecord client = cr.binding.client;
15019                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15020                                TOP_APP, doingAll, now);
15021                        int clientProcState = client.curProcState;
15022                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15023                            // If the other app is cached for any reason, for purposes here
15024                            // we are going to consider it empty.  The specific cached state
15025                            // doesn't propagate except under certain conditions.
15026                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15027                        }
15028                        String adjType = null;
15029                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15030                            // Not doing bind OOM management, so treat
15031                            // this guy more like a started service.
15032                            if (app.hasShownUi && app != mHomeProcess) {
15033                                // If this process has shown some UI, let it immediately
15034                                // go to the LRU list because it may be pretty heavy with
15035                                // UI stuff.  We'll tag it with a label just to help
15036                                // debug and understand what is going on.
15037                                if (adj > clientAdj) {
15038                                    adjType = "cch-bound-ui-services";
15039                                }
15040                                app.cached = false;
15041                                clientAdj = adj;
15042                                clientProcState = procState;
15043                            } else {
15044                                if (now >= (s.lastActivity
15045                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15046                                    // This service has not seen activity within
15047                                    // recent memory, so allow it to drop to the
15048                                    // LRU list if there is no other reason to keep
15049                                    // it around.  We'll also tag it with a label just
15050                                    // to help debug and undertand what is going on.
15051                                    if (adj > clientAdj) {
15052                                        adjType = "cch-bound-services";
15053                                    }
15054                                    clientAdj = adj;
15055                                }
15056                            }
15057                        }
15058                        if (adj > clientAdj) {
15059                            // If this process has recently shown UI, and
15060                            // the process that is binding to it is less
15061                            // important than being visible, then we don't
15062                            // care about the binding as much as we care
15063                            // about letting this process get into the LRU
15064                            // list to be killed and restarted if needed for
15065                            // memory.
15066                            if (app.hasShownUi && app != mHomeProcess
15067                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15068                                adjType = "cch-bound-ui-services";
15069                            } else {
15070                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15071                                        |Context.BIND_IMPORTANT)) != 0) {
15072                                    adj = clientAdj;
15073                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15074                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15075                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15076                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15077                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15078                                    adj = clientAdj;
15079                                } else {
15080                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15081                                        adj = ProcessList.VISIBLE_APP_ADJ;
15082                                    }
15083                                }
15084                                if (!client.cached) {
15085                                    app.cached = false;
15086                                }
15087                                if (client.keeping) {
15088                                    app.keeping = true;
15089                                }
15090                                adjType = "service";
15091                            }
15092                        }
15093                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15094                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15095                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15096                            }
15097                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15098                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15099                                    // Special handling of clients who are in the top state.
15100                                    // We *may* want to consider this process to be in the
15101                                    // top state as well, but only if there is not another
15102                                    // reason for it to be running.  Being on the top is a
15103                                    // special state, meaning you are specifically running
15104                                    // for the current top app.  If the process is already
15105                                    // running in the background for some other reason, it
15106                                    // is more important to continue considering it to be
15107                                    // in the background state.
15108                                    mayBeTop = true;
15109                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15110                                } else {
15111                                    // Special handling for above-top states (persistent
15112                                    // processes).  These should not bring the current process
15113                                    // into the top state, since they are not on top.  Instead
15114                                    // give them the best state after that.
15115                                    clientProcState =
15116                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15117                                }
15118                            }
15119                        } else {
15120                            if (clientProcState <
15121                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15122                                clientProcState =
15123                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15124                            }
15125                        }
15126                        if (procState > clientProcState) {
15127                            procState = clientProcState;
15128                        }
15129                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15130                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15131                            app.pendingUiClean = true;
15132                        }
15133                        if (adjType != null) {
15134                            app.adjType = adjType;
15135                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15136                                    .REASON_SERVICE_IN_USE;
15137                            app.adjSource = cr.binding.client;
15138                            app.adjSourceOom = clientAdj;
15139                            app.adjTarget = s.name;
15140                        }
15141                    }
15142                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15143                        app.treatLikeActivity = true;
15144                    }
15145                    final ActivityRecord a = cr.activity;
15146                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15147                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15148                                (a.visible || a.state == ActivityState.RESUMED
15149                                 || a.state == ActivityState.PAUSING)) {
15150                            adj = ProcessList.FOREGROUND_APP_ADJ;
15151                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15152                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15153                            }
15154                            app.cached = false;
15155                            app.adjType = "service";
15156                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15157                                    .REASON_SERVICE_IN_USE;
15158                            app.adjSource = a;
15159                            app.adjSourceOom = adj;
15160                            app.adjTarget = s.name;
15161                        }
15162                    }
15163                }
15164            }
15165        }
15166
15167        for (int provi = app.pubProviders.size()-1;
15168                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15169                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15170                        || procState > ActivityManager.PROCESS_STATE_TOP);
15171                provi--) {
15172            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15173            for (int i = cpr.connections.size()-1;
15174                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15175                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15176                            || procState > ActivityManager.PROCESS_STATE_TOP);
15177                    i--) {
15178                ContentProviderConnection conn = cpr.connections.get(i);
15179                ProcessRecord client = conn.client;
15180                if (client == app) {
15181                    // Being our own client is not interesting.
15182                    continue;
15183                }
15184                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15185                int clientProcState = client.curProcState;
15186                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15187                    // If the other app is cached for any reason, for purposes here
15188                    // we are going to consider it empty.
15189                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15190                }
15191                if (adj > clientAdj) {
15192                    if (app.hasShownUi && app != mHomeProcess
15193                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15194                        app.adjType = "cch-ui-provider";
15195                    } else {
15196                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15197                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15198                        app.adjType = "provider";
15199                    }
15200                    app.cached &= client.cached;
15201                    app.keeping |= client.keeping;
15202                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15203                            .REASON_PROVIDER_IN_USE;
15204                    app.adjSource = client;
15205                    app.adjSourceOom = clientAdj;
15206                    app.adjTarget = cpr.name;
15207                }
15208                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15209                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15210                        // Special handling of clients who are in the top state.
15211                        // We *may* want to consider this process to be in the
15212                        // top state as well, but only if there is not another
15213                        // reason for it to be running.  Being on the top is a
15214                        // special state, meaning you are specifically running
15215                        // for the current top app.  If the process is already
15216                        // running in the background for some other reason, it
15217                        // is more important to continue considering it to be
15218                        // in the background state.
15219                        mayBeTop = true;
15220                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15221                    } else {
15222                        // Special handling for above-top states (persistent
15223                        // processes).  These should not bring the current process
15224                        // into the top state, since they are not on top.  Instead
15225                        // give them the best state after that.
15226                        clientProcState =
15227                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15228                    }
15229                }
15230                if (procState > clientProcState) {
15231                    procState = clientProcState;
15232                }
15233                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15234                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15235                }
15236            }
15237            // If the provider has external (non-framework) process
15238            // dependencies, ensure that its adjustment is at least
15239            // FOREGROUND_APP_ADJ.
15240            if (cpr.hasExternalProcessHandles()) {
15241                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15242                    adj = ProcessList.FOREGROUND_APP_ADJ;
15243                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15244                    app.cached = false;
15245                    app.keeping = true;
15246                    app.adjType = "provider";
15247                    app.adjTarget = cpr.name;
15248                }
15249                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15250                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15251                }
15252            }
15253        }
15254
15255        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15256            // A client of one of our services or providers is in the top state.  We
15257            // *may* want to be in the top state, but not if we are already running in
15258            // the background for some other reason.  For the decision here, we are going
15259            // to pick out a few specific states that we want to remain in when a client
15260            // is top (states that tend to be longer-term) and otherwise allow it to go
15261            // to the top state.
15262            switch (procState) {
15263                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15264                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15265                case ActivityManager.PROCESS_STATE_SERVICE:
15266                    // These all are longer-term states, so pull them up to the top
15267                    // of the background states, but not all the way to the top state.
15268                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15269                    break;
15270                default:
15271                    // Otherwise, top is a better choice, so take it.
15272                    procState = ActivityManager.PROCESS_STATE_TOP;
15273                    break;
15274            }
15275        }
15276
15277        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15278            if (app.hasClientActivities) {
15279                // This is a cached process, but with client activities.  Mark it so.
15280                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15281                app.adjType = "cch-client-act";
15282            } else if (app.treatLikeActivity) {
15283                // This is a cached process, but somebody wants us to treat it like it has
15284                // an activity, okay!
15285                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15286                app.adjType = "cch-as-act";
15287            }
15288        }
15289
15290        if (adj == ProcessList.SERVICE_ADJ) {
15291            if (doingAll) {
15292                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15293                mNewNumServiceProcs++;
15294                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15295                if (!app.serviceb) {
15296                    // This service isn't far enough down on the LRU list to
15297                    // normally be a B service, but if we are low on RAM and it
15298                    // is large we want to force it down since we would prefer to
15299                    // keep launcher over it.
15300                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15301                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15302                        app.serviceHighRam = true;
15303                        app.serviceb = true;
15304                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15305                    } else {
15306                        mNewNumAServiceProcs++;
15307                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15308                    }
15309                } else {
15310                    app.serviceHighRam = false;
15311                }
15312            }
15313            if (app.serviceb) {
15314                adj = ProcessList.SERVICE_B_ADJ;
15315            }
15316        }
15317
15318        app.curRawAdj = adj;
15319
15320        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15321        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15322        if (adj > app.maxAdj) {
15323            adj = app.maxAdj;
15324            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15325                schedGroup = Process.THREAD_GROUP_DEFAULT;
15326            }
15327        }
15328        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15329            app.keeping = true;
15330        }
15331
15332        // Do final modification to adj.  Everything we do between here and applying
15333        // the final setAdj must be done in this function, because we will also use
15334        // it when computing the final cached adj later.  Note that we don't need to
15335        // worry about this for max adj above, since max adj will always be used to
15336        // keep it out of the cached vaues.
15337        app.curAdj = app.modifyRawOomAdj(adj);
15338        app.curSchedGroup = schedGroup;
15339        app.curProcState = procState;
15340        app.foregroundActivities = foregroundActivities;
15341
15342        return app.curRawAdj;
15343    }
15344
15345    /**
15346     * Schedule PSS collection of a process.
15347     */
15348    void requestPssLocked(ProcessRecord proc, int procState) {
15349        if (mPendingPssProcesses.contains(proc)) {
15350            return;
15351        }
15352        if (mPendingPssProcesses.size() == 0) {
15353            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15354        }
15355        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15356        proc.pssProcState = procState;
15357        mPendingPssProcesses.add(proc);
15358    }
15359
15360    /**
15361     * Schedule PSS collection of all processes.
15362     */
15363    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15364        if (!always) {
15365            if (now < (mLastFullPssTime +
15366                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15367                return;
15368            }
15369        }
15370        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15371        mLastFullPssTime = now;
15372        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15373        mPendingPssProcesses.clear();
15374        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15375            ProcessRecord app = mLruProcesses.get(i);
15376            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15377                app.pssProcState = app.setProcState;
15378                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15379                        isSleeping(), now);
15380                mPendingPssProcesses.add(app);
15381            }
15382        }
15383        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15384    }
15385
15386    /**
15387     * Ask a given process to GC right now.
15388     */
15389    final void performAppGcLocked(ProcessRecord app) {
15390        try {
15391            app.lastRequestedGc = SystemClock.uptimeMillis();
15392            if (app.thread != null) {
15393                if (app.reportLowMemory) {
15394                    app.reportLowMemory = false;
15395                    app.thread.scheduleLowMemory();
15396                } else {
15397                    app.thread.processInBackground();
15398                }
15399            }
15400        } catch (Exception e) {
15401            // whatever.
15402        }
15403    }
15404
15405    /**
15406     * Returns true if things are idle enough to perform GCs.
15407     */
15408    private final boolean canGcNowLocked() {
15409        boolean processingBroadcasts = false;
15410        for (BroadcastQueue q : mBroadcastQueues) {
15411            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15412                processingBroadcasts = true;
15413            }
15414        }
15415        return !processingBroadcasts
15416                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15417    }
15418
15419    /**
15420     * Perform GCs on all processes that are waiting for it, but only
15421     * if things are idle.
15422     */
15423    final void performAppGcsLocked() {
15424        final int N = mProcessesToGc.size();
15425        if (N <= 0) {
15426            return;
15427        }
15428        if (canGcNowLocked()) {
15429            while (mProcessesToGc.size() > 0) {
15430                ProcessRecord proc = mProcessesToGc.remove(0);
15431                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15432                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15433                            <= SystemClock.uptimeMillis()) {
15434                        // To avoid spamming the system, we will GC processes one
15435                        // at a time, waiting a few seconds between each.
15436                        performAppGcLocked(proc);
15437                        scheduleAppGcsLocked();
15438                        return;
15439                    } else {
15440                        // It hasn't been long enough since we last GCed this
15441                        // process...  put it in the list to wait for its time.
15442                        addProcessToGcListLocked(proc);
15443                        break;
15444                    }
15445                }
15446            }
15447
15448            scheduleAppGcsLocked();
15449        }
15450    }
15451
15452    /**
15453     * If all looks good, perform GCs on all processes waiting for them.
15454     */
15455    final void performAppGcsIfAppropriateLocked() {
15456        if (canGcNowLocked()) {
15457            performAppGcsLocked();
15458            return;
15459        }
15460        // Still not idle, wait some more.
15461        scheduleAppGcsLocked();
15462    }
15463
15464    /**
15465     * Schedule the execution of all pending app GCs.
15466     */
15467    final void scheduleAppGcsLocked() {
15468        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15469
15470        if (mProcessesToGc.size() > 0) {
15471            // Schedule a GC for the time to the next process.
15472            ProcessRecord proc = mProcessesToGc.get(0);
15473            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15474
15475            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15476            long now = SystemClock.uptimeMillis();
15477            if (when < (now+GC_TIMEOUT)) {
15478                when = now + GC_TIMEOUT;
15479            }
15480            mHandler.sendMessageAtTime(msg, when);
15481        }
15482    }
15483
15484    /**
15485     * Add a process to the array of processes waiting to be GCed.  Keeps the
15486     * list in sorted order by the last GC time.  The process can't already be
15487     * on the list.
15488     */
15489    final void addProcessToGcListLocked(ProcessRecord proc) {
15490        boolean added = false;
15491        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15492            if (mProcessesToGc.get(i).lastRequestedGc <
15493                    proc.lastRequestedGc) {
15494                added = true;
15495                mProcessesToGc.add(i+1, proc);
15496                break;
15497            }
15498        }
15499        if (!added) {
15500            mProcessesToGc.add(0, proc);
15501        }
15502    }
15503
15504    /**
15505     * Set up to ask a process to GC itself.  This will either do it
15506     * immediately, or put it on the list of processes to gc the next
15507     * time things are idle.
15508     */
15509    final void scheduleAppGcLocked(ProcessRecord app) {
15510        long now = SystemClock.uptimeMillis();
15511        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15512            return;
15513        }
15514        if (!mProcessesToGc.contains(app)) {
15515            addProcessToGcListLocked(app);
15516            scheduleAppGcsLocked();
15517        }
15518    }
15519
15520    final void checkExcessivePowerUsageLocked(boolean doKills) {
15521        updateCpuStatsNow();
15522
15523        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15524        boolean doWakeKills = doKills;
15525        boolean doCpuKills = doKills;
15526        if (mLastPowerCheckRealtime == 0) {
15527            doWakeKills = false;
15528        }
15529        if (mLastPowerCheckUptime == 0) {
15530            doCpuKills = false;
15531        }
15532        if (stats.isScreenOn()) {
15533            doWakeKills = false;
15534        }
15535        final long curRealtime = SystemClock.elapsedRealtime();
15536        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15537        final long curUptime = SystemClock.uptimeMillis();
15538        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15539        mLastPowerCheckRealtime = curRealtime;
15540        mLastPowerCheckUptime = curUptime;
15541        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15542            doWakeKills = false;
15543        }
15544        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15545            doCpuKills = false;
15546        }
15547        int i = mLruProcesses.size();
15548        while (i > 0) {
15549            i--;
15550            ProcessRecord app = mLruProcesses.get(i);
15551            if (!app.keeping) {
15552                long wtime;
15553                synchronized (stats) {
15554                    wtime = stats.getProcessWakeTime(app.info.uid,
15555                            app.pid, curRealtime);
15556                }
15557                long wtimeUsed = wtime - app.lastWakeTime;
15558                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15559                if (DEBUG_POWER) {
15560                    StringBuilder sb = new StringBuilder(128);
15561                    sb.append("Wake for ");
15562                    app.toShortString(sb);
15563                    sb.append(": over ");
15564                    TimeUtils.formatDuration(realtimeSince, sb);
15565                    sb.append(" used ");
15566                    TimeUtils.formatDuration(wtimeUsed, sb);
15567                    sb.append(" (");
15568                    sb.append((wtimeUsed*100)/realtimeSince);
15569                    sb.append("%)");
15570                    Slog.i(TAG, sb.toString());
15571                    sb.setLength(0);
15572                    sb.append("CPU for ");
15573                    app.toShortString(sb);
15574                    sb.append(": over ");
15575                    TimeUtils.formatDuration(uptimeSince, sb);
15576                    sb.append(" used ");
15577                    TimeUtils.formatDuration(cputimeUsed, sb);
15578                    sb.append(" (");
15579                    sb.append((cputimeUsed*100)/uptimeSince);
15580                    sb.append("%)");
15581                    Slog.i(TAG, sb.toString());
15582                }
15583                // If a process has held a wake lock for more
15584                // than 50% of the time during this period,
15585                // that sounds bad.  Kill!
15586                if (doWakeKills && realtimeSince > 0
15587                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15588                    synchronized (stats) {
15589                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15590                                realtimeSince, wtimeUsed);
15591                    }
15592                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15593                            + " during " + realtimeSince);
15594                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15595                } else if (doCpuKills && uptimeSince > 0
15596                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15597                    synchronized (stats) {
15598                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15599                                uptimeSince, cputimeUsed);
15600                    }
15601                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15602                            + " during " + uptimeSince);
15603                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15604                } else {
15605                    app.lastWakeTime = wtime;
15606                    app.lastCpuTime = app.curCpuTime;
15607                }
15608            }
15609        }
15610    }
15611
15612    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15613            ProcessRecord TOP_APP, boolean doingAll, long now) {
15614        boolean success = true;
15615
15616        if (app.curRawAdj != app.setRawAdj) {
15617            if (wasKeeping && !app.keeping) {
15618                // This app is no longer something we want to keep.  Note
15619                // its current wake lock time to later know to kill it if
15620                // it is not behaving well.
15621                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15622                synchronized (stats) {
15623                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15624                            app.pid, SystemClock.elapsedRealtime());
15625                }
15626                app.lastCpuTime = app.curCpuTime;
15627            }
15628
15629            app.setRawAdj = app.curRawAdj;
15630        }
15631
15632        int changes = 0;
15633
15634        if (app.curAdj != app.setAdj) {
15635            ProcessList.setOomAdj(app.pid, app.curAdj);
15636            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15637                TAG, "Set " + app.pid + " " + app.processName +
15638                " adj " + app.curAdj + ": " + app.adjType);
15639            app.setAdj = app.curAdj;
15640        }
15641
15642        if (app.setSchedGroup != app.curSchedGroup) {
15643            app.setSchedGroup = app.curSchedGroup;
15644            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15645                    "Setting process group of " + app.processName
15646                    + " to " + app.curSchedGroup);
15647            if (app.waitingToKill != null &&
15648                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15649                killUnneededProcessLocked(app, app.waitingToKill);
15650                success = false;
15651            } else {
15652                if (true) {
15653                    long oldId = Binder.clearCallingIdentity();
15654                    try {
15655                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15656                    } catch (Exception e) {
15657                        Slog.w(TAG, "Failed setting process group of " + app.pid
15658                                + " to " + app.curSchedGroup);
15659                        e.printStackTrace();
15660                    } finally {
15661                        Binder.restoreCallingIdentity(oldId);
15662                    }
15663                } else {
15664                    if (app.thread != null) {
15665                        try {
15666                            app.thread.setSchedulingGroup(app.curSchedGroup);
15667                        } catch (RemoteException e) {
15668                        }
15669                    }
15670                }
15671                Process.setSwappiness(app.pid,
15672                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15673            }
15674        }
15675        if (app.repForegroundActivities != app.foregroundActivities) {
15676            app.repForegroundActivities = app.foregroundActivities;
15677            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15678        }
15679        if (app.repProcState != app.curProcState) {
15680            app.repProcState = app.curProcState;
15681            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15682            if (app.thread != null) {
15683                try {
15684                    if (false) {
15685                        //RuntimeException h = new RuntimeException("here");
15686                        Slog.i(TAG, "Sending new process state " + app.repProcState
15687                                + " to " + app /*, h*/);
15688                    }
15689                    app.thread.setProcessState(app.repProcState);
15690                } catch (RemoteException e) {
15691                }
15692            }
15693        }
15694        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15695                app.setProcState)) {
15696            app.lastStateTime = now;
15697            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15698                    isSleeping(), now);
15699            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15700                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15701                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15702                    + (app.nextPssTime-now) + ": " + app);
15703        } else {
15704            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15705                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15706                requestPssLocked(app, app.setProcState);
15707                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15708                        isSleeping(), now);
15709            } else if (false && DEBUG_PSS) {
15710                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15711            }
15712        }
15713        if (app.setProcState != app.curProcState) {
15714            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15715                    "Proc state change of " + app.processName
15716                    + " to " + app.curProcState);
15717            app.setProcState = app.curProcState;
15718            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15719                app.notCachedSinceIdle = false;
15720            }
15721            if (!doingAll) {
15722                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15723            } else {
15724                app.procStateChanged = true;
15725            }
15726        }
15727
15728        if (changes != 0) {
15729            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15730            int i = mPendingProcessChanges.size()-1;
15731            ProcessChangeItem item = null;
15732            while (i >= 0) {
15733                item = mPendingProcessChanges.get(i);
15734                if (item.pid == app.pid) {
15735                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15736                    break;
15737                }
15738                i--;
15739            }
15740            if (i < 0) {
15741                // No existing item in pending changes; need a new one.
15742                final int NA = mAvailProcessChanges.size();
15743                if (NA > 0) {
15744                    item = mAvailProcessChanges.remove(NA-1);
15745                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15746                } else {
15747                    item = new ProcessChangeItem();
15748                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15749                }
15750                item.changes = 0;
15751                item.pid = app.pid;
15752                item.uid = app.info.uid;
15753                if (mPendingProcessChanges.size() == 0) {
15754                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15755                            "*** Enqueueing dispatch processes changed!");
15756                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15757                }
15758                mPendingProcessChanges.add(item);
15759            }
15760            item.changes |= changes;
15761            item.processState = app.repProcState;
15762            item.foregroundActivities = app.repForegroundActivities;
15763            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15764                    + Integer.toHexString(System.identityHashCode(item))
15765                    + " " + app.toShortString() + ": changes=" + item.changes
15766                    + " procState=" + item.processState
15767                    + " foreground=" + item.foregroundActivities
15768                    + " type=" + app.adjType + " source=" + app.adjSource
15769                    + " target=" + app.adjTarget);
15770        }
15771
15772        return success;
15773    }
15774
15775    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15776        if (proc.thread != null && proc.baseProcessTracker != null) {
15777            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15778        }
15779    }
15780
15781    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15782            ProcessRecord TOP_APP, boolean doingAll, long now) {
15783        if (app.thread == null) {
15784            return false;
15785        }
15786
15787        final boolean wasKeeping = app.keeping;
15788
15789        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15790
15791        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15792    }
15793
15794    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15795            boolean oomAdj) {
15796        if (isForeground != proc.foregroundServices) {
15797            proc.foregroundServices = isForeground;
15798            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15799                    proc.info.uid);
15800            if (isForeground) {
15801                if (curProcs == null) {
15802                    curProcs = new ArrayList<ProcessRecord>();
15803                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15804                }
15805                if (!curProcs.contains(proc)) {
15806                    curProcs.add(proc);
15807                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15808                            proc.info.packageName, proc.info.uid);
15809                }
15810            } else {
15811                if (curProcs != null) {
15812                    if (curProcs.remove(proc)) {
15813                        mBatteryStatsService.noteEvent(
15814                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15815                                proc.info.packageName, proc.info.uid);
15816                        if (curProcs.size() <= 0) {
15817                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15818                        }
15819                    }
15820                }
15821            }
15822            if (oomAdj) {
15823                updateOomAdjLocked();
15824            }
15825        }
15826    }
15827
15828    private final ActivityRecord resumedAppLocked() {
15829        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15830        String pkg;
15831        int uid;
15832        if (act != null && !act.sleeping) {
15833            pkg = act.packageName;
15834            uid = act.info.applicationInfo.uid;
15835        } else {
15836            pkg = null;
15837            uid = -1;
15838        }
15839        // Has the UID or resumed package name changed?
15840        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15841                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15842            if (mCurResumedPackage != null) {
15843                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15844                        mCurResumedPackage, mCurResumedUid);
15845            }
15846            mCurResumedPackage = pkg;
15847            mCurResumedUid = uid;
15848            if (mCurResumedPackage != null) {
15849                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15850                        mCurResumedPackage, mCurResumedUid);
15851            }
15852        }
15853        return act;
15854    }
15855
15856    final boolean updateOomAdjLocked(ProcessRecord app) {
15857        final ActivityRecord TOP_ACT = resumedAppLocked();
15858        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15859        final boolean wasCached = app.cached;
15860
15861        mAdjSeq++;
15862
15863        // This is the desired cached adjusment we want to tell it to use.
15864        // If our app is currently cached, we know it, and that is it.  Otherwise,
15865        // we don't know it yet, and it needs to now be cached we will then
15866        // need to do a complete oom adj.
15867        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15868                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15869        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15870                SystemClock.uptimeMillis());
15871        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15872            // Changed to/from cached state, so apps after it in the LRU
15873            // list may also be changed.
15874            updateOomAdjLocked();
15875        }
15876        return success;
15877    }
15878
15879    final void updateOomAdjLocked() {
15880        final ActivityRecord TOP_ACT = resumedAppLocked();
15881        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15882        final long now = SystemClock.uptimeMillis();
15883        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15884        final int N = mLruProcesses.size();
15885
15886        if (false) {
15887            RuntimeException e = new RuntimeException();
15888            e.fillInStackTrace();
15889            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15890        }
15891
15892        mAdjSeq++;
15893        mNewNumServiceProcs = 0;
15894        mNewNumAServiceProcs = 0;
15895
15896        final int emptyProcessLimit;
15897        final int cachedProcessLimit;
15898        if (mProcessLimit <= 0) {
15899            emptyProcessLimit = cachedProcessLimit = 0;
15900        } else if (mProcessLimit == 1) {
15901            emptyProcessLimit = 1;
15902            cachedProcessLimit = 0;
15903        } else {
15904            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15905            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15906        }
15907
15908        // Let's determine how many processes we have running vs.
15909        // how many slots we have for background processes; we may want
15910        // to put multiple processes in a slot of there are enough of
15911        // them.
15912        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15913                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15914        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15915        if (numEmptyProcs > cachedProcessLimit) {
15916            // If there are more empty processes than our limit on cached
15917            // processes, then use the cached process limit for the factor.
15918            // This ensures that the really old empty processes get pushed
15919            // down to the bottom, so if we are running low on memory we will
15920            // have a better chance at keeping around more cached processes
15921            // instead of a gazillion empty processes.
15922            numEmptyProcs = cachedProcessLimit;
15923        }
15924        int emptyFactor = numEmptyProcs/numSlots;
15925        if (emptyFactor < 1) emptyFactor = 1;
15926        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15927        if (cachedFactor < 1) cachedFactor = 1;
15928        int stepCached = 0;
15929        int stepEmpty = 0;
15930        int numCached = 0;
15931        int numEmpty = 0;
15932        int numTrimming = 0;
15933
15934        mNumNonCachedProcs = 0;
15935        mNumCachedHiddenProcs = 0;
15936
15937        // First update the OOM adjustment for each of the
15938        // application processes based on their current state.
15939        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15940        int nextCachedAdj = curCachedAdj+1;
15941        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15942        int nextEmptyAdj = curEmptyAdj+2;
15943        for (int i=N-1; i>=0; i--) {
15944            ProcessRecord app = mLruProcesses.get(i);
15945            if (!app.killedByAm && app.thread != null) {
15946                app.procStateChanged = false;
15947                final boolean wasKeeping = app.keeping;
15948                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15949
15950                // If we haven't yet assigned the final cached adj
15951                // to the process, do that now.
15952                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15953                    switch (app.curProcState) {
15954                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15955                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15956                            // This process is a cached process holding activities...
15957                            // assign it the next cached value for that type, and then
15958                            // step that cached level.
15959                            app.curRawAdj = curCachedAdj;
15960                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15961                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15962                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15963                                    + ")");
15964                            if (curCachedAdj != nextCachedAdj) {
15965                                stepCached++;
15966                                if (stepCached >= cachedFactor) {
15967                                    stepCached = 0;
15968                                    curCachedAdj = nextCachedAdj;
15969                                    nextCachedAdj += 2;
15970                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15971                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15972                                    }
15973                                }
15974                            }
15975                            break;
15976                        default:
15977                            // For everything else, assign next empty cached process
15978                            // level and bump that up.  Note that this means that
15979                            // long-running services that have dropped down to the
15980                            // cached level will be treated as empty (since their process
15981                            // state is still as a service), which is what we want.
15982                            app.curRawAdj = curEmptyAdj;
15983                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15984                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15985                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15986                                    + ")");
15987                            if (curEmptyAdj != nextEmptyAdj) {
15988                                stepEmpty++;
15989                                if (stepEmpty >= emptyFactor) {
15990                                    stepEmpty = 0;
15991                                    curEmptyAdj = nextEmptyAdj;
15992                                    nextEmptyAdj += 2;
15993                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15994                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15995                                    }
15996                                }
15997                            }
15998                            break;
15999                    }
16000                }
16001
16002                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16003
16004                // Count the number of process types.
16005                switch (app.curProcState) {
16006                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16007                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16008                        mNumCachedHiddenProcs++;
16009                        numCached++;
16010                        if (numCached > cachedProcessLimit) {
16011                            killUnneededProcessLocked(app, "cached #" + numCached);
16012                        }
16013                        break;
16014                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16015                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16016                                && app.lastActivityTime < oldTime) {
16017                            killUnneededProcessLocked(app, "empty for "
16018                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16019                                    / 1000) + "s");
16020                        } else {
16021                            numEmpty++;
16022                            if (numEmpty > emptyProcessLimit) {
16023                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16024                            }
16025                        }
16026                        break;
16027                    default:
16028                        mNumNonCachedProcs++;
16029                        break;
16030                }
16031
16032                if (app.isolated && app.services.size() <= 0) {
16033                    // If this is an isolated process, and there are no
16034                    // services running in it, then the process is no longer
16035                    // needed.  We agressively kill these because we can by
16036                    // definition not re-use the same process again, and it is
16037                    // good to avoid having whatever code was running in them
16038                    // left sitting around after no longer needed.
16039                    killUnneededProcessLocked(app, "isolated not needed");
16040                }
16041
16042                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16043                        && !app.killedByAm) {
16044                    numTrimming++;
16045                }
16046            }
16047        }
16048
16049        mNumServiceProcs = mNewNumServiceProcs;
16050
16051        // Now determine the memory trimming level of background processes.
16052        // Unfortunately we need to start at the back of the list to do this
16053        // properly.  We only do this if the number of background apps we
16054        // are managing to keep around is less than half the maximum we desire;
16055        // if we are keeping a good number around, we'll let them use whatever
16056        // memory they want.
16057        final int numCachedAndEmpty = numCached + numEmpty;
16058        int memFactor;
16059        if (numCached <= ProcessList.TRIM_CACHED_APPS
16060                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16061            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16062                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16063            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16064                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16065            } else {
16066                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16067            }
16068        } else {
16069            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16070        }
16071        // We always allow the memory level to go up (better).  We only allow it to go
16072        // down if we are in a state where that is allowed, *and* the total number of processes
16073        // has gone down since last time.
16074        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16075                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16076                + " last=" + mLastNumProcesses);
16077        if (memFactor > mLastMemoryLevel) {
16078            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16079                memFactor = mLastMemoryLevel;
16080                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16081            }
16082        }
16083        mLastMemoryLevel = memFactor;
16084        mLastNumProcesses = mLruProcesses.size();
16085        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16086        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16087        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16088            if (mLowRamStartTime == 0) {
16089                mLowRamStartTime = now;
16090            }
16091            int step = 0;
16092            int fgTrimLevel;
16093            switch (memFactor) {
16094                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16095                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16096                    break;
16097                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16098                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16099                    break;
16100                default:
16101                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16102                    break;
16103            }
16104            int factor = numTrimming/3;
16105            int minFactor = 2;
16106            if (mHomeProcess != null) minFactor++;
16107            if (mPreviousProcess != null) minFactor++;
16108            if (factor < minFactor) factor = minFactor;
16109            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16110            for (int i=N-1; i>=0; i--) {
16111                ProcessRecord app = mLruProcesses.get(i);
16112                if (allChanged || app.procStateChanged) {
16113                    setProcessTrackerState(app, trackerMemFactor, now);
16114                    app.procStateChanged = false;
16115                }
16116                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16117                        && !app.killedByAm) {
16118                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16119                        try {
16120                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16121                                    "Trimming memory of " + app.processName
16122                                    + " to " + curLevel);
16123                            app.thread.scheduleTrimMemory(curLevel);
16124                        } catch (RemoteException e) {
16125                        }
16126                        if (false) {
16127                            // For now we won't do this; our memory trimming seems
16128                            // to be good enough at this point that destroying
16129                            // activities causes more harm than good.
16130                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16131                                    && app != mHomeProcess && app != mPreviousProcess) {
16132                                // Need to do this on its own message because the stack may not
16133                                // be in a consistent state at this point.
16134                                // For these apps we will also finish their activities
16135                                // to help them free memory.
16136                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16137                            }
16138                        }
16139                    }
16140                    app.trimMemoryLevel = curLevel;
16141                    step++;
16142                    if (step >= factor) {
16143                        step = 0;
16144                        switch (curLevel) {
16145                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16146                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16147                                break;
16148                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16149                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16150                                break;
16151                        }
16152                    }
16153                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16154                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16155                            && app.thread != null) {
16156                        try {
16157                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16158                                    "Trimming memory of heavy-weight " + app.processName
16159                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16160                            app.thread.scheduleTrimMemory(
16161                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16162                        } catch (RemoteException e) {
16163                        }
16164                    }
16165                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16166                } else {
16167                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16168                            || app.systemNoUi) && app.pendingUiClean) {
16169                        // If this application is now in the background and it
16170                        // had done UI, then give it the special trim level to
16171                        // have it free UI resources.
16172                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16173                        if (app.trimMemoryLevel < level && app.thread != null) {
16174                            try {
16175                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16176                                        "Trimming memory of bg-ui " + app.processName
16177                                        + " to " + level);
16178                                app.thread.scheduleTrimMemory(level);
16179                            } catch (RemoteException e) {
16180                            }
16181                        }
16182                        app.pendingUiClean = false;
16183                    }
16184                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16185                        try {
16186                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16187                                    "Trimming memory of fg " + app.processName
16188                                    + " to " + fgTrimLevel);
16189                            app.thread.scheduleTrimMemory(fgTrimLevel);
16190                        } catch (RemoteException e) {
16191                        }
16192                    }
16193                    app.trimMemoryLevel = fgTrimLevel;
16194                }
16195            }
16196        } else {
16197            if (mLowRamStartTime != 0) {
16198                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16199                mLowRamStartTime = 0;
16200            }
16201            for (int i=N-1; i>=0; i--) {
16202                ProcessRecord app = mLruProcesses.get(i);
16203                if (allChanged || app.procStateChanged) {
16204                    setProcessTrackerState(app, trackerMemFactor, now);
16205                    app.procStateChanged = false;
16206                }
16207                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16208                        || app.systemNoUi) && app.pendingUiClean) {
16209                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16210                            && app.thread != null) {
16211                        try {
16212                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16213                                    "Trimming memory of ui hidden " + app.processName
16214                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16215                            app.thread.scheduleTrimMemory(
16216                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16217                        } catch (RemoteException e) {
16218                        }
16219                    }
16220                    app.pendingUiClean = false;
16221                }
16222                app.trimMemoryLevel = 0;
16223            }
16224        }
16225
16226        if (mAlwaysFinishActivities) {
16227            // Need to do this on its own message because the stack may not
16228            // be in a consistent state at this point.
16229            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16230        }
16231
16232        if (allChanged) {
16233            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16234        }
16235
16236        if (mProcessStats.shouldWriteNowLocked(now)) {
16237            mHandler.post(new Runnable() {
16238                @Override public void run() {
16239                    synchronized (ActivityManagerService.this) {
16240                        mProcessStats.writeStateAsyncLocked();
16241                    }
16242                }
16243            });
16244        }
16245
16246        if (DEBUG_OOM_ADJ) {
16247            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16248        }
16249    }
16250
16251    final void trimApplications() {
16252        synchronized (this) {
16253            int i;
16254
16255            // First remove any unused application processes whose package
16256            // has been removed.
16257            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16258                final ProcessRecord app = mRemovedProcesses.get(i);
16259                if (app.activities.size() == 0
16260                        && app.curReceiver == null && app.services.size() == 0) {
16261                    Slog.i(
16262                        TAG, "Exiting empty application process "
16263                        + app.processName + " ("
16264                        + (app.thread != null ? app.thread.asBinder() : null)
16265                        + ")\n");
16266                    if (app.pid > 0 && app.pid != MY_PID) {
16267                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16268                                app.processName, app.setAdj, "empty");
16269                        app.killedByAm = true;
16270                        Process.killProcessQuiet(app.pid);
16271                    } else {
16272                        try {
16273                            app.thread.scheduleExit();
16274                        } catch (Exception e) {
16275                            // Ignore exceptions.
16276                        }
16277                    }
16278                    cleanUpApplicationRecordLocked(app, false, true, -1);
16279                    mRemovedProcesses.remove(i);
16280
16281                    if (app.persistent) {
16282                        if (app.persistent) {
16283                            addAppLocked(app.info, false);
16284                        }
16285                    }
16286                }
16287            }
16288
16289            // Now update the oom adj for all processes.
16290            updateOomAdjLocked();
16291        }
16292    }
16293
16294    /** This method sends the specified signal to each of the persistent apps */
16295    public void signalPersistentProcesses(int sig) throws RemoteException {
16296        if (sig != Process.SIGNAL_USR1) {
16297            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16298        }
16299
16300        synchronized (this) {
16301            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16302                    != PackageManager.PERMISSION_GRANTED) {
16303                throw new SecurityException("Requires permission "
16304                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16305            }
16306
16307            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16308                ProcessRecord r = mLruProcesses.get(i);
16309                if (r.thread != null && r.persistent) {
16310                    Process.sendSignal(r.pid, sig);
16311                }
16312            }
16313        }
16314    }
16315
16316    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16317        if (proc == null || proc == mProfileProc) {
16318            proc = mProfileProc;
16319            path = mProfileFile;
16320            profileType = mProfileType;
16321            clearProfilerLocked();
16322        }
16323        if (proc == null) {
16324            return;
16325        }
16326        try {
16327            proc.thread.profilerControl(false, path, null, profileType);
16328        } catch (RemoteException e) {
16329            throw new IllegalStateException("Process disappeared");
16330        }
16331    }
16332
16333    private void clearProfilerLocked() {
16334        if (mProfileFd != null) {
16335            try {
16336                mProfileFd.close();
16337            } catch (IOException e) {
16338            }
16339        }
16340        mProfileApp = null;
16341        mProfileProc = null;
16342        mProfileFile = null;
16343        mProfileType = 0;
16344        mAutoStopProfiler = false;
16345    }
16346
16347    public boolean profileControl(String process, int userId, boolean start,
16348            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16349
16350        try {
16351            synchronized (this) {
16352                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16353                // its own permission.
16354                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16355                        != PackageManager.PERMISSION_GRANTED) {
16356                    throw new SecurityException("Requires permission "
16357                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16358                }
16359
16360                if (start && fd == null) {
16361                    throw new IllegalArgumentException("null fd");
16362                }
16363
16364                ProcessRecord proc = null;
16365                if (process != null) {
16366                    proc = findProcessLocked(process, userId, "profileControl");
16367                }
16368
16369                if (start && (proc == null || proc.thread == null)) {
16370                    throw new IllegalArgumentException("Unknown process: " + process);
16371                }
16372
16373                if (start) {
16374                    stopProfilerLocked(null, null, 0);
16375                    setProfileApp(proc.info, proc.processName, path, fd, false);
16376                    mProfileProc = proc;
16377                    mProfileType = profileType;
16378                    try {
16379                        fd = fd.dup();
16380                    } catch (IOException e) {
16381                        fd = null;
16382                    }
16383                    proc.thread.profilerControl(start, path, fd, profileType);
16384                    fd = null;
16385                    mProfileFd = null;
16386                } else {
16387                    stopProfilerLocked(proc, path, profileType);
16388                    if (fd != null) {
16389                        try {
16390                            fd.close();
16391                        } catch (IOException e) {
16392                        }
16393                    }
16394                }
16395
16396                return true;
16397            }
16398        } catch (RemoteException e) {
16399            throw new IllegalStateException("Process disappeared");
16400        } finally {
16401            if (fd != null) {
16402                try {
16403                    fd.close();
16404                } catch (IOException e) {
16405                }
16406            }
16407        }
16408    }
16409
16410    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16411        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16412                userId, true, true, callName, null);
16413        ProcessRecord proc = null;
16414        try {
16415            int pid = Integer.parseInt(process);
16416            synchronized (mPidsSelfLocked) {
16417                proc = mPidsSelfLocked.get(pid);
16418            }
16419        } catch (NumberFormatException e) {
16420        }
16421
16422        if (proc == null) {
16423            ArrayMap<String, SparseArray<ProcessRecord>> all
16424                    = mProcessNames.getMap();
16425            SparseArray<ProcessRecord> procs = all.get(process);
16426            if (procs != null && procs.size() > 0) {
16427                proc = procs.valueAt(0);
16428                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16429                    for (int i=1; i<procs.size(); i++) {
16430                        ProcessRecord thisProc = procs.valueAt(i);
16431                        if (thisProc.userId == userId) {
16432                            proc = thisProc;
16433                            break;
16434                        }
16435                    }
16436                }
16437            }
16438        }
16439
16440        return proc;
16441    }
16442
16443    public boolean dumpHeap(String process, int userId, boolean managed,
16444            String path, ParcelFileDescriptor fd) throws RemoteException {
16445
16446        try {
16447            synchronized (this) {
16448                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16449                // its own permission (same as profileControl).
16450                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16451                        != PackageManager.PERMISSION_GRANTED) {
16452                    throw new SecurityException("Requires permission "
16453                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16454                }
16455
16456                if (fd == null) {
16457                    throw new IllegalArgumentException("null fd");
16458                }
16459
16460                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16461                if (proc == null || proc.thread == null) {
16462                    throw new IllegalArgumentException("Unknown process: " + process);
16463                }
16464
16465                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16466                if (!isDebuggable) {
16467                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16468                        throw new SecurityException("Process not debuggable: " + proc);
16469                    }
16470                }
16471
16472                proc.thread.dumpHeap(managed, path, fd);
16473                fd = null;
16474                return true;
16475            }
16476        } catch (RemoteException e) {
16477            throw new IllegalStateException("Process disappeared");
16478        } finally {
16479            if (fd != null) {
16480                try {
16481                    fd.close();
16482                } catch (IOException e) {
16483                }
16484            }
16485        }
16486    }
16487
16488    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16489    public void monitor() {
16490        synchronized (this) { }
16491    }
16492
16493    void onCoreSettingsChange(Bundle settings) {
16494        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16495            ProcessRecord processRecord = mLruProcesses.get(i);
16496            try {
16497                if (processRecord.thread != null) {
16498                    processRecord.thread.setCoreSettings(settings);
16499                }
16500            } catch (RemoteException re) {
16501                /* ignore */
16502            }
16503        }
16504    }
16505
16506    // Multi-user methods
16507
16508    /**
16509     * Start user, if its not already running, but don't bring it to foreground.
16510     */
16511    @Override
16512    public boolean startUserInBackground(final int userId) {
16513        return startUser(userId, /* foreground */ false);
16514    }
16515
16516    /**
16517     * Refreshes the list of users related to the current user when either a
16518     * user switch happens or when a new related user is started in the
16519     * background.
16520     */
16521    private void updateCurrentProfileIdsLocked() {
16522        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16523                mCurrentUserId, false /* enabledOnly */);
16524        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16525        for (int i = 0; i < currentProfileIds.length; i++) {
16526            currentProfileIds[i] = profiles.get(i).id;
16527        }
16528        mCurrentProfileIds = currentProfileIds;
16529    }
16530
16531    private Set getProfileIdsLocked(int userId) {
16532        Set userIds = new HashSet<Integer>();
16533        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16534                userId, false /* enabledOnly */);
16535        for (UserInfo user : profiles) {
16536            userIds.add(Integer.valueOf(user.id));
16537        }
16538        return userIds;
16539    }
16540
16541    @Override
16542    public boolean switchUser(final int userId) {
16543        return startUser(userId, /* foregound */ true);
16544    }
16545
16546    private boolean startUser(final int userId, boolean foreground) {
16547        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16548                != PackageManager.PERMISSION_GRANTED) {
16549            String msg = "Permission Denial: switchUser() from pid="
16550                    + Binder.getCallingPid()
16551                    + ", uid=" + Binder.getCallingUid()
16552                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16553            Slog.w(TAG, msg);
16554            throw new SecurityException(msg);
16555        }
16556
16557        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16558
16559        final long ident = Binder.clearCallingIdentity();
16560        try {
16561            synchronized (this) {
16562                final int oldUserId = mCurrentUserId;
16563                if (oldUserId == userId) {
16564                    return true;
16565                }
16566
16567                mStackSupervisor.setLockTaskModeLocked(null);
16568
16569                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16570                if (userInfo == null) {
16571                    Slog.w(TAG, "No user info for user #" + userId);
16572                    return false;
16573                }
16574
16575                if (foreground) {
16576                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16577                            R.anim.screen_user_enter);
16578                }
16579
16580                boolean needStart = false;
16581
16582                // If the user we are switching to is not currently started, then
16583                // we need to start it now.
16584                if (mStartedUsers.get(userId) == null) {
16585                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16586                    updateStartedUserArrayLocked();
16587                    needStart = true;
16588                }
16589
16590                final Integer userIdInt = Integer.valueOf(userId);
16591                mUserLru.remove(userIdInt);
16592                mUserLru.add(userIdInt);
16593
16594                if (foreground) {
16595                    mCurrentUserId = userId;
16596                    updateCurrentProfileIdsLocked();
16597                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16598                    // Once the internal notion of the active user has switched, we lock the device
16599                    // with the option to show the user switcher on the keyguard.
16600                    mWindowManager.lockNow(null);
16601                } else {
16602                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16603                    updateCurrentProfileIdsLocked();
16604                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16605                    mUserLru.remove(currentUserIdInt);
16606                    mUserLru.add(currentUserIdInt);
16607                }
16608
16609                final UserStartedState uss = mStartedUsers.get(userId);
16610
16611                // Make sure user is in the started state.  If it is currently
16612                // stopping, we need to knock that off.
16613                if (uss.mState == UserStartedState.STATE_STOPPING) {
16614                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16615                    // so we can just fairly silently bring the user back from
16616                    // the almost-dead.
16617                    uss.mState = UserStartedState.STATE_RUNNING;
16618                    updateStartedUserArrayLocked();
16619                    needStart = true;
16620                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16621                    // This means ACTION_SHUTDOWN has been sent, so we will
16622                    // need to treat this as a new boot of the user.
16623                    uss.mState = UserStartedState.STATE_BOOTING;
16624                    updateStartedUserArrayLocked();
16625                    needStart = true;
16626                }
16627
16628                if (uss.mState == UserStartedState.STATE_BOOTING) {
16629                    // Booting up a new user, need to tell system services about it.
16630                    // Note that this is on the same handler as scheduling of broadcasts,
16631                    // which is important because it needs to go first.
16632                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16633                }
16634
16635                if (foreground) {
16636                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16637                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16638                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16639                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16640                            oldUserId, userId, uss));
16641                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16642                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16643                }
16644
16645                if (needStart) {
16646                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16647                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16648                            | Intent.FLAG_RECEIVER_FOREGROUND);
16649                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16650                    broadcastIntentLocked(null, null, intent,
16651                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16652                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16653                }
16654
16655                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16656                    if (userId != UserHandle.USER_OWNER) {
16657                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16658                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16659                        broadcastIntentLocked(null, null, intent, null,
16660                                new IIntentReceiver.Stub() {
16661                                    public void performReceive(Intent intent, int resultCode,
16662                                            String data, Bundle extras, boolean ordered,
16663                                            boolean sticky, int sendingUser) {
16664                                        userInitialized(uss, userId);
16665                                    }
16666                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16667                                true, false, MY_PID, Process.SYSTEM_UID,
16668                                userId);
16669                        uss.initializing = true;
16670                    } else {
16671                        getUserManagerLocked().makeInitialized(userInfo.id);
16672                    }
16673                }
16674
16675                if (foreground) {
16676                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16677                    if (homeInFront) {
16678                        startHomeActivityLocked(userId);
16679                    } else {
16680                        mStackSupervisor.resumeTopActivitiesLocked();
16681                    }
16682                    EventLogTags.writeAmSwitchUser(userId);
16683                    getUserManagerLocked().userForeground(userId);
16684                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16685                } else {
16686                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16687                }
16688
16689                if (needStart) {
16690                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16691                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16692                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16693                    broadcastIntentLocked(null, null, intent,
16694                            null, new IIntentReceiver.Stub() {
16695                                @Override
16696                                public void performReceive(Intent intent, int resultCode, String data,
16697                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16698                                        throws RemoteException {
16699                                }
16700                            }, 0, null, null,
16701                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16702                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16703                }
16704            }
16705        } finally {
16706            Binder.restoreCallingIdentity(ident);
16707        }
16708
16709        return true;
16710    }
16711
16712    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16713        long ident = Binder.clearCallingIdentity();
16714        try {
16715            Intent intent;
16716            if (oldUserId >= 0) {
16717                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16718                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16719                        | Intent.FLAG_RECEIVER_FOREGROUND);
16720                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16721                broadcastIntentLocked(null, null, intent,
16722                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16723                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16724            }
16725            if (newUserId >= 0) {
16726                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16727                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16728                        | Intent.FLAG_RECEIVER_FOREGROUND);
16729                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16730                broadcastIntentLocked(null, null, intent,
16731                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16732                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16733                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16734                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16735                        | Intent.FLAG_RECEIVER_FOREGROUND);
16736                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16737                broadcastIntentLocked(null, null, intent,
16738                        null, null, 0, null, null,
16739                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16740                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16741            }
16742        } finally {
16743            Binder.restoreCallingIdentity(ident);
16744        }
16745    }
16746
16747    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16748            final int newUserId) {
16749        final int N = mUserSwitchObservers.beginBroadcast();
16750        if (N > 0) {
16751            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16752                int mCount = 0;
16753                @Override
16754                public void sendResult(Bundle data) throws RemoteException {
16755                    synchronized (ActivityManagerService.this) {
16756                        if (mCurUserSwitchCallback == this) {
16757                            mCount++;
16758                            if (mCount == N) {
16759                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16760                            }
16761                        }
16762                    }
16763                }
16764            };
16765            synchronized (this) {
16766                uss.switching = true;
16767                mCurUserSwitchCallback = callback;
16768            }
16769            for (int i=0; i<N; i++) {
16770                try {
16771                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16772                            newUserId, callback);
16773                } catch (RemoteException e) {
16774                }
16775            }
16776        } else {
16777            synchronized (this) {
16778                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16779            }
16780        }
16781        mUserSwitchObservers.finishBroadcast();
16782    }
16783
16784    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16785        synchronized (this) {
16786            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16787            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16788        }
16789    }
16790
16791    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16792        mCurUserSwitchCallback = null;
16793        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16794        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16795                oldUserId, newUserId, uss));
16796    }
16797
16798    void userInitialized(UserStartedState uss, int newUserId) {
16799        completeSwitchAndInitalize(uss, newUserId, true, false);
16800    }
16801
16802    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16803        completeSwitchAndInitalize(uss, newUserId, false, true);
16804    }
16805
16806    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16807            boolean clearInitializing, boolean clearSwitching) {
16808        boolean unfrozen = false;
16809        synchronized (this) {
16810            if (clearInitializing) {
16811                uss.initializing = false;
16812                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16813            }
16814            if (clearSwitching) {
16815                uss.switching = false;
16816            }
16817            if (!uss.switching && !uss.initializing) {
16818                mWindowManager.stopFreezingScreen();
16819                unfrozen = true;
16820            }
16821        }
16822        if (unfrozen) {
16823            final int N = mUserSwitchObservers.beginBroadcast();
16824            for (int i=0; i<N; i++) {
16825                try {
16826                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16827                } catch (RemoteException e) {
16828                }
16829            }
16830            mUserSwitchObservers.finishBroadcast();
16831        }
16832    }
16833
16834    void scheduleStartProfilesLocked() {
16835        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16836            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16837                    DateUtils.SECOND_IN_MILLIS);
16838        }
16839    }
16840
16841    void startProfilesLocked() {
16842        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16843        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16844                mCurrentUserId, false /* enabledOnly */);
16845        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16846        for (UserInfo user : profiles) {
16847            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16848                    && user.id != mCurrentUserId) {
16849                toStart.add(user);
16850            }
16851        }
16852        final int n = toStart.size();
16853        int i = 0;
16854        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16855            startUserInBackground(toStart.get(i).id);
16856        }
16857        if (i < n) {
16858            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16859        }
16860    }
16861
16862    void finishUserBoot(UserStartedState uss) {
16863        synchronized (this) {
16864            if (uss.mState == UserStartedState.STATE_BOOTING
16865                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16866                uss.mState = UserStartedState.STATE_RUNNING;
16867                final int userId = uss.mHandle.getIdentifier();
16868                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16869                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16870                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16871                broadcastIntentLocked(null, null, intent,
16872                        null, null, 0, null, null,
16873                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16874                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16875            }
16876        }
16877    }
16878
16879    void finishUserSwitch(UserStartedState uss) {
16880        synchronized (this) {
16881            finishUserBoot(uss);
16882
16883            startProfilesLocked();
16884
16885            int num = mUserLru.size();
16886            int i = 0;
16887            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16888                Integer oldUserId = mUserLru.get(i);
16889                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16890                if (oldUss == null) {
16891                    // Shouldn't happen, but be sane if it does.
16892                    mUserLru.remove(i);
16893                    num--;
16894                    continue;
16895                }
16896                if (oldUss.mState == UserStartedState.STATE_STOPPING
16897                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16898                    // This user is already stopping, doesn't count.
16899                    num--;
16900                    i++;
16901                    continue;
16902                }
16903                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16904                    // Owner and current can't be stopped, but count as running.
16905                    i++;
16906                    continue;
16907                }
16908                // This is a user to be stopped.
16909                stopUserLocked(oldUserId, null);
16910                num--;
16911                i++;
16912            }
16913        }
16914    }
16915
16916    @Override
16917    public int stopUser(final int userId, final IStopUserCallback callback) {
16918        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16919                != PackageManager.PERMISSION_GRANTED) {
16920            String msg = "Permission Denial: switchUser() from pid="
16921                    + Binder.getCallingPid()
16922                    + ", uid=" + Binder.getCallingUid()
16923                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16924            Slog.w(TAG, msg);
16925            throw new SecurityException(msg);
16926        }
16927        if (userId <= 0) {
16928            throw new IllegalArgumentException("Can't stop primary user " + userId);
16929        }
16930        synchronized (this) {
16931            return stopUserLocked(userId, callback);
16932        }
16933    }
16934
16935    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16936        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16937        if (mCurrentUserId == userId) {
16938            return ActivityManager.USER_OP_IS_CURRENT;
16939        }
16940
16941        final UserStartedState uss = mStartedUsers.get(userId);
16942        if (uss == null) {
16943            // User is not started, nothing to do...  but we do need to
16944            // callback if requested.
16945            if (callback != null) {
16946                mHandler.post(new Runnable() {
16947                    @Override
16948                    public void run() {
16949                        try {
16950                            callback.userStopped(userId);
16951                        } catch (RemoteException e) {
16952                        }
16953                    }
16954                });
16955            }
16956            return ActivityManager.USER_OP_SUCCESS;
16957        }
16958
16959        if (callback != null) {
16960            uss.mStopCallbacks.add(callback);
16961        }
16962
16963        if (uss.mState != UserStartedState.STATE_STOPPING
16964                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16965            uss.mState = UserStartedState.STATE_STOPPING;
16966            updateStartedUserArrayLocked();
16967
16968            long ident = Binder.clearCallingIdentity();
16969            try {
16970                // We are going to broadcast ACTION_USER_STOPPING and then
16971                // once that is done send a final ACTION_SHUTDOWN and then
16972                // stop the user.
16973                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16974                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16975                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16976                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16977                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16978                // This is the result receiver for the final shutdown broadcast.
16979                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16980                    @Override
16981                    public void performReceive(Intent intent, int resultCode, String data,
16982                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16983                        finishUserStop(uss);
16984                    }
16985                };
16986                // This is the result receiver for the initial stopping broadcast.
16987                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16988                    @Override
16989                    public void performReceive(Intent intent, int resultCode, String data,
16990                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16991                        // On to the next.
16992                        synchronized (ActivityManagerService.this) {
16993                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16994                                // Whoops, we are being started back up.  Abort, abort!
16995                                return;
16996                            }
16997                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16998                        }
16999                        mSystemServiceManager.stopUser(userId);
17000                        broadcastIntentLocked(null, null, shutdownIntent,
17001                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17002                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17003                    }
17004                };
17005                // Kick things off.
17006                broadcastIntentLocked(null, null, stoppingIntent,
17007                        null, stoppingReceiver, 0, null, null,
17008                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17009                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17010            } finally {
17011                Binder.restoreCallingIdentity(ident);
17012            }
17013        }
17014
17015        return ActivityManager.USER_OP_SUCCESS;
17016    }
17017
17018    void finishUserStop(UserStartedState uss) {
17019        final int userId = uss.mHandle.getIdentifier();
17020        boolean stopped;
17021        ArrayList<IStopUserCallback> callbacks;
17022        synchronized (this) {
17023            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17024            if (mStartedUsers.get(userId) != uss) {
17025                stopped = false;
17026            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17027                stopped = false;
17028            } else {
17029                stopped = true;
17030                // User can no longer run.
17031                mStartedUsers.remove(userId);
17032                mUserLru.remove(Integer.valueOf(userId));
17033                updateStartedUserArrayLocked();
17034
17035                // Clean up all state and processes associated with the user.
17036                // Kill all the processes for the user.
17037                forceStopUserLocked(userId, "finish user");
17038            }
17039        }
17040
17041        for (int i=0; i<callbacks.size(); i++) {
17042            try {
17043                if (stopped) callbacks.get(i).userStopped(userId);
17044                else callbacks.get(i).userStopAborted(userId);
17045            } catch (RemoteException e) {
17046            }
17047        }
17048
17049        if (stopped) {
17050            mSystemServiceManager.cleanupUser(userId);
17051            synchronized (this) {
17052                mStackSupervisor.removeUserLocked(userId);
17053            }
17054        }
17055    }
17056
17057    @Override
17058    public UserInfo getCurrentUser() {
17059        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17060                != PackageManager.PERMISSION_GRANTED) && (
17061                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17062                != PackageManager.PERMISSION_GRANTED)) {
17063            String msg = "Permission Denial: getCurrentUser() from pid="
17064                    + Binder.getCallingPid()
17065                    + ", uid=" + Binder.getCallingUid()
17066                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17067            Slog.w(TAG, msg);
17068            throw new SecurityException(msg);
17069        }
17070        synchronized (this) {
17071            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17072        }
17073    }
17074
17075    int getCurrentUserIdLocked() {
17076        return mCurrentUserId;
17077    }
17078
17079    @Override
17080    public boolean isUserRunning(int userId, boolean orStopped) {
17081        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17082                != PackageManager.PERMISSION_GRANTED) {
17083            String msg = "Permission Denial: isUserRunning() from pid="
17084                    + Binder.getCallingPid()
17085                    + ", uid=" + Binder.getCallingUid()
17086                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17087            Slog.w(TAG, msg);
17088            throw new SecurityException(msg);
17089        }
17090        synchronized (this) {
17091            return isUserRunningLocked(userId, orStopped);
17092        }
17093    }
17094
17095    boolean isUserRunningLocked(int userId, boolean orStopped) {
17096        UserStartedState state = mStartedUsers.get(userId);
17097        if (state == null) {
17098            return false;
17099        }
17100        if (orStopped) {
17101            return true;
17102        }
17103        return state.mState != UserStartedState.STATE_STOPPING
17104                && state.mState != UserStartedState.STATE_SHUTDOWN;
17105    }
17106
17107    @Override
17108    public int[] getRunningUserIds() {
17109        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17110                != PackageManager.PERMISSION_GRANTED) {
17111            String msg = "Permission Denial: isUserRunning() from pid="
17112                    + Binder.getCallingPid()
17113                    + ", uid=" + Binder.getCallingUid()
17114                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17115            Slog.w(TAG, msg);
17116            throw new SecurityException(msg);
17117        }
17118        synchronized (this) {
17119            return mStartedUserArray;
17120        }
17121    }
17122
17123    private void updateStartedUserArrayLocked() {
17124        int num = 0;
17125        for (int i=0; i<mStartedUsers.size();  i++) {
17126            UserStartedState uss = mStartedUsers.valueAt(i);
17127            // This list does not include stopping users.
17128            if (uss.mState != UserStartedState.STATE_STOPPING
17129                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17130                num++;
17131            }
17132        }
17133        mStartedUserArray = new int[num];
17134        num = 0;
17135        for (int i=0; i<mStartedUsers.size();  i++) {
17136            UserStartedState uss = mStartedUsers.valueAt(i);
17137            if (uss.mState != UserStartedState.STATE_STOPPING
17138                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17139                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17140                num++;
17141            }
17142        }
17143    }
17144
17145    @Override
17146    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17147        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17148                != PackageManager.PERMISSION_GRANTED) {
17149            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17150                    + Binder.getCallingPid()
17151                    + ", uid=" + Binder.getCallingUid()
17152                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17153            Slog.w(TAG, msg);
17154            throw new SecurityException(msg);
17155        }
17156
17157        mUserSwitchObservers.register(observer);
17158    }
17159
17160    @Override
17161    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17162        mUserSwitchObservers.unregister(observer);
17163    }
17164
17165    private boolean userExists(int userId) {
17166        if (userId == 0) {
17167            return true;
17168        }
17169        UserManagerService ums = getUserManagerLocked();
17170        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17171    }
17172
17173    int[] getUsersLocked() {
17174        UserManagerService ums = getUserManagerLocked();
17175        return ums != null ? ums.getUserIds() : new int[] { 0 };
17176    }
17177
17178    UserManagerService getUserManagerLocked() {
17179        if (mUserManager == null) {
17180            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17181            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17182        }
17183        return mUserManager;
17184    }
17185
17186    private int applyUserId(int uid, int userId) {
17187        return UserHandle.getUid(userId, uid);
17188    }
17189
17190    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17191        if (info == null) return null;
17192        ApplicationInfo newInfo = new ApplicationInfo(info);
17193        newInfo.uid = applyUserId(info.uid, userId);
17194        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17195                + info.packageName;
17196        return newInfo;
17197    }
17198
17199    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17200        if (aInfo == null
17201                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17202            return aInfo;
17203        }
17204
17205        ActivityInfo info = new ActivityInfo(aInfo);
17206        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17207        return info;
17208    }
17209
17210    private final class LocalService extends ActivityManagerInternal {
17211        @Override
17212        public void goingToSleep() {
17213            ActivityManagerService.this.goingToSleep();
17214        }
17215
17216        @Override
17217        public void wakingUp() {
17218            ActivityManagerService.this.wakingUp();
17219        }
17220    }
17221
17222    /**
17223     * An implementation of IAppTask, that allows an app to manage its own tasks via
17224     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17225     * only the process that calls getAppTasks() can call the AppTask methods.
17226     */
17227    class AppTaskImpl extends IAppTask.Stub {
17228        private int mTaskId;
17229        private int mCallingUid;
17230
17231        public AppTaskImpl(int taskId, int callingUid) {
17232            mTaskId = taskId;
17233            mCallingUid = callingUid;
17234        }
17235
17236        @Override
17237        public void finishAndRemoveTask() {
17238            // Ensure that we are called from the same process that created this AppTask
17239            if (mCallingUid != Binder.getCallingUid()) {
17240                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17241                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17242                return;
17243            }
17244
17245            synchronized (ActivityManagerService.this) {
17246                long origId = Binder.clearCallingIdentity();
17247                try {
17248                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17249                    if (tr != null) {
17250                        // Only kill the process if we are not a new document
17251                        int flags = tr.getBaseIntent().getFlags();
17252                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17253                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17254                        removeTaskByIdLocked(mTaskId,
17255                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17256                    }
17257                } finally {
17258                    Binder.restoreCallingIdentity(origId);
17259                }
17260            }
17261        }
17262
17263        @Override
17264        public ActivityManager.RecentTaskInfo getTaskInfo() {
17265            // Ensure that we are called from the same process that created this AppTask
17266            if (mCallingUid != Binder.getCallingUid()) {
17267                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17268                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17269                return null;
17270            }
17271
17272            synchronized (ActivityManagerService.this) {
17273                long origId = Binder.clearCallingIdentity();
17274                try {
17275                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17276                    if (tr != null) {
17277                        return createRecentTaskInfoFromTaskRecord(tr);
17278                    }
17279                } finally {
17280                    Binder.restoreCallingIdentity(origId);
17281                }
17282                return null;
17283            }
17284        }
17285    }
17286}
17287